The ClassLoader used to create the pseudo module-info interface is
parent-first, so if there are any modules on the classpath, it will try to load
the module-info.class file from there instead of the synthetic that is being
generated in the method. This interface is generated if you try to read
annotations from the Module.
Simple example to reproduce:
/* --- module-info.java --- */
@Deprecated module com.test {}
/* --- com/test/Main.java --- */
package com.test;
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(Main.class.getModule().isAnnotationPresent(Deprecated.class));
}
}
> java -p target/classes -m com.test/com.test.Main
true
> java -cp target/classes -p target/classes -m com.test/com.test.Main
Exception in thread "main" java.lang.NoClassDefFoundError: module-info is not a
class because access_flag ACC_MODULE is set
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at (.....)
The problem here is that the ClassLoader is parent-first, so it will search
parent for a "module-info" class, and use that if it finds it.
If the ClassLoader was self-first this problem would not appear, it would still
delegate to parent for everything but the synthetic module-info class.
/Michael
This e-mail may contain information that is privileged or confidential. If you
are not the intended recipient, please delete the e-mail and any attachments
and notify us immediately.