Got a series of projects where code in one project uses Class.forName to load a class from another Project, which in turn makes use of a class in a third project. When I run the code in eclipse using a Java 10 JRE I get a NoClassDefFoundError but I do not see this when running (with the same JRE) at the command line. Neither do I see it when running against java 8 in eclipse.
The smallest set up I could do to replicate it was with 3 project, Project 1, Project 2 and Project 3. I've set eclipses compiler compliance level to 1.8 but did see the problem when this was 10 too.
Project 1 contains the following class:
package clayton.alex.foo;
public class Foo {
public static void setFooInterface(FooInterface newInteface) {
// Do something
}
public interface FooInterface {
public void callback();
}
}
Then Project 2 has Project 1 on its class path, and contains the following class:
package clayton.alex.bar;
import clayton.alex.foo.Foo;
import clayton.alex.foo.Foo.FooInterface;
public class Bar {
public static void doAFoo() {
Foo.setFooInterface(new FooInterface() {
@Override
public void callback() {
// Some Code
}
});
}
}
Finally Project 3 contains Project 2 only (i.e it does not include Project 1) on it's classpath. It has the following code in it:
package clayton.alex.buzz;
public class BuzzApp {
public static void main(String[] args) {
try {
Class.forName("clayton.alex.bar.Bar");
}
catch (ClassNotFoundException | SecurityException
| IllegalArgumentException | NoClassDefFoundError e) {
System.out.println("ERROR "+e.getLocalizedMessage());
e.printStackTrace();
}
}
}
When I run this code in eclipse with the oracle java 10.0.1 JRE I get the following error:
ERROR clayton/alex/foo/Foo$FooInterface
java.lang.NoClassDefFoundError: clayton/alex/foo/Foo$FooInterface
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:291)
at clayton.alex.buzz.BuzzApp.main(BuzzApp.java:8)
Caused by: java.lang.ClassNotFoundException: clayton.alex.foo.Foo$FooInterface
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:190)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499)
... 3 more
If instead I run using Java 1.8.0_52 then I see not such error. The program just runs to completion.
Also if Instead compile and generate jar files using ant; using similar project hierachy (i.e project 2 has project 1 on it's class path and project 3 has project 2 only on its class path) then again then the code completes successfully, even with the same Java 10 JRE.
Any idea why this would be happening? Why do I only see the error when running in eclipse, and when running with Java 10 (I think it can be seen with Java 9 too, but have not tested that fully)?