Hello. When implementing the remote interface, rmi ran into a problem: my remote methods return without problems primitive types, such as int, char, etc., and when I need to return Object test = new Object (), I get an error:

java.rmi.UnmarshalException: error unmarshalling return; nested exception is: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.lang.Object at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:173) at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178) at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132) at $Proxy0.func(Unknown Source) at rmiclient.Consol$TestActionListener.actionPerformed(Consol.java:107) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236) at java.awt.Component.processMouseEvent(Component.java:6289) at javax.swing.JComponent.processMouseEvent(JComponent.java:3267) at java.awt.Component.processEvent(Component.java:6054) at java.awt.Container.processEvent(Container.java:2041) at java.awt.Component.dispatchEventImpl(Component.java:4652) at java.awt.Container.dispatchEventImpl(Container.java:2099) at java.awt.Component.dispatchEvent(Component.java:4482) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168) at java.awt.Container.dispatchEventImpl(Container.java:2085) at java.awt.Window.dispatchEventImpl(Window.java:2478) at java.awt.Component.dispatchEvent(Component.java:4482) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:644) at java.awt.EventQueue.access$000(EventQueue.java:85) at java.awt.EventQueue$1.run(EventQueue.java:603) at java.awt.EventQueue$1.run(EventQueue.java:601) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98) at java.awt.EventQueue$2.run(EventQueue.java:617) at java.awt.EventQueue$2.run(EventQueue.java:615) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87) at java.awt.EventQueue.dispatchEvent(EventQueue.java:614) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.lang.Object at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1332) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350) at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:155) ... 40 more Caused by: java.io.NotSerializableException: java.lang.Object at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330) at sun.rmi.server.UnicastRef.marshalValue(UnicastRef.java:274) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:315) at sun.rmi.transport.Transport$1.run(Transport.java:159) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:155) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) 

I can not even imagine what could be the problem. Something tell me?

Added.

I work in netbeans. First, I start the server in which the remote interface and remote components are located (interface implementation).

 public interface MyRemoteInterface extends Remote { public Object func (int k) throws RemoteException; } public class MyRemoteComponent extends UnicastRemoteObject implements MyRemoteInterface { public Object func (int k) { Object p=new Object(); return p; } } 

Then I launch the client (run). Without any parameters. The client has the same remote interface and function call:

 Object y = remoteComponent.func(100); 

That's all.

* Added:

 FileOutputStream fos = new FileOutputStream("temp.out"); ObjectOutputStream oos = new ObjectOutputStream(fos); TestSerial ts = new TestSerial(); oos.writeObject(ts); oos.flush(); oos.close(); 
  • Add the patch for the server to those objects that you use in the client. - Alex Kapustin
  • I apologize, but it is possible in more detail. I just use rmi for the second day. - user1753
  • Tell us in detail what and how you launch, and with what parameters - Alex Kapustin
  • I work in netbeans. First, I start the server in which the remote interface and remote components are located (interface implementation). public interface MyRemoteInterface extends Remote {public Object func (int k) throws RemoteException; } public class MyRemoteComponent extends UnicastRemoteObject implements MyRemoteInterface {public Object func (int k) {Object p = new Object (); return p; }} then run the client (run). without any parameters. the client has the same remote interface and the function call Object y = remoteComponent.func (100); that's all. - user1753
  • And how do you start rmiregistry? Separately via cmd? Or also through java project? - Alex Kapustin

2 answers 2

In general, here is a special helloWorld for you to rivet

First of all, we run registryService itself with this file:

