Friday, February 26, 2010

Creating an Uber Jar with Maven 2

There may come a time in your life as a developer when you need to create a massive 'uber-jar' for your whole project. What do I mean by Uber-Jar, well, this is a jar that has your project, all its dependencies, AND all it's test files packaged and exploded into one massive jar file, the Uber-Jar. You may be thinking to yourself, why would I ever need to do this? Your thinking is correct, this does sound stupid to include test classes next to regular classes, but consider this use case. You may want to create a jar to run tests on a remote machine, say a dev box, to do performance testing. Ok, enough talk, on with the meat of this thing!

Create a Maven Assembly descriptor for your project to include all dependencies and your test classes. Here is an example:



<assembly>
<id>performance-test</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}/test-classes</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
<dependencySet>
<unpack>true</unpack>
<scope>test</scope>
</dependencySet>
</dependencySets>
</assembly>


Ok, so now you have an assembly file. Now we need to instruct maven to run this only when you want it run. For that we need to create a maven build profile. Check it:



<profiles>
<profile>
<id>package.test</id>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/performanceTest.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>


Pretty easy so far right? Now we just need to tell maven to run this profile AND generate test classes. Here is a command to do so.

mvn -e clean jar:test-jar assembly:assembly -Ppackage.test 


That's it! You now have a massive jar with tons of dependencies in it including all your source and test files side by side. Enjoy!

Monday, February 22, 2010

Tomcat Sucks at auto deploying multiple WAR files.

Had an issue over the weekend trying to deploy a few new war files on a tomcat server. The server is set to run with a max heap space of 1G and does not even get close to this while running. Also, said server, on amazon cloud, has the following stats:

Java 6
Tomcat 6
7.5 GB memory
EC2 Compute Units (2 virtual cores with 2 EC2 Compute Units each)
850 GB instance storage (2×420 GB plus 10 GB root partition)
64-bit platform
I/O Performance: High
API name: m1.large



When starting the tomcat service all the WARs would be autodeployed and exploded just fine. After humming along for a few minutes the entire server would freeze and had to be hard restarted from the EC2 admin console. 




So to fix this I just disabled auto-deploy in the server.xml file for tomcat. I'm wondering what the true cause of this issue was. I'll have to play around and find out.