I referenced lombok.’s method of opening jdk.compile in jdk21,which opens jdk.complie at the initialization stage of the annotation processor
private static void addOpensForLombok() {
Class<?> cModule;
try {
cModule = Class.forName("java.lang.Module");
} catch (ClassNotFoundException e) {
return; //jdk8-; this is not needed.
}
Unsafe unsafe = getUnsafe();
Object jdkCompilerModule = getJdkCompilerModule();
Object ownModule = getOwnModule();
String[] allPkgs = {
"com.sun.tools.javac.code",
"com.sun.tools.javac.comp",
"com.sun.tools.javac.file",
"com.sun.tools.javac.main",
"com.sun.tools.javac.model",
"com.sun.tools.javac.parser",
"com.sun.tools.javac.processing",
"com.sun.tools.javac.tree",
"com.sun.tools.javac.util",
"com.sun.tools.javac.jvm",
};
try {
Method m = cModule.getDeclaredMethod("implAddOpens", String.class, cModule);
long firstFieldOffset = getFirstFieldOffset(unsafe);
unsafe.putBooleanVolatile(m, firstFieldOffset, true);
for (String p : allPkgs) m.invoke(jdkCompilerModule, p, ownModule);
} catch (Exception ignore) {}
}
I use the maven clear install
command to package the annotation processor into a jar file. Apply this annotation processor to other projects. Other projects compile with an error
class org.example.async.log.client.annotation.AsyncLogProcessor (in unnamed module @0x201c3cda) cannot access class com.sun.tools.javac.api.JavacTrees (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.api to unnamed module @0x201c3cda
I debugged the compilation process through IDEA. I found that the getOwnModule method returns the unnamed module
private static Object getOwnModule() {
try {
Method m = Permit.getMethod(Class.class, "getModule");
return m.invoke(LombokProcessor.class);
} catch (Exception e) {
return null;
}
}
This method will get the unnamed module when other projects that depend on the annotation processor.
try {
Method m = cModule.getDeclaredMethod("implAddOpens", String.class, cModule);
long firstFieldOffset = getFirstFieldOffset(unsafe);
unsafe.putBooleanVolatile(m, firstFieldOffset, true);
for (String p : allPkgs) m.invoke(jdkCompilerModule, p, ownModule);
} catch (Exception ignore) {}
implAddOpens
cannot open jdk.compile for unname module
private void implAddExportsOrOpens(String pn,
Module other,
boolean open,
boolean syncVM) {
Objects.requireNonNull(other);
Objects.requireNonNull(pn);
// all packages are open in unnamed, open, and automatic modules
if (!isNamed() || descriptor.isOpen() || descriptor.isAutomatic())
return;
This means that the jdk.compile was not opened successfully.However, I have added module-info.java in my project
import javax.annotation.processing.Processor;
import org.example.async.log.client.annotation.AsyncLogProcessor;
module org.example.async.log.client{
requires jdk.compiler;
requires jdk.unsupported;
exports org.example.async.log.client.annotation;
provides Processor with AsyncLogProcessor;
}
The project of annotation processor is here
Test projects that depend on the annotation processor are here
Update: According to the answer of Naman, I conduct the following experiments.
remove it from <annotationProcessorPaths>
I removed the custom annotation processor in the <annotationProcessorPaths>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>21</source>
<target>21</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-proc:full</arg>
<arg>-Xlint:all</arg>
<arg>-verbose</arg>
<arg>-XprintRounds</arg>
<arg>-XprintProcessorInfo</arg>
<arg>-Xmaxerrs</arg>
<arg>10000</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<!-- <path>-->
<!-- <groupId>org.example</groupId>-->
<!-- <artifactId>async-log-client</artifactId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </path>-->
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
However, this causes the custom annotator to not work. Although the compilation succeeded, the custom annotation processor compilation phase was skipped straight away
If both lombok and my custom annotation processor are removed, the compilation will report an error
class org.example.async.log.client.annotation.AsyncLogProcessor (in unnamed module @0x36359723) cannot access class com.sun.tools.javac.api.JavacTrees (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.api to unnamed module @0x36359723
The git branch is here
Use the jvm parameter to open jdk.compile instead of using code
I removed module-info.java from the annotation processor.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>21</source>
<target>21</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-proc:full</arg>
<arg>-Xlint:all</arg>
<arg>-verbose</arg>
<arg>-XprintRounds</arg>
<arg>-XprintProcessorInfo</arg>
<arg>-Xmaxerrs</arg>
<arg>10000</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED</arg>
<arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.example</groupId>
<artifactId>async-log-client</artifactId>
<version>1.1-SNAPSHOT</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
The error still happened.
: java.lang.IllegalAccessError: class org.example.async.log.client.annotation.AsyncLogProcessor (in unnamed module @0x77429040) cannot access class com.sun.tools.javac.api.JavacTrees (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.api to unnamed module @0x77429040
To this I added <fork>true<fork>
referenced by here. when I remove lombok, the error still happens. whenn I don’t remove lombok, my annotation processor is skiped
9