远程对象不支持的方法
Method not Supported by Remote Object
我有两个应用程序。注册 RMI 对象的服务器应用程序和使用远程对象的客户端应用程序。在客户端中,我创建了一条消息 class 实现可序列化并将其发送到远程对象,但是在调用该方法时出现此错误:java.rmi.UnmarshalException:无法识别的方法哈希:远程对象不支持的方法。我在这里错过了什么?
客户端主要方法
package cryptocomclient;
import RemoteObject.CryptoComManager;
import clientUI.clientGui;
import clientUI.ClientPresenter;
import clientUI.LoginGui;
import java.rmi.*;
public class CryptoCom {
public static void main(String[] args) {
// Gets the remote object reference from RemoteObjectConnection
RemoteObjectConnection netConn = new RemoteObjectConnection();
CryptoComManager ccm = netConn.getCCM();
// Passes the remote object into the client for use
CryptoComClient client = new CryptoComClient(ccm);
LoginGui loginGui = new LoginGui();
loginGui.setVisible(true);
clientGui clientGui = new clientGui();
ClientPresenter presenter = new ClientPresenter(client, clientGui, loginGui);
clientGui.setPresenter(presenter);
loginGui.setPresenter(presenter);
System.out.println("All systems good to go!");
}
}
获取远程对象引用的连接
package cryptocomclient;
import RemoteObject.CryptoComManager;
import java.rmi.Naming;
public class RemoteObjectConnection {
CryptoComManager ccm;
RemoteObjectConnection() {
pullFromRegistry();
}
// Will be used to pass the ccm to the client during dependancy injections
// in the main method of the client app.
public CryptoComManager getCCM() {return ccm;}
// Looks up the name of the object in the registry and sets it's reference
// to the ccm located here.
private void pullFromRegistry() {
try {
ccm = (CryptoComManager)Naming.lookup(CryptoComManager.LOOKUPNAME);
System.out.println("Remote object pulled from registry.");
}
catch (Exception e) {
System.err.println("CrytpoComCilent: CryptoComManager exception: " + e.getMessage());
}
}
}
客户端
package cryptocomclient;
import RemoteObject.CryptoComManager;
import java.rmi.RemoteException;
import java.util.ArrayList;
public class CryptoComClient {
private ArrayList<Message> receivedMessageList = new ArrayList<>();
private String userName;
private CryptoComManager ccm;
// Constructor that takes in a reference to the remote object.
public CryptoComClient(CryptoComManager ccm) {
this.ccm = ccm;
}
//Constructor that takes no remote object reference (for testing)
public CryptoComClient(){
}
// Creates a new instance of Message and returns it.
public Message createNewMessage(String memo, String sender, String recipient) {
//Encryption should be done here
return new Message(memo, sender, recipient);
}
// Returns a message from the recived arrayList at the specified index.
public Message openMessage(int index) {
if (receivedMessageList.size() == 0) {
return null;
}
return receivedMessageList.get(index);
}
// Takes in a message and sends the message to the remote object
public void sendMessage(Message message) throws RemoteException {
ccm.sendMessageToServer(message);
}
// Calls the remote object to get the stored messages then adds them to the
// clients receivedMessageList
public void getReceivedMessages() throws RemoteException {
ArrayList<Message> receivedList = ccm.receiveMessagesFromServer(userName);
for(Message message: receivedList) {
receivedMessageList.add(message);
}
}
// Removes a message from the received message arrayList
public void removeReceivedMessage(Message message) {
receivedMessageList.remove(message);
}
// Getters and setters for fields listed at the top
public ArrayList<Message> getRecievedMessageList() {return receivedMessageList;}
public void setReceivedMessageList(ArrayList<Message> recievedMessageList) {this.receivedMessageList = recievedMessageList;}
public String getUserName() {return userName;}
public void setUserName(String userName) {this.userName = userName;}
public CryptoComManager getCCM() {return ccm;}
public void setCCM(CryptoComManager ccm) {this.ccm = ccm;}
}
远程对象接口
package RemoteObject;
import cryptocomclient.Message;
import java.rmi.*;
import java.util.ArrayList;
public interface CryptoComManager extends Remote{
public final static String LOOKUPNAME = "CryptoComManager";
public void sendMessageToServer(Message message) throws RemoteException;
public ArrayList<Message> receiveMessagesFromServer(String userName) throws RemoteException;
}
远程对象实现
package RemoteObject;
import cryptocomclient.Message;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashMap;
public class CryptoComManagerImpl extends UnicastRemoteObject implements CryptoComManager{
private HashMap<String, ArrayList<Message>> messageMap = new HashMap<>();
public CryptoComManagerImpl() throws RemoteException{
super();
}
@Override
public void sendMessageToServer(Message message) throws RemoteException {
// Checks to see if the recipient already has an arraylist
// If it doesn't creates a new arraylist with the recipient as the key
if(!messageMap.containsKey(message.getRecipient())){
messageMap.put(message.getRecipient(), new ArrayList<Message>());
}
// Gets the recipients Arraylist and adds the new message
ArrayList<Message> recipientArrayList = messageMap.get(message.getRecipient());
recipientArrayList.add(message);
}
@Override
public ArrayList<Message> receiveMessagesFromServer(String userName) throws RemoteException {
ArrayList<Message> arrayListToSendBack = messageMap.get(userName);
messageMap.remove(arrayListToSendBack);
return arrayListToSendBack;
}
public HashMap<String, ArrayList<Message>> getHashMap() {return messageMap;}
}
留言class
package cryptocomclient;
import java.io.Serializable;
import java.util.Objects;
public class Message implements Serializable{
String memo,
sender,
recipient;
public Message(String memo, String sender, String recipient) {
this.memo = memo;
this.sender = sender;
this.recipient = recipient;
}
@Override
public boolean equals(Object o) {
if(o == this) {return true;}
if(!(o instanceof Message)) {return false;}
Message otherMessage = (Message)o;
if(this.memo == otherMessage.memo &&
this.sender == otherMessage.sender &&
this.recipient == otherMessage.recipient)
{
return true;
}
return false;
}
@Override
public int hashCode() {
int hash = 3;
hash = 41 * hash + Objects.hashCode(this.memo);
hash = 41 * hash + Objects.hashCode(this.sender);
hash = 41 * hash + Objects.hashCode(this.recipient);
return hash;
}
public String getMemo() {return memo;}
public void setMemo(String memo) {this.memo = memo;}
public String getSender() {return sender;}
public void setSender(String sender) {this.sender = sender;}
public String getRecipient() {return recipient;}
public void setRecipent(String recipient) {this.recipient = recipient;}
}
服务器应用程序
package cryptocomserver;
import java.rmi.*;
import RemoteObject.*;
import java.rmi.registry.LocateRegistry;
public class CryptoComServer {
public static void main(String[] args) throws RemoteException {
System.out.println("CryptoComServer starting...");
System.out.println("Creating Registry...");
// Creates and exports a Registry instance on the local host that
// accepts request on port 1099
LocateRegistry.createRegistry(1099);
System.out.println("Registry created.");
//System.setSecurityManager(new SecurityManager());
//System.out.println("Security Manager installed, Setting up service");
try {
// Creates instance of CryptoComManagerImpl object
CryptoComManagerImpl ccm = new CryptoComManagerImpl();
System.out.println("Publishing CryptoComServer...");
// Binds the object to the registry using the LOOKUPNAME
Naming.rebind(CryptoComManager.LOOKUPNAME, ccm);
System.out.println("CryptoComServer ready.");
}
catch (Exception e) {
System.err.println(e);
System.exit(1);
}
}
}
堆栈
run:
Oct 20, 2019 12:07:32 AM clientUI.clientGui sendButtonActionPerformed
SEVERE: null
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: unrecognized method hash: method not supported by remote object
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:389)
at sun.rmi.transport.Transport.run(Transport.java:200)
at sun.rmi.transport.Transport.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:573)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:835)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run[=17=](TCPTransport.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:283)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:260)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:161)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
at com.sun.proxy.$Proxy0.sendMessageToServer(Unknown Source)
at cryptocomclient.CryptoComClient.sendMessage(CryptoComClient.java:45)
at clientUI.ClientPresenter.send(ClientPresenter.java:42)
at clientUI.clientGui.sendButtonActionPerformed(clientGui.java:258)
at clientUI.clientGui.access[=17=]0(clientGui.java:19)
at clientUI.clientGui.actionPerformed(clientGui.java:159)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6533)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6298)
at java.awt.Container.processEvent(Container.java:2238)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2296)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4897)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4534)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4475)
at java.awt.Container.dispatchEventImpl(Container.java:2282)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
at java.awt.EventQueue.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:709)
at java.awt.EventQueue.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
at java.awt.EventQueue.run(EventQueue.java:733)
at java.awt.EventQueue.run(EventQueue.java:731)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.rmi.UnmarshalException: unrecognized method hash: method not supported by remote object
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:327)
at sun.rmi.transport.Transport.run(Transport.java:200)
at sun.rmi.transport.Transport.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:573)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:835)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run[=17=](TCPTransport.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Message.java class 存在于服务器和客户端应用程序中,但未打包在完全相同的文件结构中。我重构了结构,使 Message、RemoteObjectManager 和 RemoteObjectManagerImpl 都在同一个包中,并且这些包在各自的应用程序中的名称相同,现在一切正常。
我有两个应用程序。注册 RMI 对象的服务器应用程序和使用远程对象的客户端应用程序。在客户端中,我创建了一条消息 class 实现可序列化并将其发送到远程对象,但是在调用该方法时出现此错误:java.rmi.UnmarshalException:无法识别的方法哈希:远程对象不支持的方法。我在这里错过了什么?
客户端主要方法
package cryptocomclient;
import RemoteObject.CryptoComManager;
import clientUI.clientGui;
import clientUI.ClientPresenter;
import clientUI.LoginGui;
import java.rmi.*;
public class CryptoCom {
public static void main(String[] args) {
// Gets the remote object reference from RemoteObjectConnection
RemoteObjectConnection netConn = new RemoteObjectConnection();
CryptoComManager ccm = netConn.getCCM();
// Passes the remote object into the client for use
CryptoComClient client = new CryptoComClient(ccm);
LoginGui loginGui = new LoginGui();
loginGui.setVisible(true);
clientGui clientGui = new clientGui();
ClientPresenter presenter = new ClientPresenter(client, clientGui, loginGui);
clientGui.setPresenter(presenter);
loginGui.setPresenter(presenter);
System.out.println("All systems good to go!");
}
}
获取远程对象引用的连接
package cryptocomclient;
import RemoteObject.CryptoComManager;
import java.rmi.Naming;
public class RemoteObjectConnection {
CryptoComManager ccm;
RemoteObjectConnection() {
pullFromRegistry();
}
// Will be used to pass the ccm to the client during dependancy injections
// in the main method of the client app.
public CryptoComManager getCCM() {return ccm;}
// Looks up the name of the object in the registry and sets it's reference
// to the ccm located here.
private void pullFromRegistry() {
try {
ccm = (CryptoComManager)Naming.lookup(CryptoComManager.LOOKUPNAME);
System.out.println("Remote object pulled from registry.");
}
catch (Exception e) {
System.err.println("CrytpoComCilent: CryptoComManager exception: " + e.getMessage());
}
}
}
客户端
package cryptocomclient;
import RemoteObject.CryptoComManager;
import java.rmi.RemoteException;
import java.util.ArrayList;
public class CryptoComClient {
private ArrayList<Message> receivedMessageList = new ArrayList<>();
private String userName;
private CryptoComManager ccm;
// Constructor that takes in a reference to the remote object.
public CryptoComClient(CryptoComManager ccm) {
this.ccm = ccm;
}
//Constructor that takes no remote object reference (for testing)
public CryptoComClient(){
}
// Creates a new instance of Message and returns it.
public Message createNewMessage(String memo, String sender, String recipient) {
//Encryption should be done here
return new Message(memo, sender, recipient);
}
// Returns a message from the recived arrayList at the specified index.
public Message openMessage(int index) {
if (receivedMessageList.size() == 0) {
return null;
}
return receivedMessageList.get(index);
}
// Takes in a message and sends the message to the remote object
public void sendMessage(Message message) throws RemoteException {
ccm.sendMessageToServer(message);
}
// Calls the remote object to get the stored messages then adds them to the
// clients receivedMessageList
public void getReceivedMessages() throws RemoteException {
ArrayList<Message> receivedList = ccm.receiveMessagesFromServer(userName);
for(Message message: receivedList) {
receivedMessageList.add(message);
}
}
// Removes a message from the received message arrayList
public void removeReceivedMessage(Message message) {
receivedMessageList.remove(message);
}
// Getters and setters for fields listed at the top
public ArrayList<Message> getRecievedMessageList() {return receivedMessageList;}
public void setReceivedMessageList(ArrayList<Message> recievedMessageList) {this.receivedMessageList = recievedMessageList;}
public String getUserName() {return userName;}
public void setUserName(String userName) {this.userName = userName;}
public CryptoComManager getCCM() {return ccm;}
public void setCCM(CryptoComManager ccm) {this.ccm = ccm;}
}
远程对象接口
package RemoteObject;
import cryptocomclient.Message;
import java.rmi.*;
import java.util.ArrayList;
public interface CryptoComManager extends Remote{
public final static String LOOKUPNAME = "CryptoComManager";
public void sendMessageToServer(Message message) throws RemoteException;
public ArrayList<Message> receiveMessagesFromServer(String userName) throws RemoteException;
}
远程对象实现
package RemoteObject;
import cryptocomclient.Message;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashMap;
public class CryptoComManagerImpl extends UnicastRemoteObject implements CryptoComManager{
private HashMap<String, ArrayList<Message>> messageMap = new HashMap<>();
public CryptoComManagerImpl() throws RemoteException{
super();
}
@Override
public void sendMessageToServer(Message message) throws RemoteException {
// Checks to see if the recipient already has an arraylist
// If it doesn't creates a new arraylist with the recipient as the key
if(!messageMap.containsKey(message.getRecipient())){
messageMap.put(message.getRecipient(), new ArrayList<Message>());
}
// Gets the recipients Arraylist and adds the new message
ArrayList<Message> recipientArrayList = messageMap.get(message.getRecipient());
recipientArrayList.add(message);
}
@Override
public ArrayList<Message> receiveMessagesFromServer(String userName) throws RemoteException {
ArrayList<Message> arrayListToSendBack = messageMap.get(userName);
messageMap.remove(arrayListToSendBack);
return arrayListToSendBack;
}
public HashMap<String, ArrayList<Message>> getHashMap() {return messageMap;}
}
留言class
package cryptocomclient;
import java.io.Serializable;
import java.util.Objects;
public class Message implements Serializable{
String memo,
sender,
recipient;
public Message(String memo, String sender, String recipient) {
this.memo = memo;
this.sender = sender;
this.recipient = recipient;
}
@Override
public boolean equals(Object o) {
if(o == this) {return true;}
if(!(o instanceof Message)) {return false;}
Message otherMessage = (Message)o;
if(this.memo == otherMessage.memo &&
this.sender == otherMessage.sender &&
this.recipient == otherMessage.recipient)
{
return true;
}
return false;
}
@Override
public int hashCode() {
int hash = 3;
hash = 41 * hash + Objects.hashCode(this.memo);
hash = 41 * hash + Objects.hashCode(this.sender);
hash = 41 * hash + Objects.hashCode(this.recipient);
return hash;
}
public String getMemo() {return memo;}
public void setMemo(String memo) {this.memo = memo;}
public String getSender() {return sender;}
public void setSender(String sender) {this.sender = sender;}
public String getRecipient() {return recipient;}
public void setRecipent(String recipient) {this.recipient = recipient;}
}
服务器应用程序
package cryptocomserver;
import java.rmi.*;
import RemoteObject.*;
import java.rmi.registry.LocateRegistry;
public class CryptoComServer {
public static void main(String[] args) throws RemoteException {
System.out.println("CryptoComServer starting...");
System.out.println("Creating Registry...");
// Creates and exports a Registry instance on the local host that
// accepts request on port 1099
LocateRegistry.createRegistry(1099);
System.out.println("Registry created.");
//System.setSecurityManager(new SecurityManager());
//System.out.println("Security Manager installed, Setting up service");
try {
// Creates instance of CryptoComManagerImpl object
CryptoComManagerImpl ccm = new CryptoComManagerImpl();
System.out.println("Publishing CryptoComServer...");
// Binds the object to the registry using the LOOKUPNAME
Naming.rebind(CryptoComManager.LOOKUPNAME, ccm);
System.out.println("CryptoComServer ready.");
}
catch (Exception e) {
System.err.println(e);
System.exit(1);
}
}
}
堆栈
run:
Oct 20, 2019 12:07:32 AM clientUI.clientGui sendButtonActionPerformed
SEVERE: null
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: unrecognized method hash: method not supported by remote object
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:389)
at sun.rmi.transport.Transport.run(Transport.java:200)
at sun.rmi.transport.Transport.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:573)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:835)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run[=17=](TCPTransport.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:283)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:260)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:161)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
at com.sun.proxy.$Proxy0.sendMessageToServer(Unknown Source)
at cryptocomclient.CryptoComClient.sendMessage(CryptoComClient.java:45)
at clientUI.ClientPresenter.send(ClientPresenter.java:42)
at clientUI.clientGui.sendButtonActionPerformed(clientGui.java:258)
at clientUI.clientGui.access[=17=]0(clientGui.java:19)
at clientUI.clientGui.actionPerformed(clientGui.java:159)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6533)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6298)
at java.awt.Container.processEvent(Container.java:2238)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2296)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4897)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4534)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4475)
at java.awt.Container.dispatchEventImpl(Container.java:2282)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
at java.awt.EventQueue.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:709)
at java.awt.EventQueue.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
at java.awt.EventQueue.run(EventQueue.java:733)
at java.awt.EventQueue.run(EventQueue.java:731)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.rmi.UnmarshalException: unrecognized method hash: method not supported by remote object
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:327)
at sun.rmi.transport.Transport.run(Transport.java:200)
at sun.rmi.transport.Transport.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:573)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:835)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run[=17=](TCPTransport.java:688)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Message.java class 存在于服务器和客户端应用程序中,但未打包在完全相同的文件结构中。我重构了结构,使 Message、RemoteObjectManager 和 RemoteObjectManagerImpl 都在同一个包中,并且这些包在各自的应用程序中的名称相同,现在一切正常。