注:我把题目改为更准确。
下面是我的问题:当使用RMI在客户机和服务器之间进行通信时,客户端是否需要在其类路径中包含Stub,还是该Stub应该只位于服务器端?
注:“完整”故事:
我目前正在开发一个调用计算引擎的web应用程序。这两个元素之间的通信使用RMI进行。
下面是该项目的Maven结构:
my-project
+- core
+- web-application
+- engineweb-application和engine都依赖于core。
在core模块中,我定义了一个接口:
public interface MyEngine extends java.rmi.Remote {
MyResults calculate() throws RemoteException;
}在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接口编写了一个调用引擎模块的类。
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答案中所解释的那样,确实解决了这个问题。唯一的区别是我没有无安全管理器: RMI类装入器已禁用堆栈跟踪中的消息.
编辑2:如果我在WEB-INF/lib中复制engine.jar,那么通信是正确的。但我不应该在我的web应用程序中添加引擎库.
发布于 2012-03-12 12:40:26
我终于解决了我的问题。在这一页,据说
在J2SE 5.0版本中,远程对象的存根类不再需要使用remote编译器预先生成,除非远程对象需要支持运行在预5.0vms中的客户端。
在使用Java 6时,我决定简单地删除pom.xml文件中的pom.xml任务.而且起作用了!
也许Stub在服务器(我的引擎)中的存在会给JVM造成一些混乱,这会产生我得到的错误.
发布于 2012-03-12 09:05:29
您没有使用安全管理器:
您是否有策略文件(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
https://stackoverflow.com/questions/9663999
复制相似问题