ClassLoader used in Module.loadModuleInfoClass should be self-first
Michael Rasmussen
MRasmussen at perforce.com
Fri Mar 27 15:34:09 UTC 2020
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.
More information about the core-libs-dev
mailing list