13 July 2011

Unofficial Java SE 7 Builds for Mac OS X

Not sure how I overlooked this, but according to this page here:

http://wikis.sun.com/display/OpenJDK/Mac+OS+X+Port

There are prebuilt (unofficial) binaries for Java SE 7 on Mac OS X here: 

http://code.google.com/p/openjdk-osx-build/downloads/list?q=label:Featured

Good stuff.

04 July 2011

Plugging in a later version of EclipseLink to WebLogic Server

Talking with Doug Clarke of EclipseLink fame and fortune last week, it sounds like there is some real interest from developers in wanting to update WebLogic Server to use later versions of the EclipseLink in order to access it's evolving feature set.

Which should offer no surprises really, EclipseLink rocks.

Investigation

Turning to the situation at hand, the main points to be addressed are:

1. The later versions of EclipseLink are JPA 2.0 based, so we'll assume that the predominant use case is centered around using JPA 2.0.

WebLogic Server supports JPA 2.0 through the application of a Smart Update patch or via manual adjustments to the PRE_CLASSPATH to incorporate two additional JAR files that enable the use of JPA 2.0. 

We'll consider this one easy to handle using documented features.

2. WebLogic Server provides a version of EclipseLink that is loaded as one it's standard feature bearing modules and thus is present by default in the classpath of WebLogic Server for deployed applications.  For WLS 10.3.5, this version is org.eclipse.persistence_1.1.0.0_2-1.jar.

WebLogic Server has a feature called the Filtering Classloader, which enables applications to selectively override the libraries from WebLogic Server that an application sees.  This should allow an application to be configured to not use the default version of EclipseLink that WebLogic Server provides.  This requires each application to specifically provide a weblogic-application.xml file that lists the <prefer-application-packages> configuration set to explicitly filter our the org.eclipselink.persistence package.

3. Any change to the EclipseLink version should be isolated to just an application, and not applied to an entire WebLogic Server installation or domain.

To make the later version of EclipseLink available, there are a few simple options available that could be explored: a) the EclipseLink jar file could be added to the CLASSPATH of WebLogic Server; b) the EclipseLink jar file could be dropped into the $domain/lib directory; c) the newer version of EclipseLink could be used to replace the existing EclipseLink jar file shipped with WebLogic Server, retaining the same name; d) the WebLogic Server shared-library mechanism could be used to deploy the EclipseLink libraries which applications can then selectively reference.

For the sake of expediency, I won't bother going through the pros/cons with each of those options and will just pick a winner from my perspective: the use of a shared-library to provide a selectively consumable version of EclipseLink.

Let's just examine this for a moment -- a WebLogic Server shared-library is an artifact that can be deployed to a WebLogic Server target, which can then be referenced by an application being deployed, whereupon WebLogic Server will merge the contents of the shared-library with the application.  This enables common libraries to be deployed and used by multiple applications.  Furthermore, shared-libraries can take the format of a standard Java EE archives, where descriptors can be provided which are then also merged with the final application deployment. 

Given those capabilities:

a) it's possible to construct and deploy an EAR file based shared-library that contains a later version of EclipseLink and a weblogic-application.xml file which provides a preset prefer-application-packages setting that filters the org.eclipselink.persistence.* package. 

b) to use a later version of EclipseLink, an application simply needs to include it's own weblogic-application.xml that imports the EclipseLink shared-library it need to use.

Thus, we have a supported deployment format (can be targeted at single nodes, clusters, whatever ...) to provide later versions of EclipseLink, which can be shared and selectively used by applications as desired.

Implementation

To test this out in an end-to-end manner, I performed the following steps:

1. Downloaded eclipselink-2.2.0.v20110202-r8913.zip from the EclipseLink web site.

2. Created a small ant project to produce an eclipselink-shared-lib.ear file.  The layout of the shared-library is just a standard Java EE EAR file and contains the following items:

META-INF/weblogic-application.xml
META-INF/application.xml
lib/eclipselink.jar

The weblogic-application.xml file contains the following configuration elements:

<weblogic-application>
  <prefer-application-packages>
    <package-name>org.eclipse.persistence.*</package-name>
  </prefer-application-packages>
</weblogic-application>

The application.xml was a necessary element to support the runtime library merging.  As you can see from the below, it's basically a NOOP configuration file.

<application>
  <display-name>eclipselink-shared-lin</display-name>
  <module>
        <java></java>
  </module>
</application>

The ant build script produces an EAR file from these elements with one important addition that marks the EAR file as a shared-library for WebLogic Server by adding a number of attributes to the META-INF/MANIFEST.MF file:

<target name="package" depends="prepare">
    <jar destfile="dist/${ant.project.name}.ear">
        <metainf dir="etc" includes="*.xml"/>
        <manifest>
            <attribute name="Extension-Name" value="eclipselink"/>
            <attribute name="Specification-Version" value="2.0"/>
            <attribute name="Implementation-Version" value="2.2.0"/>
        </manifest>

        <fileset dir="build" includes="**/*"/>
    </jar>       
</target>

At deployment time, WebLogic Server will use the attributes as meta-data for the deployed shared-library.

The final EAR file looks like this:

sbutton:~/Projects/Java/eclipselink-shared-lib/dist $ jar tf eclipselink-shared-lib.ear
META-INF/
META-INF/MANIFEST.MF
META-INF/application.xml
META-INF/weblogic-application.xml
lib/
lib/eclipselink.jar

For reference, the simple ant project to build the eclipselink-shared-lib.ear file is here: eclipselink-shared-lib.zip.

3. Deployed eclipselink-shared-lib.ear to WebLogic Server.  This results in a new library being available on the server, eclipselink#2.0@2.2.0.

4. Created a test application that imports eclipselink#2.0@2.2.0 and outputs the version of it that it is seeing.

The application uses a weblogic.xml to reference the eclipselink#2.0@2.2.0 shared-library that was deployed, which picks up both the new version of eclipselink.jar as well as the filtering-classloader description the library contains:



weblogic-application.xml:

<weblogic-application>
    <library-ref>
        <library-name>eclipselink</library-name>
        <specification-version>2.0</specification-version>
        <implementation-version>2.2.0</implementation-version>
    </library-ref>

</weblogic-application>

Within the application, used a simple servlet that outputs the version of EclipseLink it is seeing:

out.printf("<p>EclipseLink Version: %s</p>", org.eclipse.persistence.Version.getVersionString());


5. Packaged the application into an EAR file and deployed it to WebLogic Server as an application.

When the application is accessed it reports the new version of EclipseLink supplied via the shared-library:

EclipseLink Version: 2.2.0.v20110202-r8913
 
6. Performed a negative test by undeploying the application, removed the weblogic-application.xml file from it and redeployed it.

When the application is accessed it reports the default version of EclipseLink that WebLogic Server supplies:

EclipseLink Version: 2.1.3.v20110304-r9073

7.  With the basic premise validated, add a JPA module to validate the code-weaving EclipseLink performs works as expected.  To verify the version EclipseLink is using the EclipseLink log level was set to fine and the console output reviewed, which showed up as Eclipse Persistence Services - 2.2.0.v20110202-r8913

Summary

The use of WebLogic Server shared-libraries appears to be a very suitable model for providing later versions of EclipseLink that automatically filter out the WebLogic Server supplied versions, which applications can selectively choose to import when they need the later versions.

This was just a simple test of the concept of using WebLogic Server shared-libraries to do this.  The EclipseLink/TopLink team are in the throes of formally certifying this approach, so keep an eye out for it on the EclipseLink site if it does pass full muster!