3
votes

I tried a simple java rmi program where the client makes a remote call to a server and the server returns a String. it worked perfectly with two computers connected via lan. how can i implement a remote call by a client which is not connected to the server via lan but the server and client are both connected to the internet? I tried the following simple code by changing 'localhost' in Client.java to server's ip address. Didn't Work. what do i need to make such a remote call?

//Remote Interface -> MyInterface.java

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

public interface MyInterface extends Remote
{
    public String SaySomething() throws RemoteException;
}

//Client.java

import java.rmi.*;
import java.rmi.registry.*;

public class Client
{
    public static void main(String []args)
    {
        System.setProperty( "java.security.policy", "client.policy" );
        if (System.getSecurityManager() == null)
                    System.setSecurityManager(new RMISecurityManager());
        try {
                        String name = "MyInterface";
                        Registry registry = LocateRegistry.getRegistry("localhost",4501);
                        MyInterface mi = (MyInterface) registry.lookup(name);
            System.out.println(mi.SaySomething());
                } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

//Server.java

import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.UnicastRemoteObject;

public class Server implements MyInterface
{
    public Server()
    {
        super();
    }
    public String SaySomething()
    {
        return "Server Speaking";
    }
    public static void main(String []args)
    {
        System.setProperty( "java.security.policy", "server.policy" );
        if(System.getSecurityManager() == null)
           System.setSecurityManager(new RMISecurityManager());
            try {
                        String name = "MyInterface";
                        MyInterface mi = new Server();
                        MyInterface stub =(MyInterface) UnicastRemoteObject.exportObject(mi,4501);
                        Registry registry = LocateRegistry.createRegistry(4501);
                        registry.rebind(name, stub);
                        System.out.println("Server bound");
            } catch (Exception e) {
            System.out.println("oops");
                }
    }
}

I get the following exception: java.security.AccessControlException: access denied ("java.net.SocketPermission" "x.x.x.x:4501" "connect,resolve") at java.security.AccessControlContext.checkPermission(AccessControlContext.java:366) at java.security.AccessController.checkPermission(AccessController.java:555) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at java.lang.SecurityManager.checkConnect(SecurityManager.java:1051) at java.net.Socket.connect(Socket.java:574) at java.net.Socket.connect(Socket.java:528) at java.net.Socket.(Socket.java:425) at java.net.Socket.(Socket.java:208) at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40) at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:146) at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613) at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216) at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202) at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:340) at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) at Client.main(Client.java:14)

2
It would help if you provided more details about how it failed... "didn't work" is a bit too vague. Also, what have you tried to solve or investigate the problem? - cjstehno
I would add that RMI is not a secure protocol. So please don't go around sending credit card details :). - Augusto
Sorry, I am a little rusty with port numbers but isn't 4501 too low for general over-the-internet use, I thought that ports below a certain number were reserved. Maybe try a higher port like 10101 or something. - cjstehno
Which is the content of client.policy file? - fglez
grant { permission java.security.AllPermission; }; Both for client and server - user1717415

2 Answers

0
votes

Unless you're using the codebase feature you don't need the security manager for RMI. Remove it.

-1
votes

You should probably check your access.

If your server is your home PC, you should check to make sure that your router allows incoming connections (it is blocked by default).

If your server is an office PC, then it may be blocked by a firewall.