I have a library consisting of multiple modules:
- core
- guava
The core
module is mandatory, while guava
is optional. There are other optional modules (this question represents a minimal testcase).
Each module exposes a set of methods that the user can invoke:
class CoreVerifier
{
MapVerifier verify(Map);
}
class GuavaVerifier
{
MultimapVerifier verify(Multimap);
}
What I want
Provide users a class that exports all the methods in a single place:
class UnifiedVerifier { MapVerifier verify(Map); MultimapVerifier verify(Multimap); }
I want users to be able to use this class even if optional modules (e.g. guava) are missing at runtime. Meaning, the
UnifiedVerifier
is compiled with all libraries on the classpath but at runtimeMultimapVerifier
referenced by the second method is not present.- Users should be able to invoke the first method even if the second method (that depends on the guava module) is not available at runtime.
- If users attempt to invoke the second method (that depends on the missing module) they should get a runtime exception.
What actually happens
If users invoke the first method from application code javac fails with:
Application.java: cannot access MultimapVerifier class file for MultimapVerifier not found
Meaning, even though the first method is well-defined (the core module is available at compile-time) the compiler refuses to proceed because the second method (which they are not using) is referencing a class which is missing from the classpath.
Is there a way to achieve this sort of thing in Java?
Similar technique by assertj
assertj has a clever static-import mechanism whereby they declare a different Assertions
class per module (core, guava) and Java's static import picks up the right method depending on the types you pass in. I am already using a similar mechanism for static methods, but now I want something similar for a case where I can't use static methods.