首页 > 解决方案 > Java RMI:未找到远程接口,抛出 java.lang.ClassNotFoundException,仅在全新启动后有效

问题描述

在 Java RMI 程序期间,似乎缺少远程接口 (CalcInterface.java)。
所有的 java 文件都在项目的 src 文件夹中(我使用的是 IDEA)。没有 gradle,什么都没有。
有:

他们都编译了项目的out/production/RMI目录。
RMI 是项目的名称。

IDEA 没有给出编译错误。
但是,在运行 Server.main()
时出现以下异常:

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

它在新启动时工作,但在我 ctrl+C 服务器程序并重新运行它之后。它再也不会起作用了。是的,我正在释放端口并重新启动 rmiregistry。
我不明白为什么它不能访问 CalcInterface。

我还尝试通过在 src 文件夹中使用 javac 然后运行来编译所有这些 java 文件,java Server但这会产生相同的错误。

在这里转储四个java文件因为我不知道如何指定问题。
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();
        }
    }
}

没有附上Client.java,因为我认为它与这个问题没有任何关系。
非常感谢有关该问题或一般有关 RMI 或 Java 的任何建议。
谢谢你!

标签: javaclient-serverrmi

解决方案


使用java.rmi.server.codebase财产。这充当源,从中将类加载到虚拟机中。

你可以从这里参考它。


推荐阅读