Jdk16中JcTree的使用问题

因为jdk16进行了强制的模块化使用限制, 需要增加add-opens去进行模块的放开, 但是如果每次都需要在项目pom文件或者启动命令中增加,非常不优雅。而且很多重复的命令。
所以想有没有更好的办法去解决。
看了lombok1.18.20中的解决方法,这边来总结一下。lombok这个问题的讨论

public abstract class Example extends AbstractProcessor {
    @Override
    public final synchronized void init(ProcessingEnvironment processingEnv) {
    }
    public static void addOpens() {
        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",
            "com.sun.tools.javac.api",
            };

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

    private static Unsafe getUnsafe() {
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true);
            return (Unsafe) theUnsafe.get(null);
        } catch (Exception e) {
            return null;
        }
    }

    private static Object getJdkCompilerModule() {
        try {
            Class<?> cModuleLayer = Class.forName("java.lang.ModuleLayer");
            Method mBoot = cModuleLayer.getDeclaredMethod("boot");
            Object bootLayer = mBoot.invoke(null);
            Class<?> cOptional = Class.forName("java.util.Optional");
            Method mFindModule = cModuleLayer.getDeclaredMethod("findModule", String.class);
            Object oCompilerO = mFindModule.invoke(bootLayer, "jdk.compiler");
            return cOptional.getDeclaredMethod("get").invoke(oCompilerO);
        } catch (Exception e) {
            return null;
        }
    }

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

    private static long getFirstFieldOffset(Unsafe unsafe) {
        try {
            return unsafe.objectFieldOffset(Parent.class.getDeclaredField("first"));
        } catch (NoSuchFieldException e) {
            // can't happen.
            throw new RuntimeException(e);
        } catch (SecurityException e) {
            // can't happen
            throw new RuntimeException(e);
        }
    }

    public static class Parent {
        boolean first;
    }
}

其中调用了

long firstFieldOffset = getFirstFieldOffset(unsafe);
unsafe.putBooleanVolatile(m, firstFieldOffset, true);

其中的含义不太能清楚,看起来是个激活模块的初始化操作,去除之后添加模块权限的操作是会失效的。

有懂的大佬希望可以告知一下是不是这样

在注解解析器中添加上诉代码后就可以正常在java16中使用jcTree啦

Wish.

Do.

原文链接:https://www.cnblogs.com/my1024/p/17382868.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Jdk16中JcTree的使用问题 - Python技术站

(0)
上一篇 2023年5月9日
下一篇 2023年5月9日

相关文章

  • tomcat 启动时卡住问题排查及解决方法

    Tomcat 启动时卡住问题排查及解决方法 问题现象 在启动 Tomcat 时,控制台输出日志较少,没有显示任何正在启动的进程,且进程状态一直卡在某个进程上,无法启动成功。 问题原因 防火墙限制 在部分云服务器或者企业内部网络环境下,会有防火墙限制,导致 Tomcat 无法正常启动。可以通过关闭防火墙或者添加相应的端口规则来解决。 JVM 堆栈调整不合理 如…

    Java 2023年6月2日
    00
  • SpringBoot配置外部静态资源映射问题

    在Spring Boot中,我们可以使用@ConfigurationProperties注解来配置应用程序的属性。在这些属性中,有一个非常重要的属性是spring.resources.static-locations,它用于指定应用程序的静态资源目录。本文将详细讲解如何配置Spring Boot的静态资源映射。 步骤一:添加静态资源 我们需要在应用程序的sr…

    Java 2023年5月15日
    00
  • SpringBoot路径映射实现过程图解

    下面是关于“SpringBoot路径映射实现过程图解”的完整攻略,包含两个示例说明。 SpringBoot路径映射实现过程图解 在SpringBoot中,我们可以使用注解来实现路径映射。路径映射是指将HTTP请求映射到相应的处理方法上。本文将介绍SpringBoot中路径映射的实现过程,并提供两个示例说明。 实现过程 在SpringBoot中,我们可以使用@…

    Java 2023年5月17日
    00
  • 详解springboot采用多数据源对JdbcTemplate配置的方法

    请您耐心阅读以下攻略,我将分为以下几个部分进行讲解: Spring Boot多数据源配置 JdbcTemplate添加多数据源支持 示例代码 1. Spring Boot多数据源配置 在Spring Boot中配置多数据源其实非常简单,只需要在application.properties(或application.yml)中配置多组数据源即可。以下是一个简单…

    Java 2023年5月20日
    00
  • Java线程间的通信方式详解

    Java线程间的通信方式详解 在Java中,线程间的通信是指两个或多个线程之间通过某种方式进行交流、协作的过程,Java线程间的通信主要有以下几种方式: 1.共享内存 共享内存是指多个线程之间共享同一块内存区域,通过修改该内存区域来实现线程之间的通信。Java中的共享内存通信方式有synchronized、volatile、wait和notify等。 示例1…

    Java 2023年5月19日
    00
  • SpringBoot连接Hive实现自助取数的示例

    下面是“SpringBoot连接Hive实现自助取数的示例”的完整攻略: 一、准备工作 在开始前我们需要准备以下工具和环境: JDK 1.8及以上版本; Maven; IntelliJ IDEA; Hive。 其中,Hive是我们连接数据源的关键。如果你还没有安装Hive,可以参考以下链接进行安装: Hive官网:http://hive.apache.org…

    Java 2023年5月20日
    00
  • Ajax修改购物车示例

    下面是详细的“Ajax修改购物车示例”的攻略: 第一步:创建购物车页面 首先,需要创建一个基础的购物车页面,包含商品列表和购物车数量和总价等信息。可以使用 HTML 和 CSS 来创建一个简单的购物车页面。 第二步:添加商品和购物车的数据 在购物车页面上添加一些商品和购物车的数据,可以使用 JavaScript 来处理这些数据。例如,可以在 JavaScri…

    Java 2023年6月15日
    00
  • SpringBoot整合mybatis的方法详解

    下面我来为你详细讲解“SpringBoot整合mybatis的方法详解”的完整攻略。 准备工作 在maven中引入spring-boot-starter-jdbc、mybatis-spring-boot-starter、mysql-connector-java等依赖。 在application.properties中配置数据库信息和mybatis配置。 sp…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部