Java8升级至17 WAR项目RMI类找不到错误修复求助
修复Java 17升级中RMI相关ClassNotFoundException问题
针对你遇到的java.lang.ClassNotFoundException: com.sun.corba.ee.impl.javax.rmi.PortableRemoteObject (no security manager: RMI class loader disabled)错误,以下是务实的修复步骤:
1. 替换私有API引用
代码中直接依赖com.sun.corba.ee.impl.javax.rmi.PortableRemoteObject这类Sun/Oracle私有API是核心问题——Java 11+已彻底移除这些非标准实现。将所有引用替换为标准RMI API:
- 替换为
javax.rmi.PortableRemoteObject(对应Java EE标准) - 若使用Jakarta EE兼容包,可替换为
jakarta.rmi.PortableRemoteObject(需确保glassfish-corba版本匹配)
例如,原代码:
import com.sun.corba.ee.impl.javax.rmi.PortableRemoteObject; // ... PortableRemoteObject.narrow(obj, MyInterface.class);
替换为:
import javax.rmi.PortableRemoteObject; // ... PortableRemoteObject.narrow(obj, MyInterface.class);
2. 正确配置glassfish-corba依赖
确保添加完整的glassfish-corba套件依赖,而非零散jar包。以Maven为例,在pom.xml中添加:
<dependencies> <!-- 标准RMI API --> <dependency> <groupId>javax.rmi</groupId> <artifactId>javax.rmi-api</artifactId> <version>1.0.6</version> </dependency> <!-- glassfish-corba的实现类 --> <dependency> <groupId>org.glassfish.corba</groupId> <artifactId>glassfish-corba-orb</artifactId> <version>4.2.4</version> <scope>compile</scope> </dependency> <!-- 可选:如果需要命名服务支持 --> <dependency> <groupId>org.glassfish.corba</groupId> <artifactId>glassfish-corba-naming</artifactId> <version>4.2.4</version> <scope>compile</scope> </dependency> </dependencies>
Gradle用户可对应转换为依赖配置,确保依赖包被打包到WEB-INF/lib目录下。
3. 解决RMI类加载器禁用问题
Java 17默认在无安全管理器时禁用RMI类加载器,需通过JVM参数开启兼容模式:
在Tomcat的启动脚本(如catalina.sh或catalina.bat)中添加以下参数:
# Linux/macOS CATALINA_OPTS="$CATALINA_OPTS -Djava.rmi.server.useCodebaseOnly=false -Djdk.rmi.server.proxyTrustCodebase=true" # Windows set CATALINA_OPTS=%CATALINA_OPTS% -Djava.rmi.server.useCodebaseOnly=false -Djdk.rmi.server.proxyTrustCodebase=true
这两个参数的作用:
-Djava.rmi.server.useCodebaseOnly=false:允许RMI从指定的代码库加载类-Djdk.rmi.server.proxyTrustCodebase=true:信任指定代码库中的类,避免类加载权限问题
4. 检查Tomcat类加载配置
确保Tomcat不会干扰Web应用的类加载:
- 不要将glassfish-corba的jar包放到Tomcat的
lib目录下,避免类加载冲突 - 确认WAR包的
WEB-INF/lib目录下包含所有glassfish-corba相关依赖 - 若Tomcat有自定义类加载配置,确保Web应用的类加载器优先加载自身
WEB-INF/lib中的类
5. 备选方案:避免动态类加载
如果上述步骤仍有问题,可将RMI通信中需要的所有实体类、接口类直接打包到WAR包中,彻底避免RMI动态加载类的需求,从根源上绕开类加载器问题。
内容的提问来源于stack exchange,提问作者SRIJAN GIRDHAR
相关产品推荐
相关产品推荐

