Saturday, September 27, 2008

Building enterprise applications with Maven to use optional packages


The Java 1.3 feature of optional packages introduced support for an expanded set of Jar-file manifest attributes that enable an application jar to specify its list of dependencies on other jars. Maven can generate a jar and build a manifest automatically for you so that you can leverage optional packages deployed in your environment (whether it be the classpath or jars deployed in an application container). If you are looking to build and deploy an application EAR that has dependencies on a slew of 3rd party libraries, you can deploy the 3rd party libraries as optional packages and cut down on the size of your EAR file across many applications. The reuse of these 3rd party jars across multiple Web or enterprise application deployments becomes really handy if you want all these applications to do a common upgrade to a different version for their dependent library. So how do you tell Maven to do this? Here's an example of a Web application POM file. Within the build section, specify the following snippet -

<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addExtensions>true</addExtensions>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>


However, while building this WAR file, the dependencies will still get pulled in unless you specify another attribute on your dependencies. Example here - if you have a dependency on aspectj and aspectj is deployed to your container, say Weblogic10, as an optional package, then in your POM for your WAR file, you would specify the following -

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.0</version>
<!-- <scope>provided</scope> -->
<optional>true</optional>
</dependency>

The attribute that's important in this snippet is the "optional" attribute, the presence of which will omit the file from being included in the WAR file. The omission of the file is not the only thing that is important here. The "scope" element is also important. There are some specific rules that Maven follows when generating the manifest based on the "scope" and "optional" tags that you need to understand. Here's their docs that shows a table that helps clearly explain the relationship between these 2 attributes. In the above example, while the optional element will will exclude the jar from being added to the WAR file, the scope element will also cause the jar's extension name to be omitted from the MANIFEST - something you probably do not want if you are looking to leverage optional packages deployed.

A jar file deployed as an optional package essentially needs to have 3 properties in its manifest file -

Extension-Name: asjpectj
Specification-Version: 1.6.0
Implementation-Version: 1.6.0

The manifest file built by Maven will put the extension name of the dependent jar in the "Extension-List" property of the manifest of your WAR file. It will also put the implementation version. You have to make sure that both these attributes match with those of the deployed optional package (i.e. in this example the aspectj jar). Otherwise, you'll probably get a ClassNotFoundException. As long as you get the extension name and implementation version of the optional package the same as what Maven generates in the manifest of the dependent WAR, everything will work and deploy without a problem. Take a look at this article for Weblogic to understand the constraints on naming for optional packages.

While the above is tedious at first, it becomes a very efficient way of managing application dependencies in enterprise production systems once you get everything working and lined up. I actually created a Swing tool that takes an EAR file that has all the dependencies in it and spits out the jars converted into optional packages that Maven understands. All you really have to do is take the version information from the name of the jar and put it into the Specification(as long as this contains only digits eg. "1.1.2" ) and implementation properties of the jar's manifest.

Though your initial effort to get everything setup will take a little bit of time, it will be well worth it. So give this operational efficiency a try.....

Thursday, August 7, 2008

Using Ubuntu for Java development in the enterprise


Ubuntu's been a rage over the last 2-3 years, however it definately seems to be catching on with a lot of folks as a possible OS of choice, with the widespread dissatisfaction around MS Vista. I decided to really give Ubuntu the spin to see if I really would develop applications and do my daily work in that environment - it's one thing saying Ubuntu's an alternative to Windows, its another to actually get the tools for the job working on this OS.

So first thing I did was to install Ubuntu using Wubi from within Windows Xp. This to me is a really cool piece of software, as Ubuntu looks like any other Windows program installed. However, it actually allows Ubuntu to be booted when your pc's turned on by adding an entry to the Windows boot menu. Ubuntu is installed within a file in the Windows file system (c:\ubuntu\disks\root.disk), this file is seen by Linux as a real hard disk. The install didn't take too much time, about 20 minutes on my Toshiba M700. So essentially, you're not running Ubuntu in a virtualized mode.

While Ubuntu looks pretty good, the UI doesn't necessarily looks extraordinary. So I decided to jazz it up to look like the MacOS X. Take a look at this. On the left, that's what my desktop looks like now.

So now that I had the system look spiffy, I decided to do some real Java work on it. With Synaptic software manager, I installed JDK 1.5. I also downloaded MyEclipse 6.5. Now for the application server, I decided to use Weblogic - one of the more common enterprise wide application servers in use in production environments. I downloaded the RedHat version of Weblogic 10 MP1. For the database, MySQL was the obvious choice and Synaptics makes that an easy install.

Finally, after all that, I got a JEE5 application deployed and running for a quick test of all components. Everything worked perfectly - infact, Weblogic actually seems to run faster than it does on the Windows side - under the same hardware. On the whole, I also saw that the OS was consuming lesser memory helping programs overall. Ubuntu seems a really viable option for Java developers, and I would definitely recommend that you give some thought to this option, especially in your organization if you're a pure Java shop - lesser cost to maintain, and closer to your production environments. MS applications like Office have substitutes (OpenOffice, Evolution), but you can also use virtualization software to run these MS apps seamlessly on Ubuntu using something like QEmu. I really do think this has the potential to take off in many organizations.

PS: While I initially posted information about a 32bit Ubuntu install, I later went on and installed the 64bit version since my laptop has Intel Core2 chips. I was able to run all software I mentioned above and mostly also saw some performance improvement. The only glitch was that 2 of the MacOS options - the global menu and startup screens don't work or need to be compiled for a 64bit system. On the software side, Acrobat Reader couldn't be installed, however Ubuntu has pdf-reader preinstalled - so that's not something you'll miss.