Marcos Roriz Junior
Marcos Roriz Junior

Reputation: 4106

Remote RMI Registry

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

Answers (4)

user207421
user207421

Reputation: 310850

Use an LDAP server instead of the RMI Registry.

Upvotes: 2

Jonathan S. Fisher
Jonathan S. Fisher

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

Tom Anderson
Tom Anderson

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

Jonathan S. Fisher
Jonathan S. Fisher

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

Related Questions