注意:我更改了问题标题
以下是我的问题:当使用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,则会正确进行通信。但我不应该在我的网络应用程序中添加引擎库...
答案 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