Java 为什么RMI客户端需要将存根放在其类路径中?

Java 为什么RMI客户端需要将存根放在其类路径中?,java,rmi,Java,Rmi,注:为了更准确,我更改了问题标题 这里是我的问题:当使用RMI在客户机和服务器之间通信时,客户机是否需要在其类路径中包含存根,或者该存根是否应该只在服务器端 请注意,“完整”故事: 我目前正在开发一个调用计算引擎的web应用程序。这两个元素之间的通信使用RMI进行 以下是项目的Maven结构: my-project +- core +- web-application +- engine web应用程序和引擎都依赖于核心 在core模块中,我定义了一个接口: public interf

注:为了更准确,我更改了问题标题

这里是我的问题:当使用RMI在客户机和服务器之间通信时,客户机是否需要在其类路径中包含
存根
,或者该
存根
是否应该只在服务器端


请注意,“完整”故事:

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

以下是项目的Maven结构:

my-project
 +- core
 +- web-application
 +- engine
web应用程序
引擎
都依赖于
核心

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

public interface MyEngine extends java.rmi.Remote {

    MyResults calculate() throws RemoteException;

}
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);
    }

}
engine
模块(RMI的服务器)中,我定义了该接口的实现:

public interface MyEngine extends java.rmi.Remote {

    MyResults calculate() throws RemoteException;

}
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应用程序
上,我使用
核心
的接口编写了一个调用引擎模块的类:

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应用程序
端查找存根,因为通常存根只需位于RMI服务器上(在我的上下文中是
引擎

你知道我的问题在哪里吗

谢谢


编辑:设置安全管理器,如Riddhish中所述。Chaudhari的回答确实解决了问题。唯一的区别是,我在stacktrace中不再有无安全管理器:RMI类装入器禁用消息



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

您没有使用安全管理器:

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

并使用

java -Djava.security.manager -Djava.security.policy=/some/path/myplicy.policy MyClass
使用下面的链接以获取如何使用安全策略权限的完整示例


您没有使用安全管理器:

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

并使用

java -Djava.security.manager -Djava.security.policy=/some/path/myplicy.policy MyClass
使用下面的链接以获取如何使用安全策略权限的完整示例


我终于解决了我的问题,据说

从J2SE5.0版本开始,远程对象的存根类不再存在 需要使用rmic存根编译器预生成,除非 远程对象需要支持在5.0以前的虚拟机中运行的客户端

在使用Java6时,我决定简单地删除
pom.xml
文件中的
rmic
任务。。。成功了


可能服务器(我的引擎)中存在
存根
,这会给JVM带来一些混乱,从而产生我得到的错误…

我最终解决了我的问题,据说

从J2SE5.0版本开始,远程对象的存根类不再存在 需要使用rmic存根编译器预生成,除非 远程对象需要支持在5.0以前的虚拟机中运行的客户端

在使用Java6时,我决定简单地删除
pom.xml
文件中的
rmic
任务。。。成功了


可能服务器(我的引擎)中存在的
存根
会给JVM带来一些混乱,这会产生我得到的错误…

可能重复的问题似乎是同一个问题,但在另一个问题中,没有接受答案,用户表示这只是一个配置问题…这正是问题所在,配置问题。名为的类在客户端不可用。它必须在那里,以便客户可以使用它。这就是它的目的。除非您使用的是动态存根,否则您不会收到该错误消息。可能重复的问题似乎是同一个问题,但在另一个问题中,没有接受任何答案,并且用户表示这只是一个配置问题……这正是配置问题。名为的类在客户端不可用。它必须在那里,以便客户可以使用它。这就是它的目的。除非您正在使用动态存根,否则您不会收到错误消息。好的,谢谢。我会查一查。我是否还需要在代码中添加
System.setSecurityManager(新的RMISecurityManager())行?-1。除非他也开始使用代码库特性,否则这一切都不会有任何区别。没有回答。好的,谢谢。我会查一查。我是否还需要在代码中添加
System.setSecurityManager(新的RMISecurityManager())行?-1。除非他也开始使用代码库特性,否则这一切都不会有任何区别。没有答案。