Remote RMI Registry
Asked Answered
L

4

6

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??

Lection answered 18/1, 2012 at 0:13 Comment(1)
Can you post a code example? I think the language of your question might be a bit confusingBedel
B
1

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.

Bedel answered 29/1, 2012 at 20:57 Comment(1)
Wrong. You can only bind/rebind/unbind from the same host the Registry is running in.Hopefully
C
3

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.

Clinch answered 18/1, 2012 at 0:13 Comment(7)
@exabrial: Could you point out where in the question it says that?Clinch
@exabrial What are you talking about? The JVM does not 'bypass the TCP/IP stack for local registries'.Hopefully
Relying on SSH to fix a programming problem isn't a good solution. First, you lose Java portability among platforms, (windows doesn't have native ssh, and you your environment may not have port forward enabled). Second, your JVM can indeed bypass your operating system if it knows that the registry is in the same JVM. This isn't true in all cases, but it is true in some cases, and I asked the original poster for more info.Bedel
@exabrial: I don't see why this is specifically a programming problem. It's really more of a deployment or configuration problem. There are programming solutions; there are also networking solutions. It would indeed risk nonportability, but that is often not a concern. Still, i do recognise that my solution is a workaround, and an inelegant one - that's why i describe it as a hack!Clinch
@Tom, then why did you vote me down and provide a hack, if your answer was no better? That is kinda irritating.Bedel
@exabrial: Because your answer does not solve the problem. The problem is to get some objects on one machine into an RMI registry on another. The approach given in your answer does not do that.Clinch
@exabrial "Second, your JVM can indeed bypass your operating system if it knows that the registry is in the same JVM." This is correct if and only if you call bind/rebind/unbind on the Registry object returned by LocatRegistry.createRegistry(), but I fail to see the relevance.Hopefully
H
2

Use an LDAP server instead of the RMI Registry.

Hopefully answered 6/2, 2012 at 9:27 Comment(1)
@MarcosRoriz Certainly. There are lots of LDAP tutorials on the Web. You need to acquire and install and run an LDAP server and you need to use JNDI to talk to it, instead of the java.rmi.Naming or java.rmi.registry.Registry classes.Hopefully
B
1

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.

Bedel answered 29/1, 2012 at 20:57 Comment(1)
Wrong. You can only bind/rebind/unbind from the same host the Registry is running in.Hopefully
B
-2

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".

Bedel answered 23/1, 2012 at 21:42 Comment(2)
Thanks for the reply, but it's not what I'm looking for. I'm looking for a way to solve this using the rmi interface.Lection
Tom: actually my answer is about RMI. I demonstrated an alternative that would remove him situation he is in, which effectively would solve his dilemma.Bedel

© 2022 - 2024 — McMap. All rights reserved.