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
> 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.
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
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.
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?