|
![]() |
Note: This FAQ is under construction. If one of your question is not answered here, just send it at proactive-support@sophia.inria.fr and we'll update the FAQ.
this
and ProActive.getStubOnThis()
? ProActive uses Ant for its build. Assuming that
the environment variable JAVA_HOME
is properly set to your Java
distribution, just go into the compile
directory and use the
script :
build.bat all
build all
all
represents the target of the build.
Other targets are available if needed :
General source file builds
core
: ProActive coreext
: ProActive extic2d
: All IC2Dexamples
: All examplesall
: means all of the aboveUtility builds
docs
: creates the docs directory with javadoc
+ docclean
: removes all build generated filedist
: creates the distribution directory and filesAccording to the tool used to unpackage the ProActive distribution, permissions of newly created files can be based on default UMASK permissions. If you get a permission denied, just run the command: chmod 755 *.sh in the ProActive/scripts/unix directory in order to change the permissions.
ProActive uses ASM for the on the fly generation
of stub classes. The library asm.jar
, provided in the directory
lib
of ProActive is needed in order for any active
object to function properly. If the library is not in the CLASSPATH
you will get the following exception or a similar one :
Exception in thread "main" java.lang.NoClassDefFoundError: org/objectweb/asm/Constants
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:509)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:123)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:246)
at java.net.URLClassLoader.access$100(URLClassLoader.java:54)
at java.net.URLClassLoader$1.run(URLClassLoader.java:193)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:186)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:265)
at java.lang.ClassLoader.loadClass(ClassLoader.java:262)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:322)
at org.objectweb.proactive.core.mop.MOP.<clinit>(MOP.java:88)
at org.objectweb.proactive.ProActive.createStubObject(ProActive.java:836)
at org.objectweb.proactive.ProActive.createStubObject(ProActive.java:830)
at org.objectweb.proactive.ProActive.newActive(ProActive.java:255)
at org.objectweb.proactive.ProActive.newActive(ProActive.java:180)
at org.objectweb.proactive.examples.binarytree.TreeApplet.main(TreeApplet.java:103)
The problem can simply be fixed by adding asm.jar
in the CLASSPATH
.
ProActive uses BCEL for the on the fly generation
of stub classes. The library bcel.jar
, provided in the directory
lib
of ProActive is needed in order for any active
object to function properly. If the library if not in the CLASSPATH
you will get the following exception or a similar one :
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/bcel/generic/Type
at org.objectweb.proactive.core.mop.MOPClassLoader.loadClass(MOPClassLoader.java:129)
at org.objectweb.proactive.core.mop.MOPClassLoader.loadClass(MOPClassLoader.java:109)
at org.objectweb.proactive.core.mop.MOP.createStubClass(MOP.java:341)
at org.objectweb.proactive.core.mop.MOP.findStubConstructor(MOP.java:376)
at org.objectweb.proactive.core.mop.MOP.createStubObject(MOP.java:443)
at org.objectweb.proactive.core.mop.MOP.newInstance(MOP.java:165)
at org.objectweb.proactive.core.mop.MOP.newInstance(MOP.java:137)
at org.objectweb.proactive.ProActive.createStubObject(ProActive.java:590)
at org.objectweb.proactive.ProActive.createStubObject(ProActive.java:585)
at org.objectweb.proactive.ProActive.newActive(ProActive.java:170)
at org.objectweb.proactive.ProActive.newActive(ProActive.java:137)
at DiscoveryManager.main(DiscoveryManager.java:226)
The problem can simply be fixed by adding bcel.jar
in the CLASSPATH
.
If you don't properly set permissions when launching code using ProActive you may get the following exception or a similar one.
java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:1099 connect,resolve)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:270)
at java.security.AccessController.checkPermission(AccessController.java:401)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:542)
at java.lang.SecurityManager.checkConnect(SecurityManager.java:1044)
at java.net.Socket.connect(Socket.java:419)
at java.net.Socket.connect(Socket.java:375)
at java.net.Socket.<init>(Socket.java:290)
at java.net.Socket.<init>(Socket.java:118)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:122)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:562)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:313)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at org.objectweb.proactive.core.rmi.RegistryHelper.detectRegistry(RegistryHelper.java:101)
at org.objectweb.proactive.core.rmi.RegistryHelper.getOrCreateRegistry(RegistryHelper.java:114)
at org.objectweb.proactive.core.rmi.RegistryHelper.initializeRegistry(RegistryHelper.java:77)
at org.objectweb.proactive.core.node.rmi.RemoteNodeFactory.(RemoteNodeFactory.java:56)
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 java.lang.Class.newInstance0(Class.java:296)
at java.lang.Class.newInstance(Class.java:249)
at org.objectweb.proactive.core.node.NodeFactory.createNodeFactory(NodeFactory.java:281)
at org.objectweb.proactive.core.node.NodeFactory.createNodeFactory(NodeFactory.java:298)
at org.objectweb.proactive.core.node.NodeFactory.getFactory(NodeFactory.java:308)
at org.objectweb.proactive.core.node.NodeFactory.createNode(NodeFactory.java:179)
at org.objectweb.proactive.core.node.NodeFactory.createNode(NodeFactory.java:158)
...
ProActive uses RMI as its underlying transport
technology. Moreover it uses code downloading features to automatically move
generated stub classes from one JVM to another one. For those reasons, ProActive
needs to install a SecurityManager
that controls the execution
of the Java code based on a set of permissions given to the JVM. Without
explicit permissions nothing is granted for the code running outside java.*
or sun.*
packages.
See Permissions in the JavaTM
2 SDK to learn more about Java permissions.
As a first approximation, in order to run your code, you can create a simple
policy file granting all permissions for all code :
grant {
permission java.security.AllPermission;
};
Then you need to start your Java program using
the property -Djava.security.policy
. For instance :
java -Djava.security.policy=my.policy.file MyMainClass
An active object is always attached to a node.
A node represents a logical entity deployed onto one JVM. When creating a
new active object you have to provide a URL or a reference to a node. That
node has to exist at the moment you create the active object. It has to be
launched on a local or on a remote JVM. In order to be accessible from any
remote JVM, a node automatically registers itself in the local RMI Registry
on the local machine. Getting a reference to a remote node ends up doing
a lookup into a RMI registry. The class NodeFactory
provides a method
getNode
for doing that.
In order to start a node you can use the script
startNode
located in the scripts
directory
in the sub-directory windows
or unix
. At the moment,
startNode
can only start a node on the local machine. It
is not possible to start a remote node using startNode. The reason is that
starting a node on a remote host implies the use of protocol such as RSH,
SSH or rLogin that are platform dependant and that cannot be easily abstracted
from java. We are working on that area at the moment with the XML-based deployment
descriptor that will allow the remote creation of nodes using various protocol.
It is nevertheless possible to create an object on a remote node once it is created. On host X you can use startNode to start a new node
startNode.sh ///node1
On host Y you can create an active object on host X
org.objectweb.proactive.core.node.Node n = fr.inria.proactive.core.node.NodeFactory.getNode("//X/node1");
ProActive.turnActive(myObject, n);
You do not need to start any rmiregistry manually as they are started automatically as needed.
As we support other ways of registration and discovery
(such as Jini), getting a node can be protocol dependant. For instance, the
url of a node jini://host.org/node
won't be accessed the same
way as rmi://host.org/node
. The class NodeFactory
is able to read
the protocol and to use the right way to access the node.
When an active object is created locally without specifying a node, it is automatically attached to a default node. The default node is created automatically by ProActive on the local JVM when a first active object is created without a given node. The name of the default node is generated based on a random number.
ProActive relies on the RMI Registry for registering and discovering nodes. For this reason, the existence of a RMI Registry is necessary for ProActive to be used. In order to simplify the deployment of ProActive applications, we have included the creation of the RMI Registry with the creation of nodes. Therefore, if no RMI Registry exists on the local machine, ProActive will automatically create one. If one exists, ProActive will automatically use it.
In the RMI model, a class server is a HTTP Server
able to answer simple HTTP requests for getting class files. It is needed
in the case an object being sent to a remote location where the class the object
belongs to is unknown. In such case, if the property java.rmi.server.codebase
has been set properly to an existing class server, RMI will attempt to download
the missing class files.
Because ProActive makes use of on-the-fly, in memory, generated classes (the stubs), a class server is necessary for each JVM using active objects. For this reason, ProActive starts automatically one small class server per JVM. The launching and the use of this class server is transparent to you.
When created, an active object is associated with a Body that is the entity managing all the non functional properties of the active object. The body contains the request queue receiving all reified method calls to the reified object (the object from which the active object has been created). It is responsible for storing pending requests and serving them according to a given synchronization policy, which default behavior is FIFO.
The body of the active object should be the only object able to access directly the reified object. All other objects accessing the active object do so through the stub-proxy couple that eventually sends a request to the body. The body owns its own thread that represent the activity of the active object.
The body has two representations. One is local
and given by the interface Body. This is the local
view of the body an object can have when being in the same JVM as the body.
For instance, the implementation of the activity of an object done through
the method runActivity(Body)
of the interface RunActive
sees the body locally as it
is instantiated by the body itself. The other representation, given by the
interface UniversalBody, is
remote. It represents the view of the body a remote object can have and therefore
the methods that can be invoked. That view is the one used by the proxy of
a remote reference to the active object to send request to the body of the
active object.
When you create an active object from a regular
object, you get in return a reference on an automatically generated ProActive
stub. ProActive uses BCEL
to generate the stub on the fly. Suppose you have a class A
and an instance a
of this class. A way to turn the instance
a
into an active object is to use the method ProActive.turnActive
:
A a = new A();
A activeA = (A) ProActive.turnActive(a);
In the code above, the variable a
is a direct reference onto the instance of A
stored somewhere
in memory. In contrast, the variable activeA
is a direct reference
onto an instance of the generated ProActive stub for the class A
.
By convention, the ProActive stub of a class A
is a class generated
in memory by ProActive that inherit from A
and that is stored
in the package pa.stub
as pa.stub.Stub_A
. The ProActive
stub of a class redefines all public methods to reify them through a generic
proxy. The proxy changes all method calls into requests that are sent to
the body associated to the reified object (the object pointed by a
in our example).
The reified object can be indifferently in the same virtual machine as the active reference or in another one.
Suppose you have a class A
with an
attribute a1
as the example below.
public class A {
public int a1;
public static void main(String[] args) {
A a = new A();
A activeA = (A) ProActive.turnActive(a);
a.a1 = 2; // set the attribute a1 of the instance pointed by a to 2
activeA.a1 = 2; // !!! set the attribute a1 of the stub instance to 2
}
}
When you reference an active object, you always reference it through its associated stub (see definition of Stub). The stub class inheriting from the reified class, it has also all its attributes. But those attributes are totally useless as the only role of the generated stub is to reify every public methods call into a request passed to the associated proxy. Therefore accessing directly the attributes of an active object through its active reference would result in accessing the attributes of the generated stub. This is certainly not the behavior one would expect.
The solution to this problem is very simple : active object's properties must be accessed through a public method. Otherwise, you're accessing the local Stub's properties.
this
and ProActive.getStubOnThis()
? Suppose you have a class A
that you
want to make active. In A
you want to have a method that returns
a reference on that instance of A
as the example below.
public class A {
public A getRef() {
return this; // !!!! THIS IS WRONG FOR AN ACTIVE OBJECT
}
}
There is indeed a problem in the code above. If
an instance of A
is created as, or turned into an active object,
the method getRef
will in fact be called through the Body
of the active object by its active thread. The value returned by the method
will be the direct reference on the reified object and not a reference on
the active object. If the call is issued from another JVM, the value will
be passed by copy and the result (assuming A is serializable) will be a deep
copy of A with no links to the active object.
The solution, if you want to pass a link to the
active object from the code of the reified object, is to use the method ProActive.getStubOnThis()
.
This method will return the reference to the stub associated to the active
object whose thread is calling the method. The correct version of the previous
class is :
public class A {
public A getRef() {
return ProActive.getStubOnThis(); // returns a reference on the stub
}
}
To create an active object you invoke one of the
methods newActive
or turnActive
of the ProActive
class. ProActive.newActive
creates an active object based on the instantiation of a new object, ProActive.turnActive
creates an active object based on an existing object. The different versions
of the same newActive
or turnActive
methods allow
you to specify where to create the active object (which node) and to customize
its activity or its body (see questions below).
Here is a simple example creating an active object
of class A
in the local JVM. If the invocation of the constructor
of class A
throws an exception, it is placed inside an exception
of type ActiveObjectCreationException
. When the call to newActive
returns, the active object has been created and its active thread is started.
public class A {
private int i;
private String s;
public A() {}
public A(int i, String s) {
this.i = i;
this.s = s;
}
}
// instance based creation
A a;
Object[] params = new Object[] { new Integer (26), "astring" };
try {
a = (A) ProActive.newActive("A", params);
} catch (ActiveObjectCreationException e) {
// creation of ActiveObject failed
e.printStackTrace();
}
// object based creation
A a = new A(26, "astring");
try {
a = (A) ProActive.turnActive(a);
} catch (ActiveObjectCreationException e) {
// creation of ActiveObject failed
e.printStackTrace();
}
In ProActive there are two ways to create
active objects. One way is to use ProActive.newActive
and is
based on the instantiation of a new object, the other is to use ProActive.turnActive
and is based on the use of an existing object.
When using instantiation based creation, any argument
passed to the constructor of the reified object through ProActive.newActive
is serialized and passed by copy to the object. This is because the model
behind ProActive is uniform whether the active object is instantiated
locally or remotely. The parameters are therefore guaranteed to be passed
by copy to the constructor. When using ProActive.newActive
you
must make sure that the arguments of the constructor are Serializable
.
On the other hand, the class used to create the active object does not
need to be Serializable
even in the case the active object
is created remotly.
When using object based creation, you create the
object that is going to be reified as an active object before hand. Therefore
there is no serialization involved when you create the object. When you invoke
ProActive.turnActive
on the object two cases are possible.
If you create the active object locally (on a local node), it will not be
serialized. If you create the active object remotely (on a remote node),
the reified object will be serialized. Therefore, if the turnActive
is done on a remote node, the class used to create the active object this
way has to be Serializable
. In addition, when using turnActive
,
care must be taken that no other references to the originating object are
kept by other objects after the call to turnActive. A direct call to a method
of the originating object without passing by a ProActive stub on this object
will break the model.
ProActive automatically creates a stub/skeleton pair for your active objects. When the stub is instancied on the remote node, its constructor ascends the ancestors chain, thus calling its parent constructor [the active object]. So if you place initialization stuff in your no args constructor, it will be executed on the stub, which can lead to disastrous results!
When an active object is created from a given object, all method calls are sent as requests to the body (automatically associated to the active object). Those requests are stored in a queue waiting to be served. Serving those requests as well as performing some other work represent the activity of this active object. One can completely specify what will be this activity. The standard behavior is to serve all incoming requests one by one in a FIFO order.
In addition to the activity, it is possible to specify what to do before the activity starts, and after it ends. The three steps are :
Three interfaces are used to define and implement each step :
In case of a migration, an active object stops and restarts its activity automatically without invoking the init or ending phases. Only the activity itself is restarted.
Two ways are possible to define each of the three phases of an active object.
newActive
or turnActive
(parameter active in those methods)Note that the methods defined by those 3 interfaces are guaranted to be called by the active thread of the active object.
The algorithms that decide for each phase what
to do are the following (activity
is the eventual object passed
as a parameter to newActive
or turnActive
) :
if activity is non null and implements InitActiveRunActive
we invoke the method initActivity defined in the object activity
else if the class of the reified object implements InitActive
we invoke the method initActivity of the reified object
else
we don't do any initialization
if activity is non null and implements RunActiveEndActive
we invoke the method runActivity defined in the object activity
else if the class of the reified object implements RunActive
we invoke the method runActivity of the reified object
else
we run the standard FIFO activity
if activity is non null and implements EndActive
we invoke the method endActivity defined in the object activity
else if the class of the reified object implements EndActive
we invoke the method endActivity of the reified object
else
we don't do any cleanup
As explained before, there are two ways to define the activity of your active object
Active
directly in the
class used to create the active objectActive
in parameter
to the method newActive
or turnActive
This is the easiest solution when you do control
the class that you make active. Depending on which phase in the life of the
active object you want to customize, you implement the corresponding interface
(one or more) amongst InitActive
,
RunActive
and EndActive
. Here is an example that has
a custom initialization and activity.
import org.objectweb.proactive.*;
public class A implements InitActive, RunActive {
private String myName;
public String getName() {
return myName;
}
// -- implements InitActive
public void initActivity(Body body) {
myName = body.getName();
}
// -- implements RunActive for serving request in a LIFO fashion
public void runActivity(Body body) {
Service service = new Service(Body);
while (body.isActive()) {
service.blockingServeYoungest();
}
}
public static void main(String[] args) throws Exception {
A a = (A) ProActive.newActive("A",null);
System.out.println("Name = "+a.getName());
}
}
This is the solution to use when you do not control
the class that you make active or when you want to write generic activities
policy and reused them with several active objects. Depending on which phase
in the life of the active object you want to customize, you implement the
corresponding interface (one or more) amongst InitActive
, RunActive
and EndActive
. Here an example that has
a custom activity.
Compared to the solution above where interfaces are directly implemented in the reified class, there is one restriction here : you cannot access the internal state of the reified object. Using an external object should therefore be used when the implementation of the activity is generic enough not to have to access the member variables of the reified object.
import org.objectweb.proactive.*;
public class LIFOActivity implements RunActive {
// -- implements RunActive for serving request in a LIFO fashion
public void runActivity(Body body) {
Service service = new Service(Body);
while (body.isActive()) {
service.blockingServeYoungest();
}
}
}
import org.objectweb.proactive.*;
public class A implements InitActive {
private String myName;
public String getName() {
return myName;
}
// -- implements InitActive
public void initActivity(Body body) {
myName = body.getName();
}
public static void main(String[] args) throws Exception {
// newActive(classname, constructor parameter (null = none),
// node (null = local), active, MetaObjectFactory (null = default)
A a = (A) ProActive.newActive("A", null, null, new LIFOActivity(), null);
System.out.println("Name = "+a.getName());
}
}
The former Active
interface was simply
a marker interface allowing to change the body and/or the proxy of an active
object. It was of no use most of the time and was made obsolete with the
introduction of the MetaObjectFactory
in the 0.9.3 release
Up to ProActive 0.9.3 the activity of an
active object was given by a method live(Body)
called by reflection
of the reified object. Doing this way didn't allow compile time type checking
of the method, was using reflection, didn't allow to externalize from the
reified object its activity, didn't allow to give a custom activity to
an active object created using turnActive
. We addressed all
those issues using the new mechanism based on the three interfaces InitActive
, RunActive
and EndActive
.
In order to convert the code of an active object
containing a method live
to the new interface you just need
to :
RunActive
(and remove Active
if it was implemented)live
to runActivity
In order to use Jini in ProActive you have to configure properly the deployment descriptor. All informations on how to configure XML deployment descriptor are provided here