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 ?
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