首页 > 其他分享 >Jdk16中JcTree的使用问题

Jdk16中JcTree的使用问题

时间:2023-05-08 19:23:50浏览次数:46  
标签:return javac Jdk16 使用 tools sun com class 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啦

标签:return,javac,Jdk16,使用,tools,sun,com,class,JcTree
From: https://www.cnblogs.com/my1024/p/17382868.html

相关文章

  • barrier 安装和使用 synergy最佳替代方案
    众所周知synergy是开源软件,但官编的正版是需要付费的,而barrier是synergyfork出的另一个版本,有热心网友便以维护,分支上开放了win和mac的下载,可以直接使用,而linux版本需要知己动手编译一下。附上github地址:https://github.com/debauchee/barrier/releases这个地址可......
  • NestJs 使用 RabbitMQ
    既然是使用RabbitMQ那先不管其他的把RabbitMQ装上再说RabbitMQ安装这里直接找他们官网就行https://www.rabbitmq.com/download.html这里我们选择使用docker安装快捷方便这里直接参考:https://juejin.cn/post/7198430801850105916我们要站在巨人的肩膀上,快速学习,具......
  • 实践|如何使用云函数去实现短信验证码功能
    目前,短信验证码广泛应用于用户注册、密码找回、登录保护、身份认证、随机密码、交易确认等应用场景。本文以使用云函数开发一个短信验证码登录注册服务为例,帮助您了解如何实现短信验证码功能。准备工作已 注册腾讯云 账号,并完成 企业实名认证。已购买短信套餐包。准备短信......
  • 【Oracle】使用xmlagg(xmlparse(content()).getclobval()拼接信息
    使用xmlagg(xmlparse(content()).getclobval()拼接信息简单来说格式如下xmlagg(xmlparse(content(内容||分割符)).getclobval()内容就是使用显示的数据部分,分隔符不同效果不同,分隔符可以使用chr()函数无分隔符xmlagg(xmlparse(content('这是一个字段:'||v.supercode||'、......
  • Java 中的机器学习正在加速图像处理 Java 开发人员可以使用预训练的机器学习模型快速
    来源: https://www.infoworld.com/article/3601711/machine-learning-in-java-is-speeding-image-processing.html 近年来,人们对机器学习的兴趣稳步增长。具体来说,企业现在在各种用例中使用机器学习进行图像识别。在 汽车行业、 医疗保健、 安全、 零售、 仓库中的自动化......
  • 关于Curl命令的使用
    最常用的curl命令1、发送GET请求curlURL例:curlURL?a=1&b=nihao2、发送POST请求curl-XPOST-d'a=1&b=nihao'URL3、发送json格式请求curl-H"Content-Type:application/json"-XPOST-d'{"abc":123,"bcd":"nihao"}......
  • 2023最新版——新手使用mybatis-plus 3.5.2并使用器代码生成器
    最新版——新手使用mybatis-plus3.5.2并使用器代码生成器第一步,pom文件引入依赖主要引入mybatis-plus和代码生成器需要使用的freemaker依赖<dependency> <groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</vers......
  • Linux使用源安装nginx
    1.安装依赖包##一键安装上面四个依赖yum-yinstallgcczlibzlib-develpcre-developensslopenssl-devel2.下载并解压安装包//创建一个文件夹cd/usr/localmkdirnginxcdnginx//下载tar包wgethttp://nginx.org/download/nginx-1.21.6.tar.gztar-xvfnginx-1.21.......
  • 使用Webstrom自动编译SASS/SCSS为CSS
    sass基于Ruby语言开发而成,因此安装sass前需要安装Ruby。(注:mac下自带Ruby无需在安装Ruby!)window下安装SASS首先需要安装Ruby,先从官网下载Ruby并安装。安装过程中请注意勾选AddRubyexecutablestoyourPATH添加到系统环境变量。Ruby官方下载地址安装完成后需测试安装有没有......
  • ChatGpt 使用体验
    一.回答随机性太高由于问题的答案天生具有多样性,因此对于不同的ChatGPT客户端,温度参数不一致导致返回的答案可能大相径庭,实际使用中的例子如下:prompt我的前端项目采用vue3+vite+element-plus开发,在一个el-table中有一列属性是创建人,关键代码如下,,我希望当我用鼠标点击到这个值......