4

I would like to know if it is possible to write an Ant task (using some other library if necessary) to reduce a JAR file so that it contains only certain classes and those on which they depend.

For example, I have a JAR containing classes A, B, C and D, where A and B both extend C. D is independent of the others. What I would like to do is specify to an Ant task that I only need class B, and end up with a JAR file that contains only B and C.

I have seen this answer which provides a simple way to say "I don't want A and D", and I imagine that replacing "excludes" with "includes" would allow me to specify "I do want B and C" like this:

<jar destfile="stripped.jar">
    <zipfileset src="full.jar" includes="path/B.class;path/C.class"/>
</jar>

...but is there a dependency-aware way of doing this so that I can say "I want B" but end up with a JAR that contains B and its dependencies?

Community
  • 1
  • 1
Ian Renton
  • 699
  • 2
  • 8
  • 21
  • 1
    Note that all the tools mentioned in the answers will only find explicit dependencies, but not dependencies acquired via reflection (which includes dependency injects and similar mechanisms employed by many application frameworks). – Michael Borgwardt Mar 02 '12 at 13:32

2 Answers2

3

You could take a look at obfuscating tools, they can also often remove dead code, that is classes, methods and the like that are not referenced from anywhere in the code.

For example, you could use ProGuard.

From the documentation:

ProGuard is a free Java class file shrinker, optimizer, obfuscater, and preverifier. It detects and removes unused classes, fields, methods, and attributes. It optimizes bytecode and removes unused instructions. It renames the remaining classes, fields, and methods using short meaningless names. Finally, it preverifies the processed code for Java 6 or for Java Micro Edition.

You can configure it to do just the shrinker step. In your case, you would use the -keep option to tell ProGuard that you want the B class, and end up with B and C as you describe. This might not be exactly what you want however since ProGuard will also remove unused methods and the like, modifying the classes in your JAR file (I do not know of any option to turn this off). Also, you need to tell ProGuard not to do any of the other stuff it normally does, such as obfuscation.

If ProGuard does not fit your needs, you can look for other obfuscation and/or shrinking tools. Hope this helps, and good luck!

oers
  • 18,436
  • 13
  • 66
  • 75
user829876
  • 723
  • 5
  • 6
3

As user829876 suggests, ProGuard could be one option.

Another option, that might be closer to what you're looking for, is GenJar. There has not been much activity for some years, but it sounds like it will do what you need. You can find some examples here. There aren't very many alternatives.

Another tool you might want to look into is Autojar. It doesn't seem to have an Ant task, but you could probably use the Java task to get it going.

I've never used these tools, but it shouldn't take much to give them a try and see what works for you. If need be, the sources are available for your tweaking.

Community
  • 1
  • 1
Go Dan
  • 15,194
  • 6
  • 41
  • 65