首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在与RMIRegistry不同的主机上运行RMIServers

在与RMIRegistry不同的主机上运行RMIServers
EN

Stack Overflow用户
提问于 2010-10-28 01:28:50
回答 3查看 5.3K关注 0票数 1

这个是可能的吗?(假设Java 6)

为了说明我的观点,一个人为的/简单化的例子是:

  • I有一个定义良好的RMI接口,它永远不会更改(一个JAR文件,没有模板参数),它是运行在主机X上的RMIRegistry;
  • RMI服务,其中registry.rebind()从主机Y到它(RMIRegistry在主机X上);
  • RMI客户端,执行来自主机Z

的RMI调用。

如果可能的话,如何在服务(主机Y上的进程)上指定属性"java.rmi.server.codebase“?

如果主机A和B是同一台机器,那么当“"file:///C:/rmiCodebase/myCommonInterface.jar”“为时,此配置工作为

如果主机A和B位于单独的机器上,则在重新绑定上得到以下异常(主机Y上设置相同的"java.rmi.server.codebase“):

代码语言:javascript
复制
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
java.lang.ClassNotFoundException: 

如果主机A和B位于单独的机器上,并且通过web服务器(其中"java.rmi.server.codebase“为"http://Y/rmiCodebase/myCommonInterface.jarhttp://Z/rmiCodebase/myCommonInterface.jar"”)提供接口JAR,则在重新绑定时会出现以下稍有不同的错误:

代码语言:javascript
复制
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
java.rmi.AccessException: Registry.Registry.rebind disallowed; origin /10.0.190.25 (host Y) is non-local host

我有点困惑--如果所有的RMI服务都必须运行在与RMIRegistry相同的物理主机上(这是我成功工作的唯一东西),这似乎是非常有限的。

到头来,我只希望机器Z能够对运行在机器Y上的服务进行RMI调用。我正在为运行在机器Y和Z上的进程提供myCommonInterface.jar。我甚至不希望机器X对公共(远程)接口做任何事情!

虽然下面的链接很有用,但它不能帮助我回答这个问题:http://download.oracle.com/javase/1.4.2/docs/guide/rmi/codebase.html

EN

回答 3

Stack Overflow用户

发布于 2010-10-28 06:21:50

,这有可能吗?

不不可能。参见Registry.bind()、/rebind()、/unbind()和Naming.bind()/rebind()/unbind()的Javadoc。

但是,您可以使用LDAP服务而不是RMI注册表。

i只希望机器Z能够对运行在机器Y上的服务进行RMI调用

那为什么要问这个问题?机器Z在Y机器上查找注册表有什么问题?

票数 0
EN

Stack Overflow用户

发布于 2010-10-28 10:48:05

这并不是一个具体的答案,而是暗示了这一限制:

http://download.oracle.com/javase/6/docs/api/java/rmi/registry/Registry.html

注册表实现可能选择限制对其部分或全部方法的访问(例如,更改注册表绑定的方法可能仅限于来自本地主机的调用)。如果Registry选择拒绝对给定调用的访问,它的实现可能会抛出AccessException (因为它扩展了RemoteException),当被远程客户端捕获时,它将被包装在ServerException中。

票数 0
EN

Stack Overflow用户

发布于 2013-05-03 01:27:46

我的用例非常简单(基本上,使用RMI作为命令分布式系统的一种方式),但我能够避免将注册表一起使用。

这里有一个解决方案,我最后使用了一个Map-。

在此之前:

代码语言:javascript
复制
In client:    
    remoteMaster = (Master) remoteRegistry.lookup("master");
    // Add self to remote registry (BAD!)
    Worker stub = (Worker) UnicastRemoteObject.exportObject(this, 15213);
    remoteMaster.bind("workerName", stub);

之后:

(在这个解决方法中,我们将手动保存RemoteObject,而不是使用注册表)

代码语言:javascript
复制
In Master:
     List<Worker> workers = new List<Worker>();

     public void registerWorker(String name, Worker stub) throws RemoteException {
          worker.add(stub);
      }

一旦保存了远程实例,就可以传递它,并像任何其他对象一样调用它。

注意,只有当您只将注册表用作临时存储位置(我曾经使用过)时,此方法才会有用,因为您只是通过不将其添加到注册表并将其保持在本地,从而避免了“访问限制”。

只是记录一下我的解决方案(有点烦人),欢迎评论。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4039031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档