Java 17升级后如何修复LDAP错误
问题:升级Java 17后Spring LDAP报IllegalAccessError
我将环境升级至Java 17后,catalina.out中出现以下错误。已按其他帖子建议更新依赖,但问题仍未解决。当前运行环境:
- Java:java-17-openjdk-17.0.9.0.9-2.el9.x86_64
- Tomcat:9.0.82
使用的依赖:
<dependency> <groupId>org.springframework.ldap</groupId> <artifactId>spring-ldap-core</artifactId> <version>2.4.1</version> </dependency>
错误日志:
Caused by: java.lang.IllegalAccessError: class org.springframework.ldap.core.support.AbstractContextSource (in unnamed module @0x7e9e53cb) cannot access class com.sun.jndi.ldap.LdapCtxFactory (in module java.naming) because module java.naming does not export com.sun.jndi.ldap to unnamed module @0x7e9e53cb at org.springframework.ldap.core.support.AbstractContextSource.<clinit>(AbstractContextSource.java:77) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:172) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1295) ... 105 more
解决方案
这个错误是Java 9引入的模块系统(JPMS)导致的:com.sun.jndi.ldap.LdapCtxFactory属于java.naming模块,该模块默认不会将这个内部包导出给未命名模块(你的应用和2.4.x版本的Spring LDAP都属于未命名模块)。
方案1:升级Spring LDAP到兼容版本
Spring LDAP 2.4.x对JPMS的支持不完善,建议直接升级到2.5.x及以上版本(例如2.5.8),新版本已经适配了Java模块系统,不再直接依赖内部的com.sun.jndi.ldap.LdapCtxFactory类。
更新后的依赖配置:
<dependency> <groupId>org.springframework.ldap</groupId> <artifactId>spring-ldap-core</artifactId> <version>2.5.8</version> </dependency>
方案2:添加JVM启动参数(临时 workaround)
如果暂时无法升级依赖,可以在Tomcat的启动参数中添加以下JVM参数,强制让java.naming模块把com.sun.jndi.ldap包导出给所有未命名模块:
--add-exports java.naming/com.sun.jndi.ldap=ALL-UNNAMED
配置方式:
- Linux环境:编辑Tomcat的
bin/catalina.sh,在文件开头添加JAVA_OPTS="$JAVA_OPTS --add-exports java.naming/com.sun.jndi.ldap=ALL-UNNAMED" - Windows环境:编辑
bin/catalina.bat,添加set JAVA_OPTS=%JAVA_OPTS% --add-exports java.naming/com.sun.jndi.ldap=ALL-UNNAMED - 保存后重启Tomcat即可生效
注意:这个方案只是临时补救措施,依赖JDK内部API存在版本兼容风险,优先推荐升级Spring LDAP版本。
内容的提问来源于stack exchange,提问作者Meera
相关产品推荐
相关产品推荐

