简体   繁体   English

Java RMI-如何从客户端发送对象以进行回调

[英]Java RMI - how to send an object for callback from client

I am using RMI, I have Server Client program. 我正在使用RMI,我有Server Client程序。

Client accesses some methods from servers. 客户端从服务器访问某些方法。

However in one of the method I want to pass a client local object, using whose reference server will execute callback (which will inturn be executed on client), at least this is what I want, but may be I am doing it wrong. 但是,在一种方法中,我想传递一个客户端本地对象,使用该对象的引用服务器将执行回调(该回调将在客户端上执行),至少这是我想要的,但可能是我做错了。

at client 在客户处

---------------------------------------------------------------------------------
   server.setLock("/hello.txt", 99, 125,Locker.Lock_type.WRITE,"Shubham Verma",true, new CallBackProcess());
---------------------------------------------------------------------------------   

CallBackProcess implements an interface which is presented on both the ends. 

But I get this error    

Exception in thread "main" java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
    java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: scality.CallBackProcess (no security manager: RMI class loader disabled)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:353)
    at sun.rmi.transport.Transport$1.run(Transport.java:177)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:701)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
    at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:160)
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
    at com.sun.proxy.$Proxy1.setLock(Unknown Source)
    at scality.Client.main(Client.java:31)
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.lang.ClassNotFoundException: scality.CallBackProcess (no security manager: RMI class loader disabled)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:313)
    at sun.rmi.transport.Transport$1.run(Transport.java:177)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:701)
Caused by: java.lang.ClassNotFoundException: scality.CallBackProcess (no security manager: RMI class loader disabled)
    at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:393)
    at sun.rmi.server.LoaderHandler.loadClass(LoaderHandler.java:183)
    at java.rmi.server.RMIClassLoader$2.loadClass(RMIClassLoader.java:637)
    at java.rmi.server.RMIClassLoader.loadClass(RMIClassLoader.java:264)
    at sun.rmi.server.MarshalInputStream.resolveClass(MarshalInputStream.java:220)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1611)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1516)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1770)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1349)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:324)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:307)
    ... 9 more

public interface Callback extends Remote{
    void execute() throws RemoteException;
}


public class CallBackProcess implements Callback, Serializable{
    public static int test = 0;
    @Override
    public void execute() {
        // need to do something here
    }
}

Basically it's trying to tell you it has no access to the remote code. 基本上,它试图告诉您它无法访问远程代码。 It's trying to deserialize a class for which is does not have a definition. 它试图反序列化一个没有定义的类。 The classes are loaded from the "code base" by the client. 客户端从“代码库”中加载类。 They are not loaded by the client over the RMI connection, so they have no way to serialize this class which it knows nothing about. 它们不是由客户端通过RMI连接加载的,因此它们无法序列化对此一无所知的此类。

The server should specify the system property "java.rmi.server.codebase" when you start the JVM on the command line, or set it in code before trying to run your RMI client. 在命令行上启动JVM时,服务器应指定系统属性“ java.rmi.server.codebase”,或在尝试运行RMI客户端之前在代码中设置它。 The value must be a URL that is accessible to the client and it should point at the necessary classes to be loaded. 该值必须是客户端可访问的URL,并且应指向要加载的必要类。 Usually I specify a .jar file using the "file://" protocol handler. 通常,我使用“ file://”协议处理程序指定一个.jar文件。

The opposite is also true: If the client returns classes the server must deserialize, the server must set the code base property to a URL that is accessible to the server containing the returned classes. 反之亦然:如果客户端返回类,则服务器必须反序列化,服务器必须将代码库属性设置为包含返回的类的服务器可访问的URL。 It's usually best to have a .jar of your DAO objects and their interfaces which is shared by both client and server to avoid any confusion about which classes need to go where. 通常最好让您的DAO对象及其接口使用.jar,并由客户端和服务器共享,以免混淆哪些类需要存放在哪里。

You haven't exported the callback object, so it is being serialized instead of passed as a remote reference, and the peer doesn't have the implementation class so it gets this error. 您尚未导出回调对象,因此将其序列化而不是作为远程引用传递,并且对等方没有实现类,因此它会收到此错误。 Make it extend UnicastRemoteObject. 使它扩展UnicastRemoteObject。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM