Building a Java RMI system.

Yeah, this is old technology from the stone age. But I wanted to set up a simple Java RMI system.

And it turns out every tutorial I encountered starts with:

        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }

Then there is a ton of pages showing how we then customize the security manager settings through all sorts of security property files, or extending the SecurityManager class to give us explicit permissions or all of that stuff.

Of course all of this is nice. However, for just testing something it’s unnecessary: the SecurityManager (once set) prohibits access to various things in the JVM unless explicitly opened–and the suggestion to then grant all permissions just seems silly to me: I’m locking the door, then I’m holding it wide open.

Just don’t lock the damned door.

The following seems to work for me; YMMV.

TestInterface.java

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface TestInterface extends Remote
{
    String sayHello() throws RemoteException;
}

TestServer.java

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import com.atti.addel.test.springrpc.common.TestInterface;

public class TestServer implements TestInterface
{
    protected TestServer() throws RemoteException
    {
        super();
    }

    private static final long serialVersionUID = 1L;

    public String sayHello() throws RemoteException
    {
        return "Hello World.";
    }
    
    /**
     * Run this as an RMI object
     * @param args
     */
    public static void main(String[] args) 
    {
//        if (System.getSecurityManager() == null) {
//            System.setSecurityManager(new SecurityManager());
//        }
        
        try {
            LocateRegistry.createRegistry(1099);
        }
        catch (RemoteException e) {
            System.out.println("Registry exists.");
        }
        
        try {
            TestInterface engine = new TestServer();
            TestInterface stub = (TestInterface)UnicastRemoteObject.exportObject(engine,0);
            
            Registry registry = LocateRegistry.getRegistry();
            registry.rebind("TestServer",stub);
        }
        catch (Exception ex) {
            System.out.println("Unable to start up.");
            ex.printStackTrace();
        }
    }
}

TestClient.java

import java.rmi.Naming;

import com.atti.addel.test.springrpc.common.TestInterface;

public class TestClient
{
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        try {
            TestInterface test = (TestInterface)Naming.lookup("rmi://localhost/TestServer");
            System.out.println(test.sayHello());
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

Once you run the server, a service “TestServer” is created in the local RMI registry. The client will then invoke the server ‘sayHello’ method, and return the answer.

Naturally more complex examples and interfaces and stuff can be bolted onto this. But this seems to be the very bare bones system–and it avoids stuff like rmic and security permissions and stuff like that.

I ran this on my Macintosh (System 10.5) running JVM 1.6 in Eclipse 3.5 without any problems, outside of wasting an hour trying to figure out why I was getting an “java.security.AccessControlException” exception–which could directly be traced to setting up a security manager.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s