Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

I got some problems when using use activation mechanism of RMI

17 views
Skip to first unread message

Zheng Da

unread,
May 31, 2006, 4:49:50 AM5/31/06
to
I wrote a program to use activation mechanism of RMI to instantiate
remote
objects.
The program is as follow:

The interface is
import java.io.Serializable;
import java.rmi.Remote;
import java.rmi.RemoteException;

interface Product // shared by client and server
extends Remote, Serializable
{
String getDescription() throws RemoteException;
}

/*-------------------------------------------------------------*/

The remote object is
import java.rmi.MarshalledObject;
import java.rmi.RemoteException;
import java.rmi.activation.ActivationID;
import java.rmi.server.*;

/**
This is the implementation class for the remote product
objects.
*/
public class ProductImpl extends UnicastRemoteObject implements Product
{

private static final long serialVersionUID = 6613571299445532659L;

private String name;

public ProductImpl(ActivationID id , MarshalledObject object)throws
RemoteException{
//Activatable.exportObject(this , id , 0);
System.out.println("marshalledobject");
}

public ProductImpl(String n) throws RemoteException {
name = n;
System.out.println("no marshalledobject");
}

public String getDescription() throws RemoteException {
return "I am a " + name + ". Buy me!";
}
}

/*-----------------------------------------------------------------*/

The server is
import java.rmi.MarshalledObject;
import java.rmi.RMISecurityManager;
import java.rmi.activation.Activatable;
import java.rmi.activation.ActivationDesc;
import java.rmi.activation.ActivationGroup;
import java.rmi.activation.ActivationGroupDesc;
import java.rmi.activation.ActivationGroupID;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;

/**
This server program activates two remote objects and
registers them with the naming service.
*/
public class ProductActivator {
public static void main(String args[]) {
try {
System.out.println("Constructing activation descriptors...");

Properties properties = new Properties();
properties.put("java.security.policy", "policy");
properties.put("java.rmi.server.codebase", System
.getProperty("java.rmi.server.codebase"));
String[] options = new String[] { "-cp","."};
// use the server.policy file in the current directory
//props.put("java.security.policy", new
File("server.policy").getCanonicalPath());
System.setSecurityManager(new RMISecurityManager());
ActivationGroupDesc group = new
ActivationGroupDesc(properties, null);
ActivationGroupID id =
ActivationGroup.getSystem().registerGroup(
group);
MarshalledObject p1param = new MarshalledObject("Blackwell
Toaster");

String classDir = ".";
// turn the class directory into a file URL
// for this demo we assume that the classes are in the
current dir
// we use toURI so that spaces and other special characters
in file names
are escaped
//String classURL = new
File(classDir).getCanonicalFile().toURI().toString();
String
classURL=System.getProperty("java.rmi.server.codebase");

ActivationDesc desc1 = new ActivationDesc(id,
"ProductImpl",classURL,
p1param);

Product p1 = (Product) Activatable.register(desc1);

System.out.println("Binding activable implementations to
registry...");
Context namingContext = new InitialContext();
namingContext.rebind("rmi:toaster", p1);
System.out.println("Exiting...");
} catch (Exception e) {
e.printStackTrace();
}
}
}

/*----------------------------------------------------------*/

The client is
import java.rmi.*;
import javax.naming.*;

/**
This program demonstrates how to call a remote method
on two objects that are located through the naming service.
*/
public class ProductClient {
public static void main(String[] args) {
if(System.getSecurityManager() == null)
System.setSecurityManager(new RMISecurityManager());
String url = "rmi://localhost/";
// change to "rmi://yourserver.com/" when server runs on
remote machine
yourserver.com
try {
Context namingContext = new InitialContext();
Product c1 = (Product) namingContext.lookup(url + "toaster");
//Product c2 = (Product) namingContext.lookup(url +
"microwave");
System.out.println(c1.getDescription());
//System.out.println(c2.getDescription());
} catch (Exception e) {
e.printStackTrace();
}
}
}

I start rmid and rmiregistry.
And run my program as follow:
java -Djava.security.policy=policy
-Djava.rmi.server.codebase=http://localhost:8081/ ProductActivator
java -Djava.security.policy=policy ProductClient
The policy is as follow:
grant{
permission java.security.AllPermission;
};

But I got the java.rmi.activation.ActivateFailedException.
java.rmi.activation.ActivateFailedException: failed to activate object;
nested exception is:
java.lang.ClassCastException
at sun.rmi.server.ActivatableRef.activate(Unknown Source)
at sun.rmi.server.ActivatableRef.invoke(Unknown Source)
at ProductImpl_Stub.getDescription(Unknown Source)
at ProductClient.main(ProductClient.java:20)
Caused by: java.lang.ClassCastException
... 4 more

Does anyone know the problem?
Thank you

EJP

unread,
May 31, 2006, 5:49:06 AM5/31/06
to
Zheng Da wrote:

> public class ProductImpl extends UnicastRemoteObject implements Product

You must either change this to 'extends Activatable implements Product',
in which case you should replace the following quoted line by super(id,
0); or else restore the following quoted line as it is:

> //Activatable.exportObject(this , id , 0);

There may be other problems.

Zheng Da

unread,
May 31, 2006, 6:19:26 AM5/31/06
to
I change the class ProductImpl as you said.
public class ProductImpl extends Activatable implements Product {

private String name;

private static final long serialVersionUID = 6613571299445532659L;

public ProductImpl(ActivationID id , MarshalledObject object)throws
IOException, ClassNotFoundException{
super(id , 0);
name=(String)object.get();
System.out.println("marshalledobject");
}

public String getDescription() throws RemoteException {
return "I am a " + name + ". Buy me!";
}
}

