When packaging Java projects we rely on Maven, but I assume the problems are the same with Gradle or Ant. Sometimes we run into the problem known as "Jar Hell" if one dependency relies on a transitive dependency in a different version than another dependency, guava as an often occurring example. If the loaded library has conflicting classpaths or function signatures you get the infamous ClassNotFoundException
or NoSuchMethodError
at runtime. ("funny" that one is an Exception and the other an Error btw^^)
I know that the problems can be somewhat solved with dependencyManagement
, using the Maven Shade Plugin and detected using the Enforcer Plugin with e.g. "Dependency Convergence". I am also aware of the many questions related to these methods as e.g. SO Link.
Now my question is how can we detect these errors at compile time? As I understand the java compiler javac
itself doesn't really have mechanisms for packaging applications itself, but I would assume that a jar
packager such as shade
, assembly
or the like would be able to detect if all classes and methods are present? Obviously assuming that no classes will be loaded at runtime. (Which is the case for us as we mainly build stand-alone applications and don't deal with application servers such as JBoss/Wildfly)