简体   繁体   中英

RMI client cannot lookup server - java.rmi.UnmarshalException

I have a java rmi server and a java rmi client in two separate and different machines .

The server is basically a fibonacy calculator. It receives a bunch of numbers and calculates a Fibonacci sequence based on them.

The client simply sends a bunch of numbers for the server to calculate.

The FiboServer project consists of three classes:

  • IFibonacci.java: an interface
  • Fibonacci.java: implements the previously defined interface
  • FibonacciServer.java: Has the main, and runs the server

FibonacciServer.java:

package fiboserver;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class FibonacciServer {
    public static void main(String args[]){

        if (System.getSecurityManager() == null) {
            System.setProperty("java.security.policy", "server.policy");
            System.setSecurityManager(new SecurityManager());
        }

        try{
            IFibonacci fib = new Fibonacci();

            // Bind the remote object's stub in the registry
            Registry registry = LocateRegistry.createRegistry(1099);
            registry.rebind("fibonacci", fib);

            System.out.println("Fibonacci Server ready.");
        }catch(RemoteException rex){
            System.err.println("Exception in Fibonacci.main " + rex);
        }
    }
}

The client project merely has one class: FibonacciClient.java.

FibonacciClient.java:

package fiboclient;

import fiboserver.IFibonacci;
import java.math.BigInteger;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class FibonacciClient {

    public static void main(String[] args) {

        if (System.getSecurityManager() == null) {
            System.setProperty("java.security.policy", "client.policy");
            System.setSecurityManager(new SecurityManager());
        }

        try{
            //args[0] = server Public IP
            Registry registry = LocateRegistry.getRegistry(args[0]);
            IFibonacci calculator = (IFibonacci) registry.lookup("fibonacci");

            //the rest of the args are just numbers to calculate
            for(int i = 1; i < args.length; i++){
                try{
                    BigInteger index = new BigInteger(args[i]);
                    BigInteger f = calculator.getFibonacci(index);

                    System.out.println("The " + args[i] + "th Fibonacci number "
                            + "is " + f);
                }catch(NumberFormatException e){
                    System.err.println(args[i] + " is not an integer.");
                }
            }
        }catch(RemoteException e){
            System.err.println("Remote object threw exception " + e);
        } catch (NotBoundException e) {
            System.err.println("Could not find the requested remote object on "
                    + "the server: " + e);
        }
    }

}

Both projects have a policy file, the server has a server.policy and the client has a client.policy file. Both files have the same content:

grant{
    permission java.security.AllPermission;
};

I am launching the FiboServer in the server machine using java -jar FiboServer.jar -Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=12.34.56.789

I am launching the client by using java -jar FiboClient.jar 12.34.56.789 1 2 3 4 5 .

The server launches without a problem. But when I launch the client I get the error:

Remote object threw exception java.rmi.UnmarshalException: error unmarshalling return; nested exception is: 
    java.lang.ClassNotFoundException: fiboserver.IFibonacci

Searches on StackOverflow convinced me that this has to do with RMI registry errors or policy file errors. However I know the the policy files are being read correctly and I do not think they have any errors.

What am I doing wrong? Why is this not working?


EDIT:

IFibonacci.java:

package fiboserver;

import java.math.BigInteger;
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IFibonacci extends Remote{
    public BigInteger getFibonacci(int n) throws RemoteException;
    public BigInteger getFibonacci(BigInteger n) throws RemoteException;
}

JAR Files:

Contents of FibonacciClient.jar:

|META-INF
|----Manifest.mf
|fiboclient
|----FibonacciClient.class

Contents of FibonacciServer.jar:

|META-INF
|----manifest.mf
|fiboserver
|----IFibonacci.class
|----FibonacciServer.class
|----Fibonacci.class

The client doesn't have the class named in the exception available on its classpath. You need to deploy it, and any class it depends in, and so on recursively until closure.

Possibly you've renamed/copied the remote interface into another package for the client. You can't do that. It has to be the same at server and client. Same name, same methods, same package.

NB The message in your client 'remote object threw exception' isn't correct. It could be the lookup() throwing the exception. Don't confuse yourself by assuming things that may not be so. Just print the actual error message, exception, and stack trace.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM