Spring Boot RMI客户端调用报错:org/omg/CORBA/COMM_FAILURE类未找到
先处理你遇到的核心异常,再逐一解答你的两个疑问:
一、核心异常:java.lang.NoClassDefFoundError: org/omg/CORBA/COMM_FAILURE
这个问题的根源是JDK 9及以上版本移除了CORBA模块(CORBA属于Java EE组件,JDK 9开始模块化后默认不再包含),而Spring的RmiClientInterceptorUtils类在判断RMI连接失败时,依赖了org.omg.CORBA.COMM_FAILURE类,导致运行时找不到该类。
解决方案:
根据你使用的JDK版本选择对应方式:
- JDK 11+版本:添加第三方CORBA依赖(官方已完全移除该模块)
如果用Maven,在客户端pom.xml中加入:
Gradle项目则添加:<dependency> <groupId>org.glassfish.corba</groupId> <artifactId>glassfish-corba-orb</artifactId> <version>4.2.4</version> </dependency>implementation 'org.glassfish.corba:glassfish-corba-orb:4.2.4' - JDK 9-10版本:可以通过JVM启动参数恢复CORBA模块
在客户端启动时添加参数:--add-modules java.corba
二、你的疑问解答
1. 客户端与服务端接口路径不同是否导致类找不到?
RMI对远程接口的全限定类名(包名+类名)有严格一致性要求,只要两端接口的包名、类名完全一致,就不会因为路径问题导致类找不到。从你的代码来看,服务端和客户端的接口都是com.cw.appif.ServerServiceIF,包名完全匹配,这部分是没问题的。
但需要额外注意两个点:
- 接口的参数类(比如
User)必须实现Serializable接口,否则会触发序列化异常; - 两端接口的字节码必须完全一致(比如方法签名、返回值类型不能有差异),否则会出现类版本不匹配的问题。
2. 调试时service->h->advised->targetSource->targetClass为null是否正常?
这是完全正常的。RmiProxyFactoryBean创建的是动态代理对象,它使用DynamicTargetSource实现延迟加载——只有当你第一次调用远程方法(比如service.auth(user))时,代理才会去连接RMI注册表并获取远程对象。在调用方法之前,targetClass就是null,这是Spring RMI代理的设计逻辑。
你看到的null是因为连接失败(就是上面的CORBA类找不到问题),导致代理始终无法初始化远程对象,解决CORBA依赖问题后,成功连接服务端时targetClass会被自动赋值。
额外潜在问题提醒
你的服务端ServerService类中,static List<User> clients;仅做了声明,没有初始化(比如clients = new ArrayList<>();),调用clients.add(user)会直接抛出NullPointerException,记得补全初始化逻辑。
内容的提问来源于stack exchange,提问作者Blanderbuss

