在与 RMIServer 不同的主机上运行 RMIRegistry

发布于 2024-09-29 10:14:07 字数 1661 浏览 2 评论 0原文

这可能吗? (假设 Java 6)

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

  • 我有一个定义良好的 RMI 接口,它永远不会改变(单个 JAR 文件,没有模板参数)
  • 运行在主机 X 上的 RMIRegistry;
  • RMI 服务,它从主机 Y 对其进行registry.rebind()(主机 X 上的 RMIRegistry);以及
  • 从主机 Z 执行 RMI 调用的 RMI 客户端

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

如果主机 A 和 B 是同一台计算机,则当“java.rmi.server.codebase”为“file:///C:/rmiCodebase/myCommonInterface”时,此配置有效 .jar”

如果主机 A 和 B 位于不同的计算机上,则重新绑定时会出现以下异常(在主机 Y 上设置相同的“java.rmi.server.codebase”)

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 服务器提供接口 JAR(其中“java.rmi.server.codebase”是“http://Y/rmiCodebase/myCommonInterface”) .jar" OR "http://Z/rmiCodebase/myCommonInterface.jar"),然后我在重新绑定时遇到这个略有不同的错误:

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 能够对机器上运行的服务进行 RMI 调用Y. 我向机器 Y 和 Z 上运行的进程提供 myCommonInterface.jar。我什至不希望机器 X 必须对通用(远程)接口执行任何操作!

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

Is this possible? (Assuming Java 6)

A contrived/simplistic example to illustrate my point is:

  • I have a well-defined RMI interface that will never change (a single JAR file, no template parameters)
  • an RMIRegistry running on host X;
  • RMI Services which registry.rebind() to it (RMIRegistry on host X) from host Y; and
  • RMI clients which perform RMI calls from host Z

If it is possible, how would I specify the property "java.rmi.server.codebase" on the RMI Service (process on host Y)?

If host A and B are the same machine, then this configuration works when the "java.rmi.server.codebase" is "file:///C:/rmiCodebase/myCommonInterface.jar"

If host A and B are on separate machines, then I get the following exception on the rebind (with the same "java.rmi.server.codebase" set on host Y):

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
java.lang.ClassNotFoundException: 

If host A and B are on separate machines, and I make the interface JAR available through a web-server (where "java.rmi.server.codebase" is either "http://Y/rmiCodebase/myCommonInterface.jar" OR "http://Z/rmiCodebase/myCommonInterface.jar"), then I get this slightly different error on the rebind:

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

I am a little confused - it seems very constraining if all RMI Services must run on the same physical host as the RMIRegistry (which is the only thing I have succeeded in getting working)

At the end of the day, I only want machine Z to be able to make an RMI call to a service running on machine Y. I am providing myCommonInterface.jar to the processes running on both machine Y and Z. I don't even want machine X to have to do anything with the common (remote) interface!

Whilst the following link is useful, it doesn't help me answer this question: http://download.oracle.com/javase/1.4.2/docs/guide/rmi/codebase.html

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

瑾夏年华 2024-10-06 10:14:07

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

这是我最终用于 Map-Reduce-miniframework 的解决方法。

之前:

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,而不是使用注册表)

In Master:
     List<Worker> workers = new List<Worker>();

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

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

请注意,仅当您仅将注册表用作临时存储位置(我就是这样)时,此方法才有用,因为您只是通过不将其添加到注册表并将其保留在本地来避免“访问限制”。

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

My use-case was very simple (basically, using RMI as a way to command a distributed system), but I was able to avoid using the registry all together.

Here's a work-around to that I ended up using for a Map-Reduce-miniframework.

Before:

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

After:

(In this workaround, we will save the RemoteObject manually, not using a registry)

In Master:
     List<Worker> workers = new List<Worker>();

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

Once you save the remote instance, you can pass it around and call it like any other object.

Note this approach is useful only if you're only using the registry as a temporary storage place (which I was), since you're just avoiding the "access restriction" by not adding it to the registry, and keeping it local.

Just documenting my (slightly hacky) solution, comments welcome.

起风了 2024-10-06 10:14:07

这可能吗?

不,这是不可能的。请参阅Registry.bind()/rebind()/unbind() 和 Naming.bind()/rebind()/unbind() 的 Javadoc。

不过,您可以使用 LDAP 服务来代替 RMI 注册表。

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

那么为什么会出现这个问题呢?机器 Z 在机器 Y 上查找注册表时出现什么问题?

Is this possible?

No it is not possible. See the Javadoc for Registry.bind()/rebind()/unbind() and Naming.bind()/rebind()/unbind().

However you could use an LDAP service instead of the RMI Registry.

I only want machine Z to be able to
make an RMI call to a service running
on machine Y

So why the question? What's the problem with machine Z looking up a Registry at machine Y?

活泼老夫 2024-10-06 10:14:07

不完全是具体的答案,但暗示了限制:

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

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

Not exactly a concrete answer, but hints at the restriction:

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

A Registry implementation may choose to restrict access to some or all of its methods (for example, methods that mutate the registry's bindings may be restricted to calls originating from the local host). If a Registry method chooses to deny access for a given invocation, its implementation may throw AccessException, which (because it extends RemoteException) will be wrapped in a ServerException when caught by a remote client.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文