这个是可能的吗?(假设Java 6)
为了说明我的观点,一个人为的/简单化的例子是:
的RMI调用。
如果可能的话,如何在服务(主机Y上的进程)上指定属性"java.rmi.server.codebase“?
如果主机A和B是同一台机器,那么当“"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服务器(其中"java.rmi.server.codebase“为"http://Y/rmiCodebase/myCommonInterface.jar”或“http://Z/rmiCodebase/myCommonInterface.jar"”)提供接口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能够对运行在机器Y上的服务进行RMI调用。我正在为运行在机器Y和Z上的进程提供myCommonInterface.jar。我甚至不希望机器X对公共(远程)接口做任何事情!
虽然下面的链接很有用,但它不能帮助我回答这个问题:http://download.oracle.com/javase/1.4.2/docs/guide/rmi/codebase.html
发布于 2010-10-28 06:21:50
,这有可能吗?
不不可能。参见Registry.bind()、/rebind()、/unbind()和Naming.bind()/rebind()/unbind()的Javadoc。
但是,您可以使用LDAP服务而不是RMI注册表。
i只希望机器Z能够对运行在机器Y上的服务进行RMI调用
那为什么要问这个问题?机器Z在Y机器上查找注册表有什么问题?
发布于 2010-10-28 10:48:05
这并不是一个具体的答案,而是暗示了这一限制:
http://download.oracle.com/javase/6/docs/api/java/rmi/registry/Registry.html
注册表实现可能选择限制对其部分或全部方法的访问(例如,更改注册表绑定的方法可能仅限于来自本地主机的调用)。如果Registry选择拒绝对给定调用的访问,它的实现可能会抛出AccessException (因为它扩展了RemoteException),当被远程客户端捕获时,它将被包装在ServerException中。
发布于 2013-05-03 01:27:46
我的用例非常简单(基本上,使用RMI作为命令分布式系统的一种方式),但我能够避免将注册表一起使用。
这里有一个解决方案,我最后使用了一个Map-。
在此之前:
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);
}一旦保存了远程实例,就可以传递它,并像任何其他对象一样调用它。
注意,只有当您只将注册表用作临时存储位置(我曾经使用过)时,此方法才会有用,因为您只是通过不将其添加到注册表并将其保持在本地,从而避免了“访问限制”。
只是记录一下我的解决方案(有点烦人),欢迎评论。
https://stackoverflow.com/questions/4039031
复制相似问题