从lombok源码打开jdk.compile的方法

问题描述 投票:0回答:1

我参考了lombok.在jdk21中打开jdk.compile的方法,在注解处理器的初始化阶段打开jdk.complie

    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) {}
    }

我使用

maven clear install
命令将注释处理器打包成jar文件。将此注释处理器应用到其他项目。其他项目编译时出错

 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

我通过IDEA调试了编译过程。我发现 getOwnModule 方法返回未命名的模块 enter image description here

    private static Object getOwnModule() {
        try {
            Method m = Permit.getMethod(Class.class, "getModule");
            return m.invoke(LombokProcessor.class);
        } catch (Exception e) {
            return null;
        }
    }

当其他项目依赖注释处理器时,此方法将获取未命名模块。

        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
无法为unname模块打开jdk.compile

    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;

这说明jdk.compile没有打开成功。但是我在我的项目中添加了module-info.java

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;
}

我的项目是这里

java lombok java-module annotation-processing
1个回答
0
投票

正如Mark提到的,你应该确保项目使用模块路径,我不确定你正在使用的maven版本。但鉴于您的代码存储库,我可以看到您可能仍然会回退到旧版本的编译器插件。因此更喜欢明确指定,例如:

<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>
      </configuration>
    </plugin>
  </plugins>
</build>

我可以使用

mvn verify
并在我的机器上配置 JDK-21 进一步确认成功编译代码。

© www.soinside.com 2019 - 2024. All rights reserved.