Packing library packages into a jar fileFrom WikiJavabuy this book
This article shows how to create jars containing also all the referenced libraries, this is a standard practice in J2EE programming, where in most of the cases Java programs come packaged into single .war or .ear files, that contain all the necessary code (your program and the referenced libraries). It is a bit more tricky when it comes to do the same in a JSE .jar file. I'll explain below how the jar file should look like. Refer to the article include libraries in a jar file using ANT.
What we want to achieveWhenever I choose to use a new program one of the factors I always take in consideration is its complexity and the difficulty of installation. In general I tend to prefer programs that are standalone and portable. The perfect program for me does not require installation and I can move it to different directories or even to a USB stick, and it still works keeping the configuration as well. If additionally the program is in Java then I'm very happy, because I can install, move and use the program freely even across different platforms. Creating such software is not too complex for the programmer, and with very few adjustments it becomes very easy to make your software portable and standalone. What we want to achieve is a unique jar file: say program.jar which is the only file needed to start your program. program.jar we would like is a zip file (every jar file is a zip file) containing a file structure similar to the following: +- uncompressed
+- lib
- library1.jar
- library2.jar
- ...
+- META-INF
- MANIFEST.MF
+- org
+- wikijava
+- package structure ....
- classFile1.class
- classFile2.class
- ...
The problemUnfortunately the directory structure mentioned just above is typical of J2ee, and not implemented in the Java Standard edition class loader. See | this page for details about how to use the manifest in a JSE environment. Note: The Class-Path header points to classes or JAR files on the local network, not JAR files within the JAR file or classes accessible over internet protocols. To load classes in JAR files within a JAR file into the class path, you must write custom code to load those classes. For example, if MyJar.jar contains another JAR file called MyUtils.jar, you cannot use the Class-Path header in MyJar.jar's manifest to load classes in MyUtils.jar into the class path. Basically any classpath mentioned in the manifest file points only to files external to the jar. (either a path relative to the jar is or a fully qualified URL). If you want to use internal Jar files you need to implement your own way to load them. So are we stuck? Is there any trick? The answer is: yes and not ....
The solutionsSo far I can imagine two ways to solve this:
As per the first option, this is complex, and error prone solution. we don't want to mess up with the classloader, which is such a complex and delicate component of the standard Java API. My preferred solution is the second, where I just decompress the library jars into my jar, in order to get .class files just as they were my own code. This approach is probably not universal, and may not work in some cases, for example it's to be seen if this works also with classes that are encrypted in the jar. But it's general enough to be considered useful in many, probably most, cases. Basically what we can do is to decompress each library file and include its files in our jars, in order to look just like follows: +- program.jar
+- org
+- wikijava
+- package path ....
- myclassfile1.class
- myclassfile2.class
- ...
+- META-INF
- MANIFEST.MF
+- org
+- apache
+- poi
+- uncompressed package path
- LibClassFile1.class
- LibClassFile2.class
- ...
+- another uncompressed package path
- LibClassFile3.class
- LibClassFile4.class
- ...
In this way when the JVM runs your program, the referenced libraries will be automatically in the classpath, exactly as they were code written and compiled by you. The library code is basically merged into yours and (from the JVM's standpoint) completely indistinguishable. I don't reckon this approach too neat, as unpacking the jar files is not guaranteed to work in all cases, and I don't like too much the idea of mixing library code with proprietary code. But it should be a sufficient solution for most cases. Read the include libraries in a jar file using ANT article for details on how to generate files in this way using ANT builder, see generating a Jar file to see what's the standard way to generate jar files.
|
