如何使用本地代码库启动RMI服务器

问题描述 投票:0回答:1

我正在尝试从here运行示例

我们有一个远程界面:

package example.hello;

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

public interface Hello extends Remote {
    String sayHello() throws RemoteException;
}

然后我们有一个服务器:

package example.hello;

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

public class Server implements Hello {

    public Server() {}

    public String sayHello() {
        return "Hello, world!";
    }

    public static void main(String args[]) {

      System.out.println("Server started");

        try {
            Server obj = new Server();
            Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);

            // Bind the remote object's stub in the registry
            Registry registry = LocateRegistry.getRegistry();
            registry.bind("Hello", stub);

            System.err.println("Server ready");
        } catch (Exception e) {
            System.err.println("Server exception: " + e.toString());
            e.printStackTrace();
        }
    }
}

然后我们有了一个客户,尽管这并不重要,因为它目前不是我要运行的内容。我按照链接中的所有说明进行操作,然后想到了这样的结构:

.
├── example
│   └── hello
│       ├── Client.java
│       ├── Hello.java
│       └── Server.java
└── target
    └── classes
        └── example
            └── hello
                ├── Client.class
                ├── Hello.class
                └── Server.class

[启动服务器之前,我从项目文件夹中运行rmiregistry。然后,要从项目文件夹运行我尝试过的服务器,请使用:

java -cp ./target/classes -Djava.rmi.server.codebase=file:///Users/myself/Desktop/rmi/target/classes/ example.hello.Server

我也尝试了file:/file://,但在所有情况下,它都给了我:

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: example.hello.Hello
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
    java.lang.ClassNotFoundException: example.hello.Hello
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:421)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:272)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:276)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:253)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:379)
    at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
    at example.hello.Server.main(Server.java:26)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
    java.lang.ClassNotFoundException: example.hello.Hello
    at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
    at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:411)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:272)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: example.hello.Hello
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.rmi.server.LoaderHandler$Loader.loadClass(LoaderHandler.java:1207)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at sun.rmi.server.LoaderHandler.loadClassForName(LoaderHandler.java:1221)
    at sun.rmi.server.LoaderHandler.loadProxyInterfaces(LoaderHandler.java:731)
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:674)
    at sun.rmi.server.LoaderHandler.loadProxyClass(LoaderHandler.java:611)
    at java.rmi.server.RMIClassLoader$2.loadProxyClass(RMIClassLoader.java:646)
    at java.rmi.server.RMIClassLoader.loadProxyClass(RMIClassLoader.java:311)
    at sun.rmi.server.MarshalInputStream.resolveProxyClass(MarshalInputStream.java:265)
    at java.io.ObjectInputStream.readProxyDesc(ObjectInputStream.java:1566)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
    ... 15 more

[从我得到的东西中,它找不到类,就像我输入了错误的路径。无论如何,如果我从rmiregistry开始target/classes,一切都会正常。

我的问题是,如何设置带有相对路径的java.rmi.server.codebase属性(包括格式),以便可以从不同于类所在的文件夹中运行rmiregistry

java rmi
1个回答
0
投票

rmiregistry也必须以useCodebaseOnly开头:

rmiregistry -J-Djava.rmi.server.useCodebaseOnly=false

(来自Java RMI and ClassNotFoundException

© www.soinside.com 2019 - 2024. All rights reserved.