4

What do you normally do when you want to make use of some utility which is part of some Java library? I mean, if you add it as a Maven dependency is the whole library get included in the assembled JAR?

I don't have storage problems of any sort and I don't mind the JAR to get bloated but I'm just curious if there's some strategy to reduce the JAR size in this case.

Thanks

J Fabian Meier
  • 33,516
  • 10
  • 64
  • 142
IsaacLevon
  • 2,260
  • 4
  • 41
  • 83
  • 2
    By default the jar with your code and jar files for dependencies are entirely separate. You *can* bundle them in a "fat jar" (also goes under some other names), but that's a separate step, not a usual one. And yes, it usually means you "carry along" the whole library, even if you don't use it. – Joachim Sauer Oct 01 '20 at 11:50
  • Dependencies are not part of the JAR by default but you can configure this. If you declare a dependency, you will download it and all transient dependencies that are not optional. – dan1st Oct 01 '20 at 11:51
  • It seems to me that Maven, and most other automated dependency management systems, are predicated on the fact that we have unlimited storage. I don't really see a solution to this problem other than taking back control of dependencies. After all, we managed in the past. – Kevin Boone Oct 01 '20 at 13:25
  • 1
    classes are lazy loaded anyway, so though you _carry_ the entire jar, you might _load_ far less from it. – Eugene Oct 01 '20 at 14:30

1 Answers1

1

It is even worse: You do not only add the "whole library" to your project, but also its dependencies, whether you need them or not.

Joachim Sauer is right in saying that you do not bundle dependencies into your artifact unless you want it to be runnable. But IMHO this just moves the problem to a different point. Eventually, you want to run the stuff. At some point, a runnable JAR, a WAR or an EAR is built and it will incorporate the whole dependency tree (minus the fact that you get only one version per artifact).

The Maven shade plugin can help you to minimise your jar (see Minimize an Uber Jar correctly, Using Shade-Plugin) by only adding the "necessary" classes. But this is of course tricky in general:

  • Classes referenced by non-Java elements are not found.
  • Classes used by reflection are not found.
  • If you have some dependency injection going on, you only use the interfaces in your code. So the implementations might get kicked out.

So your minimizedJar might in general just be too small.

As you see I don't know any general solution for this.

What are sensible approaches?

  • Don't build JARs that have five purposes, but build JARs that are small. To avoid a huge number of different build processes, use multi-module projects.
  • Don't add libraries as dependencies unless you really need them. Better duplicate a method to convert Strings instead of adding a whole String library just for this purpose.
J Fabian Meier
  • 33,516
  • 10
  • 64
  • 142