I'm building a RMI application and I have the following server class. However, when I run it in eclipse I get the following exception. What is wrong and how can I fix it? I've spent the last 2 days reading about similar problems online but I couldn't find the solution. I suspect it has something to do with a policy file, but I have no idea how to use one. Also if the problem is with the way I run it can you please give me directions for doing so in eclipse.
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;
public class MyServer extends UnicastRemoteObject implements Interface {
private static final int PORT = 2019;
public MyServer() throws Exception {
super(PORT, new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
}
public static void main(String args[]) {
if (System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
Registry registry = LocateRegistry.createRegistry(PORT, new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory());
MyServer obj = new MyServer();
registry.bind("HelloServer", obj);
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
@Override
public void sayHello() throws RemoteException {
System.out.println("Hello");
}
}
--
access denied ("java.net.SocketPermission" "localhost:2019" "listen,resolve")
java.security.AccessControlException: access denied ("java.net.SocketPermission" "localhost:2019" "listen,resolve")
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkListen(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at javax.rmi.ssl.SslRMIServerSocketFactory$1.<init>(Unknown Source)
at javax.rmi.ssl.SslRMIServerSocketFactory.createServerSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPEndpoint.newServerSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.listen(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.exportObject(Unknown Source)
at sun.rmi.transport.tcp.TCPEndpoint.exportObject(Unknown Source)
at sun.rmi.transport.LiveRef.exportObject(Unknown Source)
at sun.rmi.server.UnicastServerRef.exportObject(Unknown Source)
at sun.rmi.registry.RegistryImpl.setup(Unknown Source)
at sun.rmi.registry.RegistryImpl.<init>(Unknown Source)
at sun.rmi.registry.RegistryImpl.<init>(Unknown Source)
at java.rmi.registry.LocateRegistry.createRegistry(Unknown Source)
at MyServer.main(MyServer.java:27)
It's very simple.
access denied ("java.net.SocketPermission" "localhost:2019" "listen,resolve")
means that the policy file has to grant the permission
java.net.SocketPermission "localhost:2019", "listen,resolve"
or whatever the correct syntax is. Use the policytool
to get it right. You may want to wildcard the port number. And you have to specify the location of the policy file via the java.security.policy
system property. And when you get other access control exceptions, as you will in testing, you have to likewise add the corresponding permissions, until closure.
But I would rather ask why you're using a security manager at all. It isn't necessary unless you're going to use the codebase feature, which is fairly rare, and it isn't necessary in a server unless you're going to use the codebase feature to upload classes from the client, which is much rarer.