Jdk16中JcTree的使用问题

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

pom文件时候添加

Copy Highlighter-hljs
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> <showDeprecation>true</showDeprecation> <showWarnings>true</showWarnings> <fork>true</fork> <compilerArgs> <!-- <arg>-Werror</arg>--> <arg>-Xlint:all</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> </compilerArgs> </configuration> </plugin> </plugins> </build>

注解解析器添加

Copy Highlighter-hljs
public abstract class Example extends AbstractProcessor { @Override public final synchronized void init(ProcessingEnvironment processingEnv) { } static { addOpens(); } 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; } }

其中调用了

Copy Highlighter-hljs
long firstFieldOffset = getFirstFieldOffset(unsafe); unsafe.putBooleanVolatile(m, firstFieldOffset, true);

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

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

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

最小demo项目地址

Wish.
Do.
#

posted @   MY1024-  阅读(208)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)

Wish.
Do.

点击右上角即可分享
微信分享提示
CONTENTS