Two examples are presented in this chapter: code snippets for visualizing the transition between active objects and components, and the 'hello world' from the Fractal tutorial. The programming model is Fractal/GCM, and one should refer to the Fractal documentation for more detailed examples.
In Java, objects are created by instantiation of classes. With ProActive, one can create active objects from Java classes, while components are created from component definitions. Let us first consider the 'A' interface:
public interface A {
public String bar(); // dummy method
}
'AImpl' is the class implementing this interface:
public class AImpl implements A {
Service service;
public AImpl() {
}
public String bar() {
return "bar";
}
}
The class is then instantiated in a standard way:
A object = new AImpl();
Active objects are instantiated using factory methods from the PAActiveObject class (see Chapter 6.1. Simple Computation And Monitoring Agent). It is also possible to specify the activity of the active object, the location (node or virtual node), or a factory for meta-objects, using the appropriate factory method.
A activeObject = (A) PAActiveObject.newActive(AImpl.class.getName(), // signature of the base class
new Object[] {}, // Object[]
aNode // location, could also be a virtual node
);
As components are also active objects in this implementation, they benefit from the same features and are configurable in a similar way. Constructor parameters, nodes, activity, or factories, that can be specified for active objects, are also specifiable for components. The definition of a component requires 3 sub-definitions: the type, the description of the content, and the description of the controllers.
The type of a component (i.e. the functional interfaces provided and required) is specified in a standard way: (as taken from the Fractal tutorial)
We begin by creating objects that represent the types of the application components. In order to do this, we have first to get a bootstrap component. The standard way to do this is the following one (this method creates an instance of the class specified in the gcm.provider system property or in the fractal.provider system property if the first one has not been set, and uses this instance to get the bootstrap component):
Component boot = Utils.getBootstrapComponent();
Then, we get the GCMTypeFactory interface provided by this bootstrap
component:
GCMTypeFactory tf = GCM.getGCMTypeFactory(boot);
Next, we can create the type of the first component, which only
provides a A server interface named 'a':
// type of the "a" component
ComponentType aType = tf.createFcType(new InterfaceType[] { tf.createFcItfType("a", "A", false,
false, false) });
The second step in the definition of a component is the definition
of its content. In this implementation, this is done through the
ContentDescription class:
ContentDescription contentDesc = new ContentDescription(AImpl.class.getName(), // signature of the base class
new Object[] {} // Object[]
);
Properties relative to the controllers can be specified in the
ControllerDescription:
ControllerDescription controllerDesc = new ControllerDescription("myName", // name of the component
Constants.PRIMITIVE // the hierarchical type of the component
// it could be PRIMITIVE or COMPOSITE
);
Eventually, the component definition is instantiated using the standard Fractal/GCM API. This component can then be manipulated as any other Fractal/GCM component.
PAGenericFactory componentFactory = Utils.getPAGenericFactory(boot);
Component component = componentFactory.newFcInstance(aType, // type of the component (defining the client and server interfaces)
controllerDesc, // implementation-specific description for the controller
contentDesc, // implementation-specific description for the content
aNode // location, could also be a virtual node
);
There are 2 kinds of interfaces for a component: those that offer services, and those that require services. They are named respectively server and client interfaces.
From a Java class, it is fairly natural to identify server
interfaces: they (can) correspond to the Java interfaces implemented by
the class. In the above example, 'a' is the name of an interface
provided by the component, corresponding to the A Java
interface.
On the other hand, client interfaces usually correspond to
attributes of the class, in the case of a primitive component. If the
component defined above requires a service from another component, say
the one corresponding to the Service Java interface, the AImpl class
should be modified. As we use the inversion of
control pattern, a BindingController is provided, and a
binding operation on the 'requiredService' interface will actually set
the value of the 'service' attribute, of type Service.
First, the type of the component is changed:
// type of the "a" component
ComponentType aType = tf.createFcType(new InterfaceType[] {
tf.createFcItfType("a", "A", false, false, false),
tf.createFcItfType("requiredService", "A", true, false, false) });
The Service interface is the following one:
package org.objectweb.proactive.examples.components.helloworld;
public interface Service {
void print(String msg);
}
And the AImpl class is:
public class AImpl implements A {
Service service;
public AImpl() {
}
// implementation of the A interface
public void foo() {
service.print("Hello World"); // for example
}
// implementation of BindingController
public Object lookupFc(final String cItf) {
if (cItf.equals("requiredService")) {
return service;
}
return null;
}
// implementation of BindingController
public void bindFc(final String cItf, final Object sItf) {
if (cItf.equals("requiredService")) {
service = (Service) sItf;
}
}
// implementation of BindingController
public void unbindFc(final String cItf) {
if (cItf.equals("requiredService")) {
service = null;
}
}
}
The mandatory helloworld example (from the Fractal tutorial) shows the different ways of creating a component system (programmatically and using the ADL), and it can easily be implemented using ProActive.
You can find the code for this example in the package
org.objectweb.proactive.examples.components.helloworld in the ProActive
distribution.
The code is almost identical to the Fractal tutorial's example.
The differences are the following:
The reference example is provided for level 3.3 implementation, whereas this current implementation is compliant up to level 3.2: templates are not provided. Thus, you will have to skip the specific code for templates.
The newFcInstance method of the
GenericFactory interface, used for directly
creating components, takes 2 implementation-specific parameters. So
you should use the
org.objectweb.proactive.component.ControllerDescription
and
org.objectweb.proactive.component.ContentDescription
classes to define ProActive/GCM components. (It is possible to use the
same parameters than in Julia, but that hinders you from using some
functionalities specific to ProActive, such as distributed
deployment or definition of the activity).
Components can be distributed
the ClientImpl provides an empty no-args constructor.
The helloworld example is a simple client-server application, where the client (c) and the server (s) are components, and they are both contained in the same root component (root).
Another configuration is also possible, where client and server are wrapped around composite components (C and S).
This section is specific to the ProActive/GCM implementation, as it uses the deployment framework of this library.
If the application is started with (only) the parameter 'distributed', the ADL used is 'helloworld-distributed-no-wrappers.fractal', where virtualNode of the client and server components are exported as VN1 and VN2. Exported virtual node names from the ADL match those defined in the deployment descriptor 'deployment.xml'.
One can of course customize the deployment descriptor and deploy components onto virtually any computer, provided it is connectable by supported protocols. Supported protocols include LAN, clusters and Grid protocols (see Chapter 15. XML Deployment Descriptors).
![]() |
Note |
|---|---|
|
This example has been written using the old deployment descriptors. However, it is obviously possible (and recommended) to write it using the new GCM Deployment descriptors. Besides, this examples will probably be updated with the new deployment version in the future. |
Have a look at the ADL files 'helloworld-distributed-no-wrappers.fractal' and 'helloworld-distributed-wrappers.fractal'. In a nutshell, they say: 'the primitive components of the application (client and server) will run on given exported virtual nodes, whereas the other components (wrappers, root component) will run on the current JVM.
Therefore, we have the two following configurations:
By default, bindings are not optimized. For example, in the configuration with wrappers, there is an indirection that can be costly, between the client and the server. However, optimizations allow to shortcut communications, while still allowing coherent dynamic reconfiguration. It is the same idea than in Julia, but we are dealing here with distributed components. For further information about optimizations, please refer to Section 4.5.6, “Short cuts”.
You can either compile and run the code yourself, or follow the
instructions for preparing the examples and use the script
helloworld_fractal.sh (or .bat). If you choose the first solution, do
not forget to set the gcm.provider system property
(or the fractal.provider system property).
If you run the program with no arguments (i.e. not using the parser, no wrapper composite components, and local deployment) , you should get something like this:
1: --- Fractal Helloworld example --------------------------------------------- 2: --- 3: --- The expected result is an exception 4: --- 5: 6: [INFO communication.rmi] Created a new registry on port 6646 7: [INFO proactive.mop] Generating class : 8: pa.stub.org.objectweb.proactive.core.component.type._StubComposite 9: [INFO proactive.mop] Generating class : 10: pa.stub.org.objectweb.proactive.core.jmx.util._StubJMXNotificationListener 11: [INFO proactive.mop] Generating class : 12: pa.stub.org.objectweb.proactive.examples.components.helloworld._StubClientImpl 13: [INFO proactive.mop] Generating class : 14: pa.stub.org.objectweb.proactive.examples.components.helloworld._StubServerImpl
You can see:
line 6: the creation of a rmi registry
line 7 to 14: the on-the-fly generation of ProActive stubs (the generation of component functional interfaces is silent)
Then you have (the exception that pops out is actually the expected result, and is intended to show the execution path):
1:Server: print method called 2:at org.objectweb.proactive.examples.components.helloworld.ServerImpl.print(ServerImpl.java:45) 3:at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 4:at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 5:at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 6:at java.lang.reflect.Method.invoke(Method.java:597) 7:at org.objectweb.proactive.core.mop.MethodCall.execute(MethodCall.java:390) 8:at 9: org.objectweb.proactive.core.component.request.ComponentRequestImpl. 10: serveInternal(ComponentRequestImpl.java:176) 11:at org.objectweb.proactive.core.body.request.RequestImpl.serve(RequestImpl.java:170) 12:at 13: org.objectweb.proactive.core.body.BodyImpl$ActiveLocalBodyStrategy. 14: serveInternal(BodyImpl.java:539) 15:at org.objectweb.proactive.core.body.BodyImpl$ActiveLocalBodyStrategy.serve(BodyImpl.java:510) 16:at org.objectweb.proactive.core.body.AbstractBody.serve(AbstractBody.java:909) 17:at org.objectweb.proactive.Service.blockingServeOldest(Service.java:175) 18:at org.objectweb.proactive.Service.blockingServeOldest(Service.java:150) 19:at org.objectweb.proactive.Service.fifoServing(Service.java:126) 20:at 21: org.objectweb.proactive.core.component.body.ComponentActivity$ComponentFIFORunActive. 22: runActivity(ComponentActivity.java:226) 23:at 24: org.objectweb.proactive.core.component.body.ComponentActivity. 25: runActivity(ComponentActivity.java:183) 26:at 27: org.objectweb.proactive.core.component.body.ComponentActivity. 28: runActivity(ComponentActivity.java:183) 29:at org.objectweb.proactive.core.body.ActiveBody.run(ActiveBody.java:192) 30:at java.lang.Thread.run(Thread.java:619) 31:Server: begin printing... 32:--------> hello world 33:Server: print done.c
What can be seen is very different from the output you would get with the Julia implementation. Here is what happens (from bottom to top of the stack):
line 30: The active object runs its activity in its own Thread
line 20-21-22: The default activity is to serve incoming request in a FIFO order
line 8-9-10: Requests (reified method calls) are encapsulated in ComponentRequestImpl objects
line 6: A request is served using reflection
line 2: The method invoked is the print method of an instance of ServerImpl
Now let us have a look at the distributed deployment: execute the program with the parameters 'distributed parser'. You should get something similar to the following:
1: --- Fractal Helloworld example --------------------------------------------- 2: --- 3: --- The expected result is an exception 4: --- 5: 6: [INFO communication.rmi] Created a new registry on port 6646 7: [INFO proactive] ************* Reading deployment descriptor: 8: file:/home/ProActive/classes/Examples/org/objectweb/proactive/examples/components/ 9: helloworld/deployment.xml ******************** 10: [INFO proactive.deployment] created VirtualNode name=VN1 11: [INFO proactive.deployment] created VirtualNode name=VN2 12: [INFO proactive.deployment] created VirtualNode name=VN3 13: [INFO proactive.mop] Generating class : 14: pa.stub.org.objectweb.proactive.core.jmx.util._StubJMXNotificationListener 15: [INFO deployment.log] 16: [INFO deployment.log] 311@saturn.inria.fr - 17: [INFO proactive.runtime] **** Starting jvm on 138.96.218.113 18: [INFO proactive.events] **** Mapping VirtualNode VN1 with Node: 19: rmi://138.96.218.113:6646/VN11559562212 done 20: [INFO proactive.mop] Generating class : 21: pa.stub.org.objectweb.proactive.examples.components.helloworld._StubClientImpl 22: [INFO deployment.log] 311@saturn.inria.fr - 23: [INFO communication.rmi] Detected an existing RMI Registry on port 6646 24: [INFO deployment.log] 25: [INFO deployment.log] 97714@saturn.inria.fr - 26: [INFO proactive.runtime] **** Starting jvm on 138.96.218.113 27: [INFO proactive.events] **** Mapping VirtualNode VN2 with Node: 28: rmi://138.96.218.113:6646/VN2914088183 done 29: [INFO proactive.mop] Generating class : 30: pa.stub.org.objectweb.proactive.examples.components.helloworld._StubServerImpl 31: [INFO deployment.log] 97714@saturn.inria.fr - [INFO communication.rmi] Detected an existing RMI Registry on port 6646 32: [INFO proactive.mop] Generating class : 33: pa.stub.org.objectweb.proactive.core.component.type._StubComposite
What is new is:
line 7-8-9: the parsing of the deployment descriptor
line 16-17 and 25-26: the creation of 2 virtual machines on the host 'saturn.inria.fr'
line 10-11-12: the creation of virtual nodes VN1, VN2 and VN3
line 18-19 and 27-28: the mapping of virtual nodes VN1 and VN2 to the nodes specified in the deployment descriptor
Then, we get the same output as for a local deployment, the activity of active objects is independent from its location.
1: [INFO deployment.log] Server: print method called 2: [INFO deployment.log] at 3: org.objectweb.proactive.examples.components.helloworld.ServerImpl.print(ServerImpl.java:45) 4: [INFO deployment.log] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 5: [INFO deployment.log] at 6: sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 7: [INFO deployment.log] at 8: sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 9: [INFO deployment.log] at java.lang.reflect.Method.invoke(Method.java:597) 10: [INFO deployment.log] at org.objectweb.proactive.core.mop.MethodCall.execute(MethodCall.java:390) 11: [INFO deployment.log] at 12: org.objectweb.proactive.core.component.request.ComponentRequestImpl. 13: serveInternal(ComponentRequestImpl.java:176) 14: [INFO deployment.log] at 15: org.objectweb.proactive.core.body.request.RequestImpl.serve(RequestImpl.java:170) 16: [INFO deployment.log] at 17: org.objectweb.proactive.core.body.BodyImpl$ActiveLocalBodyStrategy. 18: serveInternal(BodyImpl.java:539) 19: [INFO deployment.log] at 20: org.objectweb.proactive.core.body.BodyImpl$ActiveLocalBodyStrategy.serve(BodyImpl.java:510) 21: [INFO deployment.log] at 22: org.objectweb.proactive.core.body.AbstractBody.serve(AbstractBody.java:909) 23: [INFO deployment.log] at org.objectweb.proactive.Service.blockingServeOldest(Service.java:175) 24: [INFO deployment.log] at org.objectweb.proactive.Service.blockingServeOldest(Service.java:150) 25: [INFO deployment.log] at org.objectweb.proactive.Service.fifoServing(Service.java:126) 26: [INFO deployment.log] at 27: org.objectweb.proactive.core.component.body.ComponentActivity$ComponentFIFORunActive. 28: runActivity(ComponentActivity.java:226) 29: [INFO deployment.log] at 30: org.objectweb.proactive.core.component.body.ComponentActivity. 31: runActivity(ComponentActivity.java:183) 32: [INFO deployment.log] at 33: org.objectweb.proactive.core.component.body.ComponentActivity. 34: runActivity(ComponentActivity.java:183) 35: [INFO deployment.log] at org.objectweb.proactive.core.body.ActiveBody.run(ActiveBody.java:192) 36: [INFO deployment.log] at java.lang.Thread.run(Thread.java:619) 37: [INFO deployment.log] Server: begin printing... 38: [INFO deployment.log] ->hello world 39: [INFO deployment.log] Server: print done. 40:---------------------------------------------------------
org.objectweb.proactive.examples.components.helloworld.helloworld-distributed-wrappers:
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd"> <definition name="org.objectweb.proactive.examples.components.helloworld.helloworld-distributed-wrappers"> <interface name="r" role="server" signature="java.lang.Runnable"/> <!-- @snippet-start exported_virtual_node_1 --> <exportedVirtualNodes> <exportedVirtualNode name="VN1"> <composedFrom> <composingVirtualNode component="client" name="client-node"/> </composedFrom> </exportedVirtualNode> <exportedVirtualNode name="VN2"> <composedFrom> <composingVirtualNode component="server" name="server-node"/> </composedFrom> </exportedVirtualNode> </exportedVirtualNodes> <!-- @snippet-end exported_virtual_node_1 --> <component name="client-wrapper" definition="org.objectweb.proactive.examples.components.helloworld.ClientType"> <component name="client" definition="org.objectweb.proactive.examples.components.helloworld.ClientImpl"/> <binding client="this.r" server="client.r"/> <binding client="client.s" server="this.s"/> <controller desc="composite"/> </component> <component name="server-wrapper" definition="org.objectweb.proactive.examples.components.helloworld.ServerType"> <component name="server" definition="org.objectweb.proactive.examples.components.helloworld.ServerImpl"/> <binding client="this.s" server="server.s"/> <controller desc="composite"/> </component> <binding client="this.r" server="client-wrapper.r"/> <binding client="client-wrapper.s" server="server-wrapper.s"/> </definition>
org.objectweb.proactive.examples.components.helloworld.ClientType:
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd"> <definition name="org.objectweb.proactive.examples.components.helloworld.ClientType" extends="org.objectweb.proactive.examples.components.helloworld.RootType"> <interface name="r" role="server" signature="java.lang.Runnable"/> <interface name="s" role="client" signature="org.objectweb.proactive.examples.components.helloworld.Service"/> </definition>
org.objectweb.proactive.examples.components.helloworld.ClientImpl:
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd"> <definition name="org.objectweb.proactive.examples.components.helloworld.ClientImpl" extends="org.objectweb.proactive.examples.components.helloworld.ClientType"> <!-- @snippet-start exported_virtual_node_2 --> <exportedVirtualNodes> <exportedVirtualNode name="client-node"> <composedFrom> <composingVirtualNode component="this" name="client-node"/> </composedFrom> </exportedVirtualNode> </exportedVirtualNodes> <!-- @snippet-break exported_virtual_node_2 --> <content class="org.objectweb.proactive.examples.components.helloworld.ClientImpl"/> <!-- @snippet-resume exported_virtual_node_2 --> <virtual-node name="client-node"/> <!-- @snippet-end exported_virtual_node_2 --> </definition>
org.objectweb.proactive.examples.components.helloworld.ServerType:
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd"> <definition name="org.objectweb.proactive.examples.components.helloworld.ServerType"> <interface name="s" role="server" signature="org.objectweb.proactive.examples.components.helloworld.Service"/> </definition>
org.objectweb.proactive.examples.components.helloworld.ServerImpl:
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd"> <definition name="org.objectweb.proactive.examples.components.helloworld.ServerImpl" extends="org.objectweb.proactive.examples.components.helloworld.ServerType"> <exportedVirtualNodes> <exportedVirtualNode name="server-node"> <composedFrom> <composingVirtualNode component="this" name="server-node"/> </composedFrom> </exportedVirtualNode> </exportedVirtualNodes> <content class="org.objectweb.proactive.examples.components.helloworld.ServerImpl"/> <attributes signature="org.objectweb.proactive.examples.components.helloworld.ServiceAttributes"> <attribute name="header" value="->"/> <attribute name="count" value="1"/> </attributes> <controller desc="primitive"/> <virtual-node name="server-node"/> </definition>
© 1997-2010 INRIA/University of Nice-Sophia Antipolis/ActiveEon All Rights Reserved