0

During a Java RMI program, the Remote Interface(CalcInterface.java) seems to be missing.
All the java files are in the project's src folder(I'm using IDEA). No gradle, maven nothing.
There are:

  • CalcClass.java
  • CalcInterface.java
  • Client.java
  • Server.java

They're all compiled the project's out/production/RMI directory.
RMI is the name of the project.

IDEA gives no compilation error.
But, on running Server.main()
I get the following exception:

Server Exception:java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: CalcInterface
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: CalcInterface
...

It works when it's a fresh boot, but after I ctrl+C the Server program and re-run it. It never works again. And Yes, I am freeing up the ports and also restarting rmiregistry.
I don't understand why it can't access CalcInterface.

I have also tried compiling all those java files by using javac in the src folder and then running java Server but that gives the same error.

Dumping the four java files here cuz I don't know how else to specify the problem.
CalcInterface.java

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface CalcInterface extends Remote {
    int add(int a, int b) throws RemoteException;
    int subtract(int a, int b) throws RemoteException;
    int multiply(int a, int b) throws RemoteException;
    double divide(int a,int b) throws RemoteException, ArithmeticException;
}

CalcClass.java

import java.rmi.RemoteException;

public class CalcClass implements CalcInterface{

    @Override
    public int add(int a, int b) throws RemoteException {
        return a+b;
    }

    @Override
    public int subtract(int a, int b) throws RemoteException {
        return a-b;
    }

    @Override
    public int multiply(int a, int b) throws RemoteException {
        return a*b;
    }

    @Override
    public double divide(int a, int b) throws RemoteException, ArithmeticException {
        return (double)a/b;
    }
}

Server.java

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class Server {
    public static void main(String[] args) {
        try {
//            Instantiating implementation class
            CalcClass obj = new CalcClass();

//            Exporting object of implementation class to stub
            CalcInterface stub = (CalcInterface) UnicastRemoteObject.exportObject(obj,5000);

//            Binding stub to registry
            Registry registry = LocateRegistry.getRegistry();

            registry.bind("Calculator", stub);
            System.out.println("Server Ready");
        }
        catch (Exception e){
            System.err.println("Server Exception:" + e.toString());
            e.printStackTrace();
        }
    }
}

Not enclosing Client.java as I don't think it has anything to do with the issue.
Any advice of on the problem or generally regarding RMI or Java is greatly appreciated.
Thank You!

Varun Gawande
  • 870
  • 9
  • 21
  • I managed to fix the issue. Turns out, I have to start ```rmiregistry &``` in the same folder as that of my .class files. I was starting it elsewhere, hence it was unable to find the other classes. I am unable to mark this question as solved, it'd be appreciated if a mod or admin could do it and mark this comment as the answer. – Varun Gawande Mar 08 '21 at 07:23

1 Answers1

-1

Use java.rmi.server.codebase property. This act as a source, from which to load classes into a virtual machine.

You can refer it from here.

Frightera
  • 4,773
  • 2
  • 13
  • 28