Reputation: 4106
I'm coding an application that requires remote binding, i.e., bind a remote object to a remote registry. By default, Java RMI Registry only binds locally, only remote objects that are binded in the same JVM/host.
I've seen some solutions that bypass this making a remote interface that will take a remote object and then bind locally (SO link of this disucssion). Isn't there a more elegant way to solve this? Maybe I should try to use JNDI with other provider??
Upvotes: 6
Views: 5590
Reputation: 8807
I did some more research on this... First, if you have the same codebase on both servers, it should be as simple as this:
...
Registry registry = LocateRegistry.getRegistry("192.168.1.1", 1100);
registry.rebind("Hello, World!", myObj);
But you can run into problems quickly if you need to load classes to the remote registry... you'll need a security manager: http://www.devx.com/getHelpOn/10MinuteSolution/20444
I was still hoping you could post a code example or give us more information about your situation.
Upvotes: 1
Reputation: 47163
This is a hack, but you could try setting up a port forwarding on the server, so the registry's server port is exposed in such a way that all requests coming through it look like they're local.
This is fairly easy to do with SSH. On the server, run:
ssh localhost -N -L 1199:localhost:1099 -g
That won't run a command (-N
), but will open a listening socket on port 1199 on the local machine which is forwarded to port 1099 on localhost (-L 1199:localhost:1099
) and which is accessible to connections from any source (-g
). Connections made through this tunnel will appear to the server on port 1099 to have come from localhost. Note that you can also add -f
to have SSH go into the background after setting up the tunnel, in which case i would suggest also adding '-o ExitOnForwardFailure' to improve the error handling.
It should also be possible to do this using netcat rather than SSH, which will be simpler and more efficient, but i don't have a suitable version of netcat installed. It is also possible to do it with socat, if you have that installed:
socat TCP-LISTEN:1199,fork TCP:localhost:1099
Now, i don't know that any of these options will be sufficient. That will open up network-level access, but it's possible that the rmiregistry server will still refuse to register remote objects. I doubt that, though.
Upvotes: 3
Reputation: 8807
I've done this, but I used a much different approach. I wrote plain POJOs and Plain Java Interfaces without messing around with the strange abstract classes, remote stub compilers, or a plethora of checked exceptions associated with the Java RMI API. Then I used Spring Remoting to connect everything and Spring took care of the RMI transport:
Take a look at the manual here: http://static.springsource.org/spring/docs/2.0.x/reference/remoting.html
Here's an example of a bean that will proxy out to a remote registry:
<bean id="accountService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl" value="rmi://HOST:1199/AccountService"/>
<property name="serviceInterface" value="example.AccountService"/>
</bean>
This solves your problem, but probably doesn't answer your question exactly... the old RMI API from Java is quite antiquated though, Spring lets you work with "just plain java".
Upvotes: -2