【问题标题】:Java RMI: Remote Interface not found, throwing java.lang.ClassNotFoundException, only works after Fresh Boot [duplicate]Java RMI:找不到远程接口,抛出java.lang.ClassNotFoundException,仅在Fresh Boot后有效[重复]
【发布时间】:2021-05-09 17:18:35
【问题描述】:

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

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

他们都编译了项目的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 的建议。
谢谢!

【问题讨论】:

  • 我设法解决了这个问题。事实证明,我必须在与我的 .class 文件相同的文件夹中启动 rmiregistry &。我在其他地方开始它,因此无法找到其他类。我无法将此问题标记为已解决,如果模组或管理员能够做到这一点并将此评论标记为答案,我们将不胜感激。

标签: java client-server rmi


【解决方案1】:

使用java.rmi.server.codebase 属性。 这充当了一个源,从中将类加载到虚拟机中。

你可以参考here

【讨论】:

  • 这还不够。您还需要运行 HTTP 服务器来为这些类提供服务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
  • 2019-03-04
  • 2011-09-25
  • 2016-09-24
  • 1970-01-01
相关资源
最近更新 更多