注意:我将问题标题更改为更精确

这是我的问题:使用RMI在客户端和服务器之间进行通信时,客户端是否需要在类路径中包含Stub,或者该Stub应该只在服务器端吗?


注意,“完整”的故事:

我目前正在开发一个调用计算引擎的Web应用程序。这两个元素之间的通信是使用RMI进行的。

这是项目的Maven结构:

my-project
 +- core
 +- web-application
 +- engine


web-applicationengine都依赖于core

core模块中,我定义了一个接口:

public interface MyEngine extends java.rmi.Remote {

    MyResults calculate() throws RemoteException;

}


engine模块(从RMI角度来看是服务器)中,我定义此接口的实现:

public class MyEngineImpl extends UnicastRemoteObject implements MyEngine {

    public MyResults calculate() throws RemoteException {
        ...
    }

    public static void main(String... args) {
        MyEngine engine = new MyEngineImpl();
        Registry registry = LocateRegistry.createRegistry(1418);
        registry.rebind("my-engine", engine);
    }

}


最后,在web-application上,我使用core的接口编写了一个调用引擎模块的类:

public class RemoteEngineFacade {

    public MyResults callCalculate() throws RemoteException {
        Registry localisation = LocateRegistry.getRegistry("url-of-engine", 1418);
        MyEngine engine = (LiquidityEngine) localisation.lookup("my-engine");
        return engine.calculate();
    }

}


RMI编译由rmic Maven插件完成:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>rmic-maven-plugin</artifactId>
    <version>1.1</version>
    <executions>
        <execution>
            <id>rmi compilation</id>
            <goals>
                <goal>rmic</goal>
            </goals>
            <configuration>
                <outputDirectory>target/classes</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>


(请注意,此插件定义是在每个模块上进行的)

现在,在部署应用程序之后,当web-application调用engine时,我在Web应用程序日志中收到以下错误:

2012-03-12 09:42:37 ERROR [xxx.RemoteEngineFacade] Engine is unable to respond to the request
java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
    java.lang.ClassNotFoundException: xxx.MyEngineImpl_Stub (no security manager: RMI class loader disabled)
    at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
    at xxx.RemoteEngineFacade.callCalculate(RemoteEngineFacade.java:50)
    ...


我不明白为什么它要在web-application侧寻找Stub,因为通常该Stub只能位于RMI服务器上(在我的上下文中为engine)。

你知道我的问题在哪里吗?

谢谢。



编辑:如Riddhish.Chaudhari的回答所述,设置安全管理器可以解决此问题。唯一的区别是我没有安全管理器:stacktrace中的RMI类加载器已禁用消息...



编辑2:如果我在WEB-INF/lib中复制engine.jar,则表明通信正确。但是我不必在我的Web应用程序中添加引擎库...

最佳答案

我终于解决了我的问题。 In this page,据说


  从J2SE 5.0版本开始,远程对象的存根类不再
  需要使用rmic stub编译器进行预生成,除非
  远程对象需要支持在5.0之前的VM中运行的客户端


当我使用Java 6时,我决定只删除我的rmic文件中的pom.xml任务...,它起作用了!

也许服务器(我的引擎)中存在Stub会对JVM造成一些混乱,这会产生我得到的错误...

关于java - 为什么RMI客户端需要在其类路径中包含 stub ?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9663999/

10-14 08:44