Reputation: 11377
Given a regular java gradle project, we have some entry main method which is defined in the jar manifest, and bunch of dependencies.
Now normally when we create a distribution we may use application plugin and have some structure like this as output
/bin (some splatform specific scripts that point to our jar)
/lib (our jar + all dependencies with their dependencies etc...)
Problem is that even though we used just few classes from our direct dependencies, they and all the transitive dependencies will end up in a distribution. For example from 100M of distribution only 1M is actually code that can possibly run and may have any relation to our application...
Tool like proguard can shrink code in a particular jar with various optimizations but it won't care if the code is unused. By unused i mean the main method is the entry point of the jar, and depending on the code in main it may never ever use majority of the code in the actual application jar and a lot more in library jars...
Our goal is to create this 1M jar that has only code that it actually will use, taking into consideration what is the main method in the jar manifest...
I've searched a lot but couldn't find any solution to this, proguard was very close, but i can't find any way to make it only care about specific flow of the code not all the code.
Are there any tools that can do this?
Upvotes: 1
Views: 303
Reputation: 6200
Your description of what ProGuard does is wrong:
Tool like proguard can shrink code in a particular jar with various optimizations but it won't care if the code is unused. By unused i mean the main method is the entry point of the jar, and depending on the code in main it may never ever use majority of the code in the actual application jar and a lot more in library jars...
What you describe as unused code
is exactly what ProGuard does in its shrinking step. Starting from a seed (in your case the main
method), it will look for any class/method that is being used and remove everything else.
If too many classes are being kept, it is most likely due to some -keep
rules. You will have to adjust them as needed. If the 3rd-party libraries do not use reflection for example, no keep should be needed.
ProGuard can also remove dead code
in its optimization step: any instructions inside a method that will never be executed according to flow analysis will get removed. This technique operates on instruction-level, whereas shrinking works on class-level.
Upvotes: 1