Add new comment

Hi there,

First of all, be very careful disabling external firewalls (as tempting as it is) as this may leave you wide open for hacking!

I believe my instructions only work in specific configurations actually as far as I remember... Basically, it has something to do with your security manager for your Java VM. On the client side, I think it may be not allowing external connections. By default, I think it's trying to connect to a loopback address.

One workaround is to have a custom factory for your server and client sockets I believe.

Custom server-socket factory (automatically uses your local IP as specified in my guide and apologies for lack of indentation, the site CSS is a bit quirky with code...)

/** Factory for creating NotificationServerSockets
*
* @author Nicholas Hatter
*/
import java.io.IOException;
import java.net.ServerSocket;
import java.rmi.server.RMIServerSocketFactory;
public class NotificationServerSocketFactory implements RMIServerSocketFactory {
@Override
// Creates a server socket on local IP address on a given port number
public ServerSocket createServerSocket(int port) throws IOException {
return new ServerSocket(port);
}
@Override
public int hashCode() {
return externalIP.hashCode();
}
@Override
public boolean equals(Object obj) {
return (getClass() == obj.getClass() &&
externalIP.equals(((NotificationServerSocketFactory) obj).getExternalIP()));
}
}

Custom socket factory for client connecting to a remote IP:


/** Factory for creating NotificationClientSockets
*
* @author Nicholas Hatter
*/
import java.io.IOException;
import java.io.Serializable;
import java.net.Socket;
import java.rmi.server.RMIClientSocketFactory;
public class NotificationClientSocketFactory implements RMIClientSocketFactory, Serializable {
private final String externalIP;
public NotificationClientSocketFactory(String externalIP) {
this.externalIP = externalIP;
}
public String getExternalIP() {
return externalIP;
}
public Socket createSocket(String host, int port) throws IOException {
return new Socket(externalIP, port);
}
public int hashcode() {
return externalIP.hashCode();
}
@Override
public int hashCode() {
return externalIP.hashCode();
}
@Override
public boolean equals(Object obj) {
return (getClass() == obj.getClass() &&
externalIP.equals(((NotificationClientSocketFactory) obj).getExternalIP()));
}
}

Example call on server-side:

Registry rmiRegistry = LocateRegistry.getRegistry(Registry.REGISTRY_PORT);
stub = (YourObjectInterfaceForYourRemoteObject) UnicastRemoteObject.exportObject(this, port, new NotificationClientSocketFactory(externalIP), new NotificationServerSocketFactory());
rmiRegistry.rebind(name, stub);

Example call client-side:

UnicastRemoteObject.exportObject(this, port, new NotificationClientSocketFactory(externalIP), new NotificationServerSocketFactory());

So basically we create these socket factories to allow us to make external connections. We then have to instantiate these factories when we call .exportObject to let Java RMI that we're using our own custom socket factories.

Try something like this along these lines and don't hesitate to ask for more help :)

Regards,
Nick

CAPTCHA