Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / June 2006

Tip: Looking for answers? Try searching our database.

I got some problems when using use activation mechanism of RMI

Thread view: 
Zheng Da - 31 May 2006 09:49 GMT
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 - 31 May 2006 10:49 GMT
> 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 - 31 May 2006 11:19 GMT
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

> > public class ProductImpl extends UnicastRemoteObject implements Product
>
[quoted text clipped - 5 lines]
>
> There may be other problems.
Zheng Da - 31 May 2006 11:38 GMT
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.

> > public class ProductImpl extends UnicastRemoteObject implements Product
>
[quoted text clipped - 5 lines]
>
> There may be other problems.
EJP - 01 Jun 2006 05:49 GMT
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 - 01 Jun 2006 08:03 GMT
Thank you.
> Sorry, my mistake it can't extend UnicastRemoteObject, because that will
> automatically export it. Delete those two words, or extend Activatable
[quoted text clipped - 5 lines]
>
> 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.
> 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?
EJP - 02 Jun 2006 02:50 GMT
Well done. Activation is a pretty little mess and very tricky to conquer.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.