Exception using RMI, Eclipse and Cajo

Hi,

I am new to RMI and I have a problem with my first program. I use Eclipse 3.3, Java 6, EMF and Cajo.

This is my server:

package server;

import gnu.cajo.invoke.Remote;

import gnu.cajo.utils.ItemServer;

import java.io.File;

import org.eclipse.emf.common.util.URI;

import org.eclipse.emf.ecore.resource.Resource;

import org.eclipse.emf.ecore.resource.ResourceSet;

import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;

import AnforderungsModell.util.AnforderungsModellResourceFactoryImpl;

publicclass Start{

privatestatic Resource reqModel;

publicstaticvoid main(String args[])throws Exception{

// Remote.config(null, 1198, null, 0);

Remote.config("localhost", 1198, null, 0);

ItemServer.bind(new Start(),"AT_Server");

System.out.println("The server is running!");

reqModel = loadReqModel();

}

privatestatic Resource loadReqModel(){

// Create a resource set.

ResourceSet resourceSet =new ResourceSetImpl();

resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("anforderungsmodell",new AnforderungsModellResourceFactoryImpl());

// Get the URI of the model file.

URI fileURI = URI.createFileURI(new File("C:/Programme/Anwendungen/ServerWorkspace/AT_EMFServer/model/My.anforderungsmodell").getAbsolutePath());

// Demand load the resource for this file.

Resource resource = resourceSet.getResource(fileURI,true);

return resource;

}

public Resource getReqModel(){

System.out.println("getReqModel called");

return reqModel;

}

public String test(){

System.out.println("test called");

return"erfolgreich";

}

}

My client:

package rmi;

import java.io.IOException;

import java.net.MalformedURLException;

import java.rmi.NotBoundException;

import java.rmi.RemoteException;

import gnu.cajo.invoke.Remote;

publicclass ConnectToServer{

privatestatic Object object;

public ConnectToServer(){

try{

object = Remote.getItem("//localhost:1198/AT_Server");

}catch (RemoteException e){

// TODO Auto-generated catch block

e.printStackTrace();

}catch (MalformedURLException e){

// TODO Auto-generated catch block

e.printStackTrace();

}catch (NotBoundException e){

// TODO Auto-generated catch block

e.printStackTrace();

}catch (IOException e){

// TODO Auto-generated catch block

e.printStackTrace();

}catch (ClassNotFoundException e){

// TODO Auto-generated catch block

e.printStackTrace();

}catch (InstantiationException e){

// TODO Auto-generated catch block

e.printStackTrace();

}catch (IllegalAccessException e){

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public Object invoke(String method, String args){

try{

return Remote.invoke(object, method, args);

}catch (Exception e){

// TODO Auto-generated catch block

e.printStackTrace();

}

returnnull;

}

}

And my main method to start the client:

package rmi;

publicclass Test{

/**

* @param args

*/

publicstaticvoid main(String[] args){

ConnectToServer connection =new ConnectToServer();

System.out.println(connection.invoke("test",null));

System.out.println(connection.invoke("getReqModel",null));

}

}

The Server prints out:

The server is running!

test called

getReqModel called

The Client prints out:

erfolgreich

java.rmi.UnmarshalException: error unmarshallingreturn; nested exception is:

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: AnforderungsModell.util.AnforderungsModellResourceImpl

at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:173)

at gnu.cajo.invoke.Remote_Stub.invoke(Unknown Source)

at gnu.cajo.invoke.Remote.invoke(Unknown Source)

at rmi.ConnectToServer.invoke(ConnectToServer.java:43)

at rmi.Test.main(Test.java:11)

Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: AnforderungsModell.util.AnforderungsModellResourceImpl

at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1333)

at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)

at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:306)

at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:155)

... 4 more

Caused by: java.io.NotSerializableException: AnforderungsModell.util.AnforderungsModellResourceImpl

at java.io.ObjectOutputStream.writeObject0(Unknown Source)

at java.io.ObjectOutputStream.writeObject(Unknown Source)

at sun.rmi.server.UnicastRef.marshalValue(Unknown Source)

at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)

at sun.rmi.transport.Transport$1.run(Unknown Source)

at java.security.AccessController.doPrivileged(Native Method)

at sun.rmi.transport.Transport.serviceCall(Unknown Source)

at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)

at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)

at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

null

It works for a simple String but not for my more complex EMF Resource Type. What is the problem? Can someone tell me whats wrong with my code?

Thanks,

Mirco

[9761 byte] By [SanSebastiana] at [2007-11-27 11:39:10]
# 1

> java.io.NotSerializableException: AnforderungsModell.util.AnforderungsModellResourceImpl

This probably means you haven't exported that object. You'll have to ask Cajo about how to do that in Cajo, I have no idea. Normally this object would extend UnicastRemoteObject or call UnicastRemoteObject.exportObject(this, 0) in its constructor.

ejpa at 2007-7-29 17:24:26 > top of Java-index,Core,Core APIs...
# 2

Hallo Micro,

The exception is being generated because your getReqModel method is trying to return an EMF Resource object by value and it is not serialisable. Are you sure this is what you want to do?

Perhaps you wanted to return a remote reference to the resource, with which the client can manipulate it?

In that case you would need to remote the reference before returning it. In getReqModel:return new Remote(reqModel);

Then the client can invoke methods on the remote instance of the resource.

Serialisable objects like Strings can be passed freely but non-serialisable ones, must be remoted.

I hope this helps, if you have any more questions, please feel free to ask.

Tschuss

John

cajoa at 2007-7-29 17:24:26 > top of Java-index,Core,Core APIs...
# 3

Hi John,

yes, you are right. In my second step I want to manipulate it with the client. Your solution works great for this.

But first I want to show the EMF Resource in a TreeViewer. So I have to initialize the TreeViewer with an EObject (in this case the reqModel Resouce).

Here how it works without RMI:

TreeViewer treeViewer = new TreeViewer(tree, SWT.MULTI |SWT.V_SCROLL);

treeViewer.setInput(new Itemprovider(Collections.singleton(reqModel.getContents().get(0)));

My problem is that I don't know how to initialize the TreeViewer with a remote reference.

Thanks,

Mirco

Message was edited by:

SanSebastian

SanSebastiana at 2007-7-29 17:24:26 > top of Java-index,Core,Core APIs...
# 4

Unfortunately, I do not know very much about SWT. Hopefully the EObject that TreeViewer requires is a Java Interface. However, given its class name, that looks unlikely. If SWT is well designed, what TreeViewer really needs would be one or more interfaces, implemented by EObject.

In that case, I would point you to the page on turning remote cajo references into syntactically local references, via one or more common interfaces:

http://wiki.java.net/bin/view/Communications/TransparentProxy

John

cajoa at 2007-7-29 17:24:26 > top of Java-index,Core,Core APIs...