Java class with possibly-missing run-time dependencies
classloader, dependency-management, java
Solution
Generally, when a class is first loaded, then if it refers to a class which does not exist, that might lead to an error. So yes, having one class do the check and another class actually access the external package without reflection will work as intended, at least on all implementations I've seen so far. It doesn't have to be an inner class.
The Linking section in the JVM specs give great freedom to implementations. If you don't use the two-class approach, then the verification of `U` in an implementation using eager linking will cause an attempt to load `X` which results in a `LinkageError`. The specs don't require the references class to be verified as well, but neither does it forbid such early verification. It does however require that
any error detected during resolution must be thrown at a point in the program that (directly or indirectly) uses a symbolic reference to the class or interface.
Seems you should be safe to assume that the error is only thrown when you actually access your inner class. If you look at the history of this answer, you will find that I already changed my opinion twice, so there will be no guarantees that I read it correctly this time… :-/
Problem
I have utility class U that depends on a library X, and must go in a package that will be used from programs with X available (where it should do its normal stuff), and places without X (where it should do nothing). Without splitting the class in two, I have found a simple pattern that solves this: ``` package foo; import bar.MisteriousX; public class U { static private boolean isXPresent = false; static { try { isXPresent = (null != U.class.getClassLoader().loadClass("bar.MisteriousX")); } catch (Exception e) { // loading of a sample X class failed: no X for you } } public static void doSomething() { if (isXPresent) { new Runnable() { public void run() { System.err.println("X says " + MisteriousX.say()); } }.run(); } else { System.err.println("X is not there"); } } public static void main(String args[]) { doSomething(); } } ``` With this pattern, U requires X present to compile, but works as expected when run with or without X present. Unless all accesses to the X library are inside internal classes, this code launches a classloader exception. Questions: is import resolution guaranteed to work like this everywhere, or will it depend on JVM/ClassLoader implementation? Is there an established pattern for this? Is the above code-snippet too hackish to make it into production?