运行 RMI 服务器,编组参数出错,class 未找到

Running RMI Server, got errors with marshalling arguments and class not found

我正在关注展示如何创建 RMI 项目的教程。

但是当我运行服务器站点时,它有错误。当我 运行: rmic CalculatorImpl 时,它只是创建存根,我没有看到 ske。

这是我 运行 rmic CalculatorImpl:

时的日志
Warning: generation and use of skeletons and static stubs for JRMP is deprecated. Skeletons are unnecessary, and static stubs have been superseded by dynamically generated stubs. Users are encouraged to migrate away from using rmic to generate skeletons and static stubs. See the documentation for java.rmi.server.UnicastRemoteObject.

当我 运行 CalculatorServer:

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

这是我的代码:

文件计算器服务器:

public class CalculatorServer {
public CalculatorServer() {
    try {
        Calculator c = new CalculatorImpl();
        Naming.bind("rmi://localhost:1099/CalculatorService", c);
    } catch (Exception e) {
        System.out.println("Trouble: " + e);
    }
}

public static void main(String args[]) {
    new CalculatorServer();
}
}

文件计算器:

public interface Calculator extends Remote {
public long add(long a, long b)
        throws java.rmi.RemoteException;
}

和文件 CalculatorImpl:

public class CalculatorImpl extends
    java.rmi.server.UnicastRemoteObject implements Calculator {
public CalculatorImpl()
        throws java.rmi.RemoteException {
    super();
}

public long add(long a, long b)
        throws java.rmi.RemoteException {
    return a + b;
}
}

以及另一个项目中的CalculatorClient:

public class CalculatorClient {

public static void main(String[] args) {
    try {
        Calculator c = (Calculator)
                Naming.lookup(
                        "rmi://localhost/CalculatorService");
        System.out.println( c.add(4, 5) );

    }
    catch (MalformedURLException murle) {
        System.out.println();

        System.out.println(
                "MalformedURLException");
        System.out.println(murle);
    }
    catch (RemoteException re) {
        System.out.println();
        System.out.println(
                "RemoteException");
        System.out.println(re);
    }
    catch (NotBoundException nbe) {
        System.out.println();
        System.out.println(
                "NotBoundException");
        System.out.println(nbe);
    }
    catch (
            java.lang.ArithmeticException
                    ae) {
        System.out.println();
        System.out.println(
                "java.lang.ArithmeticException");
        System.out.println(ae);
    }
}
}

所以请大家帮助me.Tks!

总结评论链。

重要的是注册表应该知道服务器存根。为了实现这一点,有两种选择。选项一是注册表和服务器共享同一个虚拟机。这可以通过

来实现

添加LocateRegistry.createRegistry() 在主服务器开始 class.

选项二是

两个配置服务器使用存根文件的自动下载这可以通过java.rmi.server.codebase

实现

示例命令

java -cp c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar
     -Djava.rmi.server.codebase=file:/c:/home/ann/public_html/classes/compute.jar
     -Djava.rmi.server.hostname=mycomputer.example.com
     -Djava.security.policy=server.policy
        engine.ComputeEngine

这取自https://docs.oracle.com/javase/tutorial/rmi/running.html

注册表的 CLASSPATH 上没有存根。解决这个问题的简单方法是通过 LocateRegistry.createRegistry().

在服务器 JVM 中启动注册表

然后您可能会发现在客户端 CLASSPATH 中也没有它。