为什么RMI客户端需要在其类路径中使用Stub?

时间:2012-03-12 08:49:00

标签: java rmi

注意:我更改了问题标题

以下是我的问题:当使用RMI在客户端和服务器之间进行通信时,客户端是否需要在其类路径中具有Stub,或者执行此操作{{1}应该只在服务器端?

<小时/> 注意,“完整”故事:

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

进行的

这是项目的Maven结构:

Stub

my-project +- core +- web-application +- engine web-application都依赖于engine

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

core

public interface MyEngine extends java.rmi.Remote { MyResults calculate() throws RemoteException; } 模块(从RMI的角度来看是服务器)中,我定义了这个接口的实现:

engine

最后,在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

RMI编译由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(); } } Maven插件:

完成
rmic

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

现在,在部署应用程序后,当<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时,我在Web应用程序日志上收到以下错误

engine

我不明白为什么它在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) ... 侧寻找Stub,因为通常Stub只能位于RMI服务器上(我的上下文中为web-application)。 / p>

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

感谢。


编辑:设置安全管理器,如Riddhish.Chaudhari中所述,答案确实解决了问题。唯一的区别是我在堆栈跟踪中没有没有安全管理器:RMI类加载器已禁用消息...


编辑2 :如果我在我的engine中复制engine.jar,则会正确进行通信。但我不应该在我的网络应用程序中添加引擎库...

2 个答案:

答案 0 :(得分:2)

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

  

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

当我使用Java 6时,我决定简单地删除rmic文件中的pom.xml任务......并且它有效!

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

答案 1 :(得分:-2)

您没有使用安全管理器:

您是否有策略文件(mypolicy.policy):

grant {
  permission java.security.AllPermission;
};

并使用

运行您的程序
java -Djava.security.manager -Djava.security.policy=/some/path/myplicy.policy MyClass

使用以下链接获取有关如何使用安全策略权限的完整示例

http://www.javacoffeebreak.com/articles/javarmi/javarmi.html