Is it possible to specify a Java classpath
that includes a JAR file contained within another JAR file?
views:
3914answers:
8Not without writing your own class loader. You can add jars to the jar's classpath, but they must be co-located, not contained in the main jar.
You need to build a custom class-loader to do this or a third-party library that supports this. Your best bet is to extract the jar from the runtime and add them to the classpath (or have them already added to the classpath).
If you're trying to create a single jar that contains your application and it's required libraries, there are two ways (that I know of) to do that. The first is One-Jar, which uses a special classloader to allow the nesting of jars. The second is UberJar, (or Shade), which explodes the included libraries and puts all the classes in the top-level jar.
I should also mention that UberJar and Shade are plugins for Maven1 and Maven2 respectively. As mentioned below, you can also use the assembly plugin (which in reality is much more powerful, but much harder to properly configure).
I was about to advise to extract all the files at the same level, then to make a jar out of the result, since the package system should keep them neatly separated. That would be the manual way, I suppose the tools indicated by Steve will do that nicely.
I use maven for my java builds which has a plugin called the maven assembly plugin.
It does what your asking, but like some of the other suggestions describe - essentially exploding all the dependent jars and recombining them into a single jar
See http://stackoverflow.com/questions/81260/java-easiest-way-to-merge-a-release-into-one-jar-file for a way to pack them all into one.
You do NOT want to use those "explode JAR contents" solutions. They definitely make it harder to see stuff (since everything is exploded at the same level). Furthermore, there could be naming conflicts (should not happen if people use proper packages, but you cannot always control this).
The feature that you want is one of the top Sun RFEs, which Sun, in their infinite wisdom, has designated as being of low priority. (Edit: would post the links, but am prevented from having more than one in this post. %$##& spammers. Search on Sun's bug parade under top RFEs around item #14.) We can only hope that Sun wakes up...
In the meanwhile, the best solution that I have come across (which I wish that Sun would copy in the JDK) is to use the custom class loader JarClassLoader.