views:

53

answers:

3

Hello, an application I have written uses several third party jars. Sometimes only a small portion of the entire 50kB to 1.7mB jar is used - one or two function calls or classes.

What is the best way to reduce the jar sizes. Should I download the sources and build a jar with just the classes I need? What existing tools can help automate this (ex I briefly looked at http://code.google.com/p/jarjar/)?

Thank you

Edit 1: I would like to lower the size of my third party 'official' jars like swingx-1.6.jar (1.4 MB), set-3.6 (1.7 MB) glazedlists-1.8.jar (820kB) , etc. so that they only contain the bare minimum classes I need

Edit 2: Minimizing a jar by hand or by using a program like proguard is further complicated if the library uses reflection. http://stackoverflow.com/questions/2369939/injection-with-google-guice-does-not-work-anymore-after-obfuscation-with-proguard

The answer by cletus on another post is very good http://stackoverflow.com/questions/475516/how-to-determine-which-classes-are-used-by-a-java-program

+1  A: 

Proguard would be an option. It can eliminate unused classes and methods. You can also use it to obfuscate, which can further reduce the size of your final jar. Be aware that class loading by name is liable to break unless care is taken to keep the affected classes unobfuscated.

I've found Proguard quite effective - can be a bit cryptic to understand at the outset. But I don't have any experience with similar to offer a comparison.

martin clayton
I have used Proguard for obfuscation of my application jar with good result, and noticed the smaller output size. I also ran into issues with 'broken classes' as you mention, with xstream objects, until I added them to the "keep" section. I have not used proguard to reduce the size of my dependency jars though - is this possible?
brian_d
@brian_d - yes it should be possible, using -injars/-outjars. I guess the 'level of difficulty' will be related to the number of jars you have. An example use I had was of bouncycastle encryption. I was able to just include the classes I needed, discarding all the code for unused algorithms, etc.
martin clayton
thanks for the suggestion, I will give this a try.
brian_d
A: 

First of all, if you use only one class from JAR file this does not mean that this class does not use other classed from that JAR. The option for you, if you use open source JARs, is to get sources of that JAR, attach them to your project, remove unnecessary stuff and build the changes by yourself.

Andriy Sholokh
Still problematic as mentioned in my 'Edit #2'. I reduced swingx by hand from 1.4MB to 160kB. It built fine, but crashed on running because of several reflection method class calls that were not included.
brian_d
A: 

You could add GenJar as an Ant task and use it to build the JAR. As it says on the library's home page,

GenJar is a specialized Ant task that builds jar files based on class dependencies rather than simply the contents of a directory.

You can find it on SourceForge.

Sorin Marinescu
I am getting nothing but frustration with GenJar, with 'Unable to resolve' errors. It looks like it has not been updated since 2003-03-06 either.
brian_d