But I get another exception:
java.rmi.UnmarshalException: Error unmarshaling return header; nested
exception is:
java.io.EOFException
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)


at sun.rmi.server.ActivatableRef.invoke(Unknown Source)
at ProductImpl_Stub.getDescription(Unknown Source)
at ProductClient.main(ProductClient.java:20)

Caused by: java.io.EOFException
at java.io.DataInputStream.readByte(Unknown Source)
... 5 more

Zheng Da

unread,
May 31, 2006, 6:38:02 AM5/31/06
to
You're right.
But I find that running rmid should be as follow:
rmid -J-Dsun.rmi.activation.execPolicy=none
-J-Djava.security.policy=rmid.policy
And the program cannot run correctly when using
Activatable.exportObject(this , id , 0);
If the ProductImpl is:

public class ProductImpl extends UnicastRemoteObject implements Product
{
private String name;

private static final long serialVersionUID = 6613571299445532659L;
public ProductImpl(ActivationID id , MarshalledObject object)throws
IOException, ClassNotFoundException{
//super(id , 0);
Activatable.exportObject(this , id , 0);
name=(String)object.get();
System.out.println("marshalledobject");
}

public String getDescription() throws RemoteException {
return "I am a " + name + ". Buy me!";
}
}

I still get the exception when the client runs.


java.rmi.activation.ActivateFailedException: failed to activate object;
nested exception is:

java.rmi.activation.ActivationException: exception in object
constructor; nested exception is:
java.rmi.server.ExportException: object already exported


at sun.rmi.server.ActivatableRef.activate(Unknown Source)
at sun.rmi.server.ActivatableRef.invoke(Unknown Source)
at ProductImpl_Stub.getDescription(Unknown Source)
at ProductClient.main(ProductClient.java:20)

Caused by: java.rmi.activation.ActivationException: exception in object
constructor; nested exception is:
java.rmi.server.ExportException: object already exported
at
sun.rmi.server.ActivationGroupImpl.newInstance(ActivationGroupImpl.java:286)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
at sun.rmi.transport.Transport$1.run(Transport.java:148)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
at
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:534)
at
sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
at
sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:133)
at java.rmi.activation.ActivationGroup_Stub.newInstance(Unknown
Source)
at
sun.rmi.server.Activation$ObjectEntry.activate(Activation.java:1481)
at sun.rmi.server.Activation$GroupEntry.activate(Activation.java:1132)
at
sun.rmi.server.Activation$ActivatorImpl.activate(Activation.java:262)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
at sun.rmi.transport.Transport$1.run(Transport.java:148)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
at
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:534)
at
sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown
Source)


at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)

at sun.rmi.server.Activation$ActivatorImpl_Stub.activate(Unknown
Source)
at java.rmi.activation.ActivationID.activate(Unknown Source)
... 4 more
Caused by: java.rmi.server.ExportException: object already exported
at sun.rmi.transport.ObjectTable.putTarget(ObjectTable.java:171)
at sun.rmi.transport.Transport.exportObject(Transport.java:69)
at
sun.rmi.transport.tcp.TCPTransport.exportObject(TCPTransport.java:190)
at
sun.rmi.transport.tcp.TCPEndpoint.exportObject(TCPEndpoint.java:382)
at sun.rmi.transport.LiveRef.exportObject(LiveRef.java:116)
at
sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:145)
at
sun.rmi.server.UnicastServerRef.exportObject(UnicastServerRef.java:129)
at java.rmi.activation.Activatable.exportObject(Activatable.java:507)
at java.rmi.activation.Activatable.exportObject(Activatable.java:399)
at ProductImpl.<init>(ProductImpl.java:22)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
at
sun.rmi.server.ActivationGroupImpl$1.run(ActivationGroupImpl.java:241)
at java.security.AccessController.doPrivileged(Native Method)
at
sun.rmi.server.ActivationGroupImpl.newInstance(ActivationGroupImpl.java:222)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
at sun.rmi.transport.Transport$1.run(Transport.java:148)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
at
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:534)

It seems that the server has exported the object, and the client cannot
export it again.

EJP

unread,
Jun 1, 2006, 12:49:39 AM6/1/06
to
Sorry, my mistake it can't extend UnicastRemoteObject, because that will
automatically export it. Delete those two words, or extend Activatable
and use the super(id,0) in the constructor instead of Activatable.
exportObject(). These two forms are equivalent: the super(id,0) call
just calls Activatable.exportObject for you. There's nothing to choose
between them and certainly no reason to believe that one works better
than the other.

I don't know what's going on with your UnmarshalException. Can you turn
on java.rmi.server.logCalls and the transport logging at rmid and in the
system properties of the activation group, and have a look at what comes
out?

Zheng Da

unread,
Jun 1, 2006, 3:03:08 AM6/1/06
to
Thank you.

EJP wrote:
> Sorry, my mistake it can't extend UnicastRemoteObject, because that will
> automatically export it. Delete those two words, or extend Activatable
> and use the super(id,0) in the constructor instead of Activatable.
> exportObject(). These two forms are equivalent: the super(id,0) call
> just calls Activatable.exportObject for you. There's nothing to choose
> between them and certainly no reason to believe that one works better
> than the other.
>
> I don't know what's going on with your UnmarshalException. Can you turn
It's my mistake. I forget to specify a policy file when I run rmid.

EJP

unread,
Jun 1, 2006, 9:50:06 PM6/1/06
to
Well done. Activation is a pretty little mess and very tricky to conquer.
0 new messages