Question

I am learning Java RMI and I have created a very simple server that calculates Fibonacci numbers. The server (FibonacciServer) creates an object responsible for calculating the sequence (Fibonacci) and that object implements an interface (IFibonacci):

FibonacciServer.java:

package myrmifibonacciserver;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;

public class FibonacciServer {
    public static void main(String args[]){
        try{
            Fibonacci fib = new Fibonacci();
            Naming.rebind("fibonacci", fib);
            System.out.println("Fibonacci Server ready.");
        }catch(RemoteException rex){
            System.err.println("Exception in Fibonacci.main " + rex);
        } catch (MalformedURLException ex) {
            System.err.println("MalformedURLException " + ex);
        }
    }
}

Fibonacci:

package myrmifibonacciserver;

import java.math.BigInteger;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Fibonacci extends UnicastRemoteObject implements IFibonacci{

    private static final long serialVersionUID = -4300545841720809981L;

    public Fibonacci() throws RemoteException{
        super();
    }

    @Override
    public BigInteger getFibonacci(int n) throws RemoteException {
        return getFibonacci(new BigInteger(Long.toString(n)));
    }

    @Override
    public BigInteger getFibonacci(BigInteger n) throws RemoteException {
        System.out.println("Calculating teh " + n + "th Fibonacci number");
        BigInteger zero = BigInteger.ZERO;
        BigInteger one = BigInteger.ONE;

        if(n.equals(zero) || n.equals(one)) 
            return one;

        BigInteger current = one;
        BigInteger low = one;
        BigInteger high = one;
        BigInteger temp;

        while(current.compareTo(n) == -1){
            temp = high;
            high = high.add(low);
            low = temp;
            current = current.add(one);
        }
        return high;
    }

}

IFibonacci:

package myrmifibonacciserver;

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;
}

As you can see, this is quite a basic example. I am launching the RMI registry on linux by using the command rmiregistry & and it starts without problems.

However, when I click the run button (in Eclipse or Netbeans) to run my little project, I get an error:

Exception in Fibonacci.main java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: myrmifibonacciserver.IFibonacci

And I have no idea why! At first I thought it was because of the stubs, but since I am using java 1.7, those are created automatically. What am I doing wrong ?

Était-ce utile?

La solution

It's not finding the codebase. The reason is that, as of JDK 7, the java.rmi.server.useCodebaseOnly property is true by default, whereas in prior releases it was false by default.

When property is false then it uses the code base of sever but in true case it ignores it.

http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/enhancements-7.html

Your problem would resolve in lower JDK. ex JDK6

Autres conseils

The Registry doesn't have the named class available on its CLASSPATH and/or you haven't set up the codebase correctly, if at all. You don't have to use the codebase feature, but if you do it has to be correct. An easier way out of this may be to start the Registry in the server JVM, via LocateRegistry.createRegistry().

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top