How can I use the maven shade or assembly plugin to automatically determine which classes are needed from the dependency jars, and copy ONLY these classes into the build. So far I have had no luck getting it to automatically find which classes will be necessary for my build.
I can use minimizeJar and include and exclude tags to specify which classes get added but what I really want it to do is something like this:
Copy all of the imports of all of my classes into the jar, and copy all of their imports, and all of their import's imports and so on.
Am I thinking about the problem all wrong? How can I get maven to automatically minimize the jar size depending on which imports are used? (please don't just say this maven plugin) because I am already at a dead end, I need an example of what to add to my pom to accomplish these tasks.
ProGuard can remove unused classes and even more.
ProGuard is a free Java class file shrinker, optimizer, obfuscator, 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.
First, you should package a jar with dependencies. It can be easily done with maven-assembly-plugin:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.4</version>
<configuration>
<archive>
<manifest>
<mainClass>com.test.HelloWorld</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Then configure proguard to optimize generated jar. For maven projects, use proguard-maven-plugin:
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.10</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>proguard</goal></goals>
</execution>
</executions>
<configuration>
<injar>${project.build.finalName}-jar-with-dependencies.jar</injar>
<outjar>${project.build.finalName}-small.jar</outjar>
<outputDirectory>${project.build.directory}</outputDirectory>
<options>
<option>-dontobfuscate</option>
<option>-dontwarn com.google.**</option>
<option>-keep public class com.test.HelloWorld {public static void main(java.lang.String[]);}</option>
</options>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
</libs>
</configuration>
</plugin>
After these steps run
mvn clean install
and check target/<artifact name>-small.jar
- it should contain only classes that are actually used in runtime.
Please note that there might be some issues if your code or your dependencies use reflection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With