views:

18

answers:

2

Hello,

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

A: 

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?

EJP
Essentially I wanted all systems to be running on a single "IT controlled" machine (2 RMI Clients, RMI Registry, 1 of 2 RMI Services). Due to various constraints, there was going to be only a single RMI Service running on a separate "non-IT controlled" machine. ... This is a pity - it seems like quite a significant deficiency of RMI - it allows all kind of remoting to be available, yet constrains the registry to "not be remote", so to speak! Thanks for the info now - at least I will give up banging my head against the wall with this one!
Ben
A: 

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.

Ben