I built a stand-alone Java application that has a bunch of dependencies (Apache Commons libs, etc) as well as a dependency on the Spring framework, which in turn has a bunch of dependencies.
I built this in Eclipse, where it runs fine. Now I need to deploy it to production and so I'm trying to figure out the best way to package it with all dependencies and also how to even invoke the thing (it will be invoked from the command line).
The brute-force way would be to export my project as a jar, find all the dependent jars (and their dependencies!), copy them to a common directory, write a shell script that includes every one on the classpath and run it. Obviously that seems stupid and tedious.
Should I use Ant, Maven? Should I package all of the dependent Spring jars into one big file? Any tips on dealing with this would be helpful.
Java deployment is still stupid and tedious in 2009. So the usual option is to write this small script. If you put all your JARs into one directory (say,
lib\
), you can use a common script which builds the classpath automatically (see this blog entry). I suggest to add acd /d %~dp0
at the beginning to cd into the script's directory.Maven 2 has a plugin which can assemble your application in one "super JAR" (mvn assembly:assembly). This works unless you use the DB2 JCC driver (which contains "COM.ibm." packages which get converted to com.ibm. -> ClassNotFoundException).
The last solution, if you have already an ANT build.xml which works, is to unpack all the dependent JARs and create a "super JAR" yourself.
In my ANT build script, I generate the *.bat and *.sh startup scripts with the list of JARs dynamically built at build time based on the contents of the build's lib dir.
For instance, to create the list of jars with appropriate separators:
You can then use the
${exec.classpath.unix}
and${exec.classpath.windows}
values in the java invocation scripts.We found that the best solution for dependency management and packaging is to use Maven with the Assembly plugin. This provides a very elegant means to packaging you projects, along with all the runtime dependencies and supporting scripts into a binary distribution. One of the greatest advantages of using assemblies is that it is possible to split your projects into distinct components according to necessity. If you're using Spring Integration its quite common you would have separate components to be split over multiple machines. The assembly plugin allows you to configure this to your requirements.
The maven-assembly-plugin may not be the best choice. You should have a look at the onejar-maven-plugin, as described here:
http://blog.jayway.com/2009/03/22/executable-jar-with-onejar-maven-plugin/
It lets all your dependency jars stay jars, and your code is in its own jar. All of those jars are put in a bigger jar, which is made executable.