My experience with Java class loading is limited. With tools like Maven I have a rusty understanding of how they resolve dependency versions. But I've hit a problem that's making me question how Java loads classes.
My scenario, I have a dependency on version 30.1.1-jre
of com.google.guava
. I also have a shaded jar which has a dependency on Guava 18.0.
In my application I end up seeing the following exception
java.lang.IncompatibleClassChangeError: Class com.google.common.base.Suppliers$MemoizingSupplier does not implement the requested interface java.util.function.Supplier
which I cannot reproduce locally. Based on https://github.com/crabhi/celery-java/issues/9 it sounds like this error is produced when an older version of Guava is on the classpath.
Checking the classes in the war I see
WEB-INF/lib/java-driver-shaded-guava-25.1-jre-graal-sub-1.jar.d/com/datastax/oss/driver/shaded/guava/common/base/Suppliers$MemoizingSupplier.class
WEB-INF/lib/nautilus-es2-library-2.3.4.jar.d/com/google/common/base/Suppliers$MemoizingSupplier.class
WEB-INF/lib/guava-30.1.1-jre.jar.d/com/google/common/base/Suppliers$MemoizingSupplier.class
This makes me think the shaded jars are causing a problem.
Is that possible? Are there any articles explaining how classes are loaded when shaded jars enter the picture?