RegistryService.java

 package server; import client.TestObject; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.io.Serializable; import java.util.*; public class TestService implements TestServiceInterface, Serializable { Map testServiceListenerQueueMap = new HashMap(); public TestService() throws Exception { init(); unBindFromRegistry(); bindToRegistry(); } private void init() throws Exception { } public String test() throws RemoteException { System.out.println( "test" ); return "Hello"; } public TestObject test2() throws RemoteException { return new TestObject(); } public static void main(String[] args) throws Exception { final TestService t = new TestService(); t.startLiveLoop(); t.unBindFromRegistry(); } public void startLiveLoop() { Thread cMainThread = new Thread(new Runnable() { public void run() { while (Thread.currentThread() != null) { try { //Thread.sleep(10000); Iterator itr = testServiceListenerQueueMap.keySet().iterator(); while (itr.hasNext()) { try { String name = (String) itr.next(); // Ваши какие то действия для очереди сообщений } catch (Exception e) { e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } } }}); cMainThread.setName("Live Loop"); //Start the thread cMainThread.start(); try { cMainThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } protected void bindToRegistry() { boolean bound = false; while (!bound) { try { System.out.println("Trying to bind " + BIND_NAME); java.rmi.server.UnicastRemoteObject.exportObject(this); java.rmi.registry.LocateRegistry.getRegistry().bind(BIND_NAME, this); bound = true; System.out.println("Successfully called bind() for " + BIND_NAME); }catch (Exception ex) { System.out.println("Could not bind " + BIND_NAME + ", trying to rebind"); try { java.rmi.registry.LocateRegistry.getRegistry().rebind(BIND_NAME, this); bound = true; System.out.println("Successfully called rebind() for " + BIND_NAME); }catch (Exception ex2) { System.out.println("Could not rebind " + BIND_NAME); ex2.printStackTrace(); } } //Sleep a little before attemping to bind again. try { Thread.sleep(5000); }catch (Exception ex1) { ex1.printStackTrace(); } } } protected void unBindFromRegistry() { try { System.out.println("Trying unbind() for " + BIND_NAME); java.rmi.registry.LocateRegistry.getRegistry().unbind(BIND_NAME); System.out.println("Successfully called unbind() for " + BIND_NAME); }catch (Exception ex) { System.out.println("Could not unbind() for " + BIND_NAME); } } public void ping() { //System.out.println("ping() :" + getClass().getName()); } } 

Then run this:

 package server; import client.TestObject; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.io.Serializable; import java.util.*; public class TestService implements TestServiceInterface, Serializable { Map testServiceListenerQueueMap = new HashMap(); public TestService() throws Exception { init(); unBindFromRegistry(); bindToRegistry(); } private void init() throws Exception { } public String test() throws RemoteException { System.out.println( "test" ); return "Hello"; } public TestObject test2() throws RemoteException { return new TestObject(); } public static void main(String[] args) throws Exception { final TestService t = new TestService(); t.startLiveLoop(); t.unBindFromRegistry(); } public void startLiveLoop() { Thread cMainThread = new Thread(new Runnable() { public void run() { while (Thread.currentThread() != null) { try { //Thread.sleep(10000); Iterator itr = testServiceListenerQueueMap.keySet().iterator(); while (itr.hasNext()) { try { String name = (String) itr.next(); // Ваши какие то действия для очереди сообщений } catch (Exception e) { e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } } }}); cMainThread.setName("Live Loop"); //Start the thread cMainThread.start(); try { cMainThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } protected void bindToRegistry() { boolean bound = false; while (!bound) { try { System.out.println("Trying to bind " + BIND_NAME); java.rmi.server.UnicastRemoteObject.exportObject(this); java.rmi.registry.LocateRegistry.getRegistry().bind(BIND_NAME, this); bound = true; System.out.println("Successfully called bind() for " + BIND_NAME); }catch (Exception ex) { System.out.println("Could not bind " + BIND_NAME + ", trying to rebind"); try { java.rmi.registry.LocateRegistry.getRegistry().rebind(BIND_NAME, this); bound = true; System.out.println("Successfully called rebind() for " + BIND_NAME); }catch (Exception ex2) { System.out.println("Could not rebind " + BIND_NAME); ex2.printStackTrace(); } } //Sleep a little before attemping to bind again. try { Thread.sleep(5000); }catch (Exception ex1) { ex1.printStackTrace(); } } } protected void unBindFromRegistry() { try { System.out.println("Trying unbind() for " + BIND_NAME); java.rmi.registry.LocateRegistry.getRegistry().unbind(BIND_NAME); System.out.println("Successfully called unbind() for " + BIND_NAME); }catch (Exception ex) { System.out.println("Could not unbind() for " + BIND_NAME); } } public void ping() { //System.out.println("ping() :" + getClass().getName()); } } 

Well, the interface file itself: TestServiceInterface.java

 package server; import client.TestObject; import java.rmi.Remote; import java.rmi.RemoteException; public interface TestServiceInterface extends Remote{ public static final String BIND_NAME = "testRMI"; public String test() throws RemoteException; public TestObject test2() throws RemoteException; public void ping() throws RemoteException; } 

Now the server is running.

We start client Client.java

 package client; import java.rmi.Naming; import server.TestServiceInterface; public class Client { TestServiceInterface test; String RMIURL = "rmi://localhost/" + TestServiceInterface.BIND_NAME; public TestServiceInterface getTest() throws Exception { int attempts = 0; while (attempts < 5) { try { test.ping(); attempts++; Thread.sleep(100); break; }catch (Exception ex) { System.out.println("===> TestClient Connection failed! Reconnecting..."); test = (TestServiceInterface) Naming.lookup( RMIURL ); } } return test; } public void test(){ try{ getTest(); System.out.println( test.test() ); }catch(Exception e){ e.printStackTrace(); } } public void test2(){ try{ getTest(); TestObject to = test.test2(); System.out.println( to.t ); }catch(Exception e){ e.printStackTrace(); } } public static void main(String[] args){ Client c = new Client(); c.test(); c.test2(); } } 

TestObject.java

 package client; import java.io.Serializable; public class TestObject implements Serializable { public String t = "Hello World"; } 
  • Thank you very much! Although there are more questions than answers, but it works. And that's good) - user1753

Hmm, I practically didn’t work with rmi, but based on general erudition, it seems to me that Caused by: java.io.NotSerializableException: java.lang.Object speaks for itself - for rmi to work, the transmitted objects are serializable, etc. e. implemented the interface Serializable .

  • As I understand it, it requires the implementation of the object serialization mechanism. But it requires the mandatory creation of an external file, through which the whole mechanism passes. Question: Why should I use external files to transfer an object via a remote interface? In my opinion this is not logical. Is it possible to get around this? - user1753
  • What external files are you talking about? Serialization is necessary in order to be able to pack objects (arguments and return values) into blocks of bytes for transmission to the other end through the network. Or are you about stubs / stubs? In my opinion, this is one of the moments of the specification and can not do without them. - yozh
  • If you pack this way (added to the main message), then a binary file temp.out is created. I spoke about him. Where can I pack these "blocks of bytes", except in the file, and how to send or receive? - user1753