问题
Class for all
package Task2;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class IdCl extends UnicastRemoteObject {
private int id;
private String name;
protected IdCl() throws RemoteException {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setId(int id) {
this.id = id;
}
}
Interface for client
package Task2;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ClientInt extends Remote {
public void printMe(String s) throws RemoteException;
public void onePrint(String s) throws RemoteException;
}
Class for CLient
package Task2;
import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class ClientCl extends UnicastRemoteObject implements ClientInt {
protected ClientCl() throws RemoteException {
}
public void printMe(String s) throws RemoteException {
System.out.println(s);
}
public void onePrint(String s) throws RemoteException {
System.out.println(s);
}
}
Client
package Task2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
protected Client() throws RemoteException {
}
public synchronized static void main(String[] args) throws IOException {
ServInt servInt = null;
if (System.getSecurityManager()==null){
System.setSecurityManager(new SecurityManager());
}
try {
Registry registry = LocateRegistry.getRegistry("localhost",Registry.REGISTRY_PORT);
servInt= (ServInt) Naming.lookup("server");
}catch (Exception e){
System.err.println(e);
e.printStackTrace();
}
IdCl idCl = new IdCl();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("What is your name?");
idCl.setName(br.readLine());
ClientInt clientInt = new ClientCl();
// servInt.someNew(clientInt);
servInt.connect(idCl, clientInt);
}
}
Interface for server
package Task2;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface ServInt extends Remote {
public void connect(IdCl idCl, ClientInt clientInt)throws RemoteException;
public void someNew(ClientInt clientInt)throws RemoteException;
}
Class for server
package Task2;
import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Vector;
public class ServCl extends UnicastRemoteObject implements ServInt {
protected int bw = 100000;
private Vector<ClientInt> serverlist;
protected ServCl() throws RemoteException {
}
public void someNew (ClientInt clientInt) throws RemoteException {
serverlist.addElement(clientInt);
}
@Override
public void connect(IdCl idCl, ClientInt clientInt) throws RemoteException {
if (!serverlist.contains(clientInt)) {
serverlist.addElement(clientInt);
idCl.setId((int)Math.random()*bw);
print(clientInt);
}
else {
clientInt.onePrint("Hello from the server "+clientInt.getClass().getName());
}
}
public void print(ClientInt clientInt) throws RemoteException {
for (int i = 0; i < serverlist.capacity(); i++) {
if (!(clientInt.equals(serverlist.get(i)))) {
clientInt.printMe("Hello from " + serverlist.get(i).getClass().getName()+". Nice to meet you "+clientInt.getClass().getName());
}
}
}
}
Server
package Task2;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class Server {
public static void main(String[] args) throws InterruptedException {
if (System.getSecurityManager()==null){
System.setSecurityManager(new SecurityManager());
}
try {
Registry registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
ServInt servInt = new ServCl();
registry.rebind("server",servInt);
}catch (Exception e){
System.err.println(e);
e.printStackTrace();
}
Thread.sleep(5000);
}
}
Mistake 1
Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
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: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.connect(Unknown Source)
at Task2.Client.main(Client.java:34)
If I remove from all class - UnicastRemoteObject and all syncronized metods and use is "Server" UnicastRemoteObject.ExportObject I will have this:
Exception in thread "main" java.rmi.MarshalException: error marshalling arguments; nested exception is:
java.io.NotSerializableException: Task2.IdCl
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:157)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:227)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:179)
at com.sun.proxy.$Proxy0.connect(Unknown Source)
at Task2.Client.main(Client.java:34)
Caused by: java.io.NotSerializableException: Task2.IdCl
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at sun.rmi.server.UnicastRef.marshalValue(UnicastRef.java:290)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:152)
... 4 more
People) I need your help) What I misundesrstand? What I miss?
Thank all for help. I added to IdCl extend Serializible ant it start works.
But I have another problem)) It is
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 1
at java.util.Vector.get(Vector.java:748)
at Task2.ServCl.print(ServCl.java:35)
at Task2.ServCl.connect(ServCl.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
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: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.connect(Unknown Source)
at Task2.Client.main(Client.java:34)
Ok I replaced method serverlist.capacity for serverlist.size.... My stupid mistake)
回答1:
Re the first issue, you changed your remote interface without recompiling or redeploying the client code, which should no longer compile, unless you've changed it, in which case you still haven't recompiled or redeployed it.
The second case changes the semantics of the application, in that IdCl
becomes a non-remote object, which is a completely different kettle of fish. Unclear why you even suggested it.
Just clean, build, fix, and redeploy.
Re your comment below, adding Serializable
to ClientInterface
accomplishes exactly nothing, as ClientCl extends UnicastRemoteObject
which (a) is already Serializable
and (b) never gets serialized, because it is an exported remote object by construction. You need to do what it says in my answer. When you call methods of ClientCl
they print at the host ClientCl
was exported from. Or else this is not the real code.
来源:https://stackoverflow.com/questions/49294521/rmi-mistake-illegalargumentexception-marshalexception