JDK8升级到JDK17之后,打包xjar成功,但是在容器中运行错误
错误日志:
Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field private final jdk.internal.loader.URLClassPath java.net.URLClassLoader.ucp accessible: module java.base does not "opens java.net" to unnamed module @6f29c911
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
at io.xjar.reflection.XReflection.field(XReflection.java:20)
at io.xjar.boot.XBootClassLoader.<init>(XBootClassLoader.java:41)
at io.xjar.boot.XJarLauncher.createClassLoader(XJarLauncher.java:31)
at org.springframework.boot.loader.ExecutableArchiveLauncher.createClassLoader(ExecutableArchiveLauncher.java:109)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:55)
at io.xjar.boot.XJarLauncher.launch(XJarLauncher.java:26)
at io.xjar.boot.XJarLauncher.main(XJarLauncher.java:22)
panic: exit status 1
goroutine 1 [running]:
main.main()
/usr/local/product/xjar.go:86 +0x545
找到原因:
出现这个错误的原因是 JDK9 往后引入了Java Platform Module System(模块化)这个概念,每个模块都是强封装的,而我们启动 JAR 包需要用到反射去访问目标类,这里提示没有权限;那我们只能在命令里增加参数,来特定打开某些需要打开的包才能正常启动项目,下面的命令增加了启动参数,JAR 包可以正常执行。
根据报错信息分析
上面的异常需要的参数就是(ALL-UNNAMED代表所有jdk编译出来的匿名类):
--add-exports java.base/jdk.internal.loader=ALL-UNNAMED
--add-exports java.base/java.net=ALL-UNNAMED
--add-exports java.base/java.lang=ALL-UNNAMED
加入命令解决:
./xjar java --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED -jar ./xxx.xjar