Z
Zheng Da
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
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