此文档写于:2022-10,所在版本:koca 3.6.0-SNAPSHOT
本教程适用于 koca-base、koca-boot、koca-cloud、koca-admin (统称为基础包)在 Java 8 环境下 install 为 jar 的形式提供给 koca-application、koca-sample 在 Java11 或 Java 17 环境下运行。
经测试,基础包 在 Java 8 环境为 install 操作后,都可正常运行通过。
@[TOC]
koca-application & sample 在 Java 11 环境运行
1. koca-application
-
在 koca-cloud-admin-bootapp 下的 application.yml 增加解析 bex 的配置
koca: bex: enabled: true bex-path: classpath*:/bex/*-bex.xml
-
在 koca-admin-bootapp 下的 bootstrap.yml 增加解析 bex 的配置
koca: bex: enabled: true bex-path: classpath*:/bex/*-bex.xml
2. koca-sample
1、koca-log-sample - log-separate-samples - business - BusinessApplication
-
启动报错:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
-
原因:Java11 中不包含 javax.xml.bind 包
-
解决方法:在 pom.xml 加入
<dependency> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-ri</artifactId> <version>2.3.3</version> <type>pom</type> </dependency>
2、koca-other-samples - koca-config-server-sample
-
启动报错:
Caused by: java.net.URISyntaxException: Illegal character in opaque part at index 11: jar:file:D:\repo\com\szkingdom\koca\cloud\koca-cloud-config-server\3.6.0-SNAPSHOT\koca-cloud-config-server-3.6.0-SNAPSHOT.jar!/bex/config-audit-bex.xml
-
原因:bex解析异常
-
解决方法:
koca: bex: enabled: true bex-path: classpath*:/bex/*-bex.xml
koca-application & sample 在 Java 17 环境运行
1. koca-application
-
在 koca-cloud-admin-bootapp 下的 application.yml 增加解析 bex 的配置
koca: bex: enabled: true bex-path: classpath*:/bex/*-bex.xml
-
在 koca-admin-bootapp 下的 bootstrap.yml 增加解析 bex 的配置
koca: bex: enabled: true bex-path: classpath*:/bex/*-bex.xml
-
koca-cloud-admin-bootapp、koca-admin-bootapp 都需要在启动的VM选项中加上:
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
2. koca-sample
-
koca-sample 必须在上述 Java 11 测试改动的基础上作出相应的修改,才能成功运行其程序。
-
在 Java17 环境下,大多 启动类 出现如下问题:
如:ServerApplication
Caused by: java.lang.IllegalStateException: Failed to create adaptive instance: java.lang.IllegalStateException: Can't create adaptive extension interface org.apache.dubbo.rpc.Protocol, cause: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1757cd72 at org.apache.dubbo.common.extension.ExtensionLoader.getAdaptiveExtension(ExtensionLoader.java:568) ~[dubbo-2.7.6.jar:2.7.6] at org.apache.dubbo.config.ServiceConfig.<clinit>(ServiceConfig.java:118) ~[dubbo-2.7.6.jar:2.7.6] ... 23 common frames omitted Caused by: java.lang.IllegalStateException: Can't create adaptive extension interface org.apache.dubbo.rpc.Protocol, cause: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1757cd72 at org.apache.dubbo.common.extension.ExtensionLoader.createAdaptiveExtension(ExtensionLoader.java:980) ~[dubbo-2.7.6.jar:2.7.6] at org.apache.dubbo.common.extension.ExtensionLoader.getAdaptiveExtension(ExtensionLoader.java:564) ~[dubbo-2.7.6.jar:2.7.6] ... 24 common frames omitted Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @1757cd72 at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) ~[na:na] at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) ~[na:na] at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199) ~[na:na]
如:KocaServerApplication
java.lang.reflect.InaccessibleObjectException: Unable to make field private transient volatile java.lang.reflect.Parameter[] java.lang.reflect.Executable.parameters accessible: module java.base does not "opens java.lang.reflect" to unnamed module @192d43ce at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) ~[na:na] at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) ~[na:na] at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178) ~[na:na] at java.base/java.lang.reflect.Field.setAccessible(Field.java:172) ~[na:na] at com.fasterxml.jackson.databind.util.ClassUtil.checkAndFixAccess(ClassUtil.java:987) ~[jackson-databind-2.12.6.1.jar:2.12.6.1] Caused by: java.lang.RuntimeException: Unable to make field private transient volatile java.lang.reflect.Parameter[] java.lang.reflect.Executable.parameters accessible: module java.base does not "opens java.lang.reflect" to unnamed module @192d43ce
-
原因:根据查询的资料,大致意思如下:
异常是由Java 9及以上版本中引入的Java Platform Module System引起的,特别是强封装的实现。它仅在特定条件下允许access,最突出的条件是: - 类型必须是公共的 - 必须导出拥有的软件包 对于反射,导致异常的代码尝试使用相同的限制。更确切地说,异常是由对 setAccessible 的调用引起的。 为了确保程序成功运行,必须说服模块系统允许访问调用了setAccessible 的元素。
-
可以总结为:从 Java 9 开始,除非明确导出/打开它们,否则并非所有模块都可以访问。由于这是一个运行时问题,可以添加
--add-opens
为 JVM arg/CLI 选项以使该类型可访问。如果必须允许类路径上的代码进行深度反射以访问非公共成员,请使用 --add-opens 运行时选项。如果还想导出编译时可用的内部类型,可以使用--add-exports
,ALL-UNNAMED
意味着指定的包在整个代码库中可用。 -
解决方法:根据报错提示的内容,看需要打开哪个模块就在启动配置 VM Options 中添加,再启动即可。
如:KocaServerApplication 提示需要打开 “opens java.lang.reflect” 模块,添加如下:
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
-
如需添加多个模块,如:
--add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED
-
建议直接在报错信息下搜索 “opens” ,查看需要打开哪些模块就在启动类的 VM Options 中添加即可
-
常用的模块如下:
--add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED
-
参考资料:
module java.base does not "opens java.lang" to unnamed module - 滔天蟹 - 博客园
https://github.com/pinterest/ktlint/issues/1391
https://github.com/sshahine/JFoenix/issues/1200
https://dev.to/jjbrt/how-to-avoid-resorting-to-add-exports-and-add-opens-in-jdk-16-and-later-j3m