Performing Grid Computing from an Application Server
The goal of this Article is to show a use case of delegating the computation performed within a J2EE Application Server (Jboss is used in this article) by connecting an EJB3 application to a grid computing open source technology (ProActive Scheduler). This is very useful in case of applications that require computational intensive algorithms for responding to a user request. See the picture bellow.

Organization of The Article/Tutorial
Part ONE: Write a very simple EJB application
In the first part, we will create a simple EJB application composed by one single session bean that exposes e method for counting the number of divisors of a number n.
Part TWO: Use ProActive Scheduler to perform the computation on a grid
In this part we will show how to connect to the ProActive Scheduler, split input data and create tasks, create a job wich contains the tasks and submit it to the scheduler, merge the results of the computation and send the final result to the user.
The tutorial includes the installation steps of the required (open source) software (Jboss server, ProActive Scheduler, Eclipse ).

The Target Application
We will implement a simple application that computes the number of divisors of a (big) integer number.
Install and Configuration
- Download Eclipse Ganymede (the package “Eclipse IDE for Java EE Developers”) from http://www.eclipse.org/downloads/packages/ and extract it into a local folder. Lets call it ECLIPSE_HOME
- Download JBOSS Server (I used the version 4.2.3 GA) from http://www.jboss.org/jbossas/downloads and extract into a local folder (lets call it JBOSS_HOME)
- Download the ProActive Scheduler product from http://www.activeeon.com/community-downloads (I used the 4.0 version) and put it in a folder (lets call it SCHEDULER_HOME)
Note: It is recommended that folders that contain JBoss and ProActive do not contain spaces.
Note: If you want to start the JBoss server from eclipse, into Eclipse Workbench go to “Servers View” → right click → New→ Server; Choose Jboss → the version your are using (v.4.2 for me) → Next → Provide application server directory (browse to your JBOSS_HOME folder) → Finish
Part ONE: Write a very simple EJB3 application
We will now write a simple EJB3 application (compound of only one session bean), deploy it on the server and use a client application to send a request to the bean. Let’s write an application that counts the number of divisors of a number n. In the Eclipse workspace, create a new simple java project called DivisorCounterEJB
Import jars from Jboss
Go to Project → Properties → Java Build Path → Libraries and click on Add External Jars. Navigate to JBOSSS_HOME/server/default/lib and import the jars:
- ejb3-persistence.jar
- jboss-ejb3x.jar
Creation of the interface
Create a new interface in your project
- Package: com.activeeon.demos.ejb.divisors
- Interface Name: DivisorCounter
We will annotate the interface with the @javax.ejb.Remote annotation and define our business method countDivisors(BigInteger n)
The code of the interface is:
package com.activeeon.demos.ejb.divisors; import java.math.BigInteger; import javax.ejb.ApplicationException; @javax.ejb.Remote public interface DivisorCounter { public long countDivisors(BigInteger n); }
Creation of the Bean
Create a new class:
- package: com.activeeon.demos.ejb.divisors
- class name: DivisorCounterBean
The class implements the interface DivisorCounter We will annotate the class with @Stateleful. (Stateless version works as well, see notes at the end of the article) We have to implement the method countDivisors. For now we will compute the number of divisors sequentially, in this method. In the second part of this article, we will perform the computation on a grid. The code we obtain is:
package com.activeeon.demos.ejb.divisors; import java.math.BigInteger; import javax.ejb.Stateful; @Stateful public class DivisorCounterBean implements DivisorCounter{ @Override public long countDivisors(BigInteger n) { long divisors = 0; System.out.println("New request received for counting divisor for number "+n.toString()); for (BigInteger i = new BigInteger("1"); i.compareTo(n.divide(new BigInteger("2")))<=0; i=i.add(new BigInteger("1"))) { if (n.remainder(i).equals(BigInteger.ZERO)) divisors++; } //we add the last divisor which is n itself divisors+=1; return divisors; } }
Generating the JAR file and deploying the Bean on the JBoss Server:
We will have to generate the jar file of our application and deploy it on the application server. In the Eclipse Workbench, go to File → Export → Java→ Jar File Choose the project DivisorCounterEJB. Choose the name of the jar file DivisorCounter.jar and the location JBOSS_HOME/servers/default/deploy If your jboss server is not yet running, you can start it (from Eclipse go to Java EE perspective, Servers View, start server). You should see on the output of the JBoss Serever the lines:
12:58:16,702 INFO [JmxKernelAbstraction] installing MBean: jboss.j2ee:jar=DivisorCounter.jar,name=DivisorCounterBean,service=EJB3 with dependencies: 12:58:16,732 INFO [EJBContainer] STARTED EJB: com.activeeon.demos.ejb.divisors.DivisorCounterBean ejbName: DivisorCounterBean 12:58:16,779 INFO [EJB3Deployer] Deployed: file:/home/esalagea/ActiveEon/articles/SchedulerAndJboss/jboss-4.2.3.GA/server/default/deploy/DivisorCounter.jar
Your bean is deployed on the server and ready to be used.
Creating a client Application:
-
Create a new Java Project called DivisorCounterClient.
-
Add the external jars Jnp-client.jar and Jbossall-client.jar from JBOSS_HOME/client (go to Properties, Java Build Path → Add External Jars → …)
-
We also need to add the jar file of the previous (EJB) application. Go to Add External Jars and navigate to JBOSS_HOME/server/default/deploy/DivisorCounter.jar
-
Now add a JNDI file to your client project. Create a (text) file callled jndi.properties. At running time this file should be found in the root of the bin folder of your project (you could put the file in the root of the src folder in order to be copied, at compile time, in the bin folder) The content of the file is:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces java.naming.provider.url=localhost
Now, let’s write the client class. The client should connect to the
bean application and send a request in order to obtain the number of
divisors of a number n. The content of the class is:
package com.activeeon.demos.ejb.divisors.client; import java.math.BigInteger; import javax.naming.InitialContext; import javax.naming.NamingException; import com.activeeon.demos.ejb.divisors.DivisorCounter; public class DivisorCounterTester { public static BigInteger bi = new BigInteger("123456789"); public static void main (String args[]) throws NamingException { InitialContext ctx = new InitialContext(); DivisorCounter calculator = (DivisorCounter) ctx.lookup("DivisorCounterBean/remote"); System.out.println("Beginning computation in sequential version"); long beginTime = System.currentTimeMillis(); long d= calculator.countDivisors(bi); long endTime = System.currentTimeMillis(); System.out.println(d+" divisors have been found"); System.out.println("Answer have been received after "+(endTime-beginTime)+ " milliseconds. "); System.out.println("*****************\n"); } }
Run the client application
On my machine, the output of the client is:
Beginning computation. 12 divisors have been found Answer have been received after 33570 milliseconds.
Part TWO: Use ProActive Scheduler to perform the computation on a grid.
Note: We will start by performing the computation on several JVMs on localhost. Then, if you have some available machines, you can use those ones in order to perform the computation.
I assume you have downloaded the last version of the ProActive Scheduler in the SCHEDULER_HOME folder. (for me this folder is “/home/ProActiveScheduler” )
Note: we will go on with the implementation and start the scheduler server later.
Add ProActive jars
Lets go back to our DivisorCounterEJB project and modify our bean to make it delegate the computation on the grid. First, we add jars for the ProActive Scheduler. As we want to deploy these jars on the JBoss server we will copy them in a lib folder of our project. Create a new Folder called “lib” in the DivisorCounterEJB project. Use your system navigator to navigate to the SCHEDULER_HOME/dist/lib folder. Select and copy the files: bouncycastle.jar,fractal-adl.jar,fractal.jar,javassist.jar, log4j.jar, ProActive_resource-manager.jar, ProActive_scheduler.jar, ProActive.jar. Then go back to the Eclipse Workbench and paste these files into the previously created “lib” folder. Now import these jars into the project (Properties → Java Build Path → Add Jars and select all the jars from the “lib” folder)
Modify the class DivisorCounterBean
First, we have to establish a connection to the Scheduler. Note that the Scheduler will accept one connection per Thread (this is due to the ProActive ActiveObjects programming pattern). As JBoss will reuse the threads we will have to keep a static variable that contain a mapping between the threads and the connections to the Scheduler. We also add three static variables containing the url of the scheduler, username and password. Lets add the next lines to the DivisorCounterBean class:
public final static String schedulerURL ="//192.168.1.10"; public final static String schedulerUserName = "user1"; public final static String userPassword="pwd1"; private static int numberOfTasks = 4; public UserSchedulerInterface schedulerUI=null; public SchedulerAuthenticationInterface schedulerAuth=null; public static HashMap<Long, UserSchedulerInterface> connections=new HashMap<Long, UserSchedulerInterface>();
We will use the schedulerUI and schedulerAuth objects in order to connect to the Scheduler and submit a job.
Connect to the scheduler
We will start by writing a private method to connect to the scheduler.
Important Note: This is is the trickiest thing in this tutorial. First, we need to keep in mind that we need to connect to the ProActive Scheduler and therefore we are now in a ProActive programming model context. the ProActive Scheduler accepts only one connection per caller Thread (this is because the Scheduler accepts one connection per ActiveObject caller, plase see the ProActive programming model if you want to have a deeper understanding of all this). On the other hand, JBoss uses a thread pool in order to serve user requests. So, if at one point, I want to know if my session bean is connected to the Scheduler, I actually need to check if the current Thread has a connection to the Scheduler. I know it sounds complicated but it isn’t ..
As we need to keep one connection per Thread we will start by verifying if the current thread already has a connection attached, and, if not, create one and ad an entry in the connections HashMap. The method we obtain is:
private void connectToScheduler() throws SchedulerException, LoginException { long threadId = Thread.currentThread().getId(); schedulerUI = DivisorCounterBean.connections.get(new Long(threadId)); if (schedulerUI!=null) { System.out.println("already logged in"); return; } else { schedulerAuth = SchedulerConnection.join(schedulerURL); schedulerUI = schedulerAuth.logAsUser(schedulerUserName, userPassword); DivisorCounterBean.connections.put(new Long(threadId), schedulerUI); System.out.println("new Connection to the schdeuler has been created. Nb of connections: "+connections.size()); } }
Add ejbCreate() method
We want to connect to the scheduler when the bean is created. We’ll just add a method called ejbCreate() that we annotate with @javax.ejb.Init in which we call the connectToScheduler() method. The method looks like this:
@javax.ejb.Init public void ejbCreate() { System.out.println("Creation of DivicorCounterBean. "); try{ connectToScheduler(); } catch (Exception e) { e.printStackTrace(); } }
We have connected our bean to the scheduler, we only need now to split
the data, create the Tasks which count the number of divisors, send
them to the Scheduler and addition the results.
Implement the Task class
Lets start by implementing the Task code. A task will take in argument the number n for which we are counting divisors and interval in which we are looking for divisors, given by its lower and upper bounds. A Scheduler Task will have its input data in a HashMap of arguments. The execute method can take as input a list of results of the Tasks on which this task depends on, but, as our tasks don’t have dependencies, this list will always be empty. Furthermore, the code for the Task class it is easy to understand. Here it is:
package com.activeeon.demos.ejb.divisors; import java.math.BigInteger; import org.objectweb.proactive.core.util.wrapper.StringWrapper; import org.ow2.proactive.scheduler.common.task.TaskResult; public class DivisorsTask extends org.ow2.proactive.scheduler.common.task.executable.JavaExecutable{ @Override public Serializable execute(TaskResult... arg0) throws Throwable { String lowerBoundString = this.getArgs().get("LowerBound"); BigInteger lowerBound = new BigInteger(lowerBoundString); //BigInteger fromNumbber = new BigInteger(from); String upperBoundString = this.getArgs().get("UpperBound"); BigInteger upperBound = new BigInteger(upperBoundString); String n = this.getArgs().get("n"); BigInteger nNumber = new BigInteger(n); long divisors = 0; for (BigInteger i = lowerBound; i.compareTo(upperBound)<=0; i=i.add(new BigInteger("1"))) { if (nNumber.remainder(i).equals(BigInteger.ZERO)) divisors++; } String s = (new Long(divisors)).toString(); StringWrapper sw = new StringWrapper(s); return sw; } }
Our bean is almost finished. We only need to create a job (which is formed of tasks) and submit it to the Scheduler.
Lets first add to our com.activeeon.demos.ejb.divisors.DivisorCounter interface a method
public long distributedCountDivisors(BigInteger n);
We will create a TaskFlowJob (which is a job that can contain one or more task(s) ), will add tasks to this job and then submit it to the scheduler.
Implement the distributedCountDivisors method
- job creation
TaskFlowJob job = new TaskFlowJob(); job.setName("DivisorCounter"); //if error occur on one task, should we cancel the job? job.setCancelOnError(true); job.setDescription("Job sent from an EJB application deployed on JBoss v4.2 AS");
- classpath
As we need to execute the code in the DivisorTask class that we
previously wrote, we need to have this class on the remote machines (on
the nodes). We need so, either to provide a classpath containing the
DivisorTask class when starting the nodes, either to provide this
classpath to the job by using a JobEnvironment object. This is done by
these lines:
String appClassPath = ""; try { File appMainFolder = new File(DivisorCounterBean.class .getProtectionDomain().getCodeSource().getLocation() .toURI()); appClassPath = appMainFolder.getAbsolutePath(); } catch (URISyntaxException e1) { System.out .println("An exception has occured while setting the job classpath."); e1.printStackTrace(); } JobEnvironment je = new JobEnvironment(); je.setJobClasspath(new String[] { appClassPath }); job.setEnv(je);
- creation of the tasks
We will create m intervals in which we will be counting the divisors of the number n. To do so, we will split the interval (2, n/2+1) into m intervals (where m = numberOfTasks, statically defined), and provide one interval to each Task. An interval is defined by its lower bound and its upper bound. Our tasks will receive then 3 arguments: lower bound, upper bound and the number n. For two values lower bound and upper bound already computed, the code which creates the task is:
JavaTask jt = new JavaTask(); jt.setName("Divisors Task "+i); jt.setDescription("Count divisors of number "+n.toString()+" within the interval ("+lowerBound.toString()+" , "+upperBound.toString()+")"); jt.addArgument("LowerBound",lowerBound.toString()); jt.addArgument("UpperBound", upperBound.toString()); jt.addArgument("n", n.toString()); jt.setPreciousResult(true); jt.setExecutableClassName(DivisorsTask.class.getName()); job.addTask(jt);
- submit the job to the scheduler and wait for the results
Once the job is submitted, we only have to wait for the results, addition them when arrived and send the final result to the client.
Note: In this implementation we will just keep waiting (perform a Thread sleep) and ask the scheduler every n milliseconds if the result is available. A better solution would be to subscribe a listener to the Scheduler in order to be notified, by the Scheduler, when the result is available. See the Advanced section at the end of this article.
The code of the method is:
public long distributedCountDivisors(BigInteger n) { if (schedulerUI == null) { try { connectToScheduler(); } catch (LoginException e) { // TODO Auto-generated catch block e.printStackTrace(); return 0; } catch (SchedulerException e) { // TODO Auto-generated catch block e.printStackTrace(); return 0; } } long nbOfDivisors = 0; try { TaskFlowJob job = new TaskFlowJob(); job.setName("DivisorCounter"); // if error occur on one task, should we cancel the job? job.setCancelOnError(true); job .setDescription("Job sent from an EJB application deployed on JBoss v4.2 AS"); // handle classpath String appClassPath = ""; try { File appMainFolder = new File(DivisorCounterBean.class .getProtectionDomain().getCodeSource().getLocation() .toURI()); appClassPath = appMainFolder.getAbsolutePath(); } catch (URISyntaxException e1) { System.out .println("An exception has occured while setting the job classpath."); e1.printStackTrace(); } JobEnvironment je = new JobEnvironment(); je.setJobClasspath(new String[] { appClassPath }); job.setEnv(je); BigInteger halfN = n.divide(new BigInteger("2")) .add(BigInteger.ONE); BigInteger intervalSize = halfN.divide(new BigInteger(new Integer( DivisorCounterBean.numberOfTasks - 1).toString())); BigInteger lowerBound; BigInteger upperBound; for (int i = 0; i < DivisorCounterBean.numberOfTasks; i++) { lowerBound = intervalSize.multiply( new BigInteger(new Integer(i).toString())).add( BigInteger.ONE); upperBound = lowerBound.add(intervalSize .subtract(BigInteger.ONE)); // for the last interval if (upperBound.compareTo(halfN) > 0) { upperBound = halfN; } // Creating the Divisors Task for the interval (upperBound, // lowerBound) JavaTask jt = new JavaTask(); jt.setName("Divisors Task " + i); jt.setDescription("Count divisors of number " + n.toString() + " within the interval (" + lowerBound.toString() + " , " + upperBound.toString() + ")"); jt.addArgument("LowerBound", lowerBound.toString()); jt.addArgument("UpperBound", upperBound.toString()); jt.addArgument("n", n.toString()); jt.setPreciousResult(true); jt.setExecutableClassName(DivisorsTask.class.getName()); job.addTask(jt); } JobId jobId = schedulerUI.submit(job); System.out.println("The Job has been submited to the scheduler."); JobResult jResult = null; boolean keepWaiting = true; while (keepWaiting && (jResult == null)) { try { Thread.sleep(500); jResult = schedulerUI.getJobResult(jobId); } catch (SchedulerException se) { keepWaiting = false; se.printStackTrace(); return 0; } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("The results of the job are: " + jResult); HashMap<String, TaskResult> results = jResult.getAllResults(); for (TaskResult t : results.values()) { String rs = ((StringWrapper) t.value()).toString(); int r = new Integer(rs).intValue(); nbOfDivisors += r; } // we add n as divisor of n nbOfDivisors++; } catch (Exception e) { e.printStackTrace(); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } return nbOfDivisors; }
Call the distributed method from the client
Lets call, from the client, the 2 methods (the sequential one and distributed one, in order to compare the computation times) Add the next lines to the main method oof the DivisorCounterTester class in the DivisorCounterClient project:
System.out.println("Begining computation in distributed version"); beginTime = System.currentTimeMillis(); d= calculator.distributedCountDivisors(bi); endTime = System.currentTimeMillis(); System.out.println(d+" divisors have been found"); System.out.println("Answer have been received after "+(endTime-beginTime)+ " milliseconds. "); System.out.println("*****************/n");
Note: your client might not compile now because it does not now the distributedCountDivisors method. Just export again the DivisorCounterEJB project as a jar and import it again in the client project.
Start the scheduler and run your application
Important Note: before you do this, you should change the Proactive default rmi port in order not to have a conflict with JBoss port.
In your root folder you should have a folder called “.proactive” . Go inside and edit the file called ProActiveConfiguration.xml. Look for the line which defines the property “proactive.rmi.port” and change its value (1099 by default). In my case I put it to 1605 (it’s my credit card pin code
)
Proactive Scheduler relies on a Resource Manager server.
- Start the Resource manager:
Open a command console and navigate to SCHEDULER_HOME/bin/unix (../windows if you are working on a windows system). Type ./startRM.sh (startRM.bat for windows) The Resource Manager will start and will deploy, by default, 4 nodes (jvm’s) on the localhost.
-
Start the scheduler
Open a new command console and navigate to SCHEDULER_HOME/bin/unix (../windows) Only for the first time your are launching the scheduler, you have to create its database (which contains information about jobs, their tasks, results, etc..) Type: startScheduler_newDB.sh (.. bat for windows) This will create the database and start the scheduler which will connect to the resource manager in order to obtain resources and deploy tasks.
- Start the JBoss server
Important Note add this property to the jboss launcher: -Dlog4j.configuration=JBOSS_HOME/default/conf/jboss-log4j.xml
./run.sh -Dlog4j.configuration=JBOSS_HOME/default/conf/jboss-log4j.xml
You have to do this in order to force ProActive use the log4j.configuration
file of JBoss (in order not to have logger conflicts in the JBoss JVM).
- Run your client application.
On my machine the output of the client is:
Beginning computation in sequential version 12 divisors have been found Answer have been received after 35638 milliseconds. *****************
Beginning computation in distributed version 12 divisors have been found Answer have been received after 18980 milliseconds. *****************
This is it, if you followed me until this point, you have your session bean which delegates the computation on a set of JVMs. I only have few words to add about adding remote resources (nodes), starting the Scheduler itself on a remote machine, using the GUI for administration of the Scheduler and Resource manager.
Additional Information
Scheduler and Resource Manager Administration
-
First start the Resource Manager administration GUI. Right Click → connect to Resource Manager.
You should see now the four JVMs that have been deployed by default on your machine.
-
Now start the Scheduler administration GUI. Right Click → connect to scheduler ..
-
Relaunch your application
You can remove, if you want to, from the client, the call to the sequential method. You should see that, on the Resource Manager GUI some of the resources are marked as “occupied” (yellow), and, on the Scheduler Administration GUI you can see your job running.
Add remote resources
Connect to another machine of your network. Open a command console and navigate to SCHEDULER_HOME/bin folder Type ./startNode.sh myNode The ProActive Runtime (jvm, node) is launched and the url of the node is printed at stdout. Go to the Resource Manager, right click → Add node(s) and type the url of the node you have just started. (you can also remove one node from the localhost). You can rerun your client application now.
Running the scheduler and resource manager on remote machines
You can start the resource manager on a machine M1 and the scheduler on a machine M2. When you start the Scheduler, make sure you give the good url of the Resource Manager in argument (option -u //IpOfM2). Then modify the schedulerURL static variable in the DivisorCounterBean class with the ip of the machine M2. Export again the jar file of your application. Stop the JBoss server. When you start the JBoss server pass as argument “–host ip” where ip is the ip of your machine in the local network. Now run your client application. The bean now connects to the machine M2 on the scheduler server (which itself connects to the machine M1 to the Resource Manager server in order to obtain resources.). Run your client application again.
Remarks
-
You can specify your bean as “Stateless”
(for our example, a stateless bean would do just fine). Note that in this case, the ejbCreate() method will not be called (and, the SchedulerUI will be instantiated at the first call of distributedCountDivisors method)
-
In this example we have defined the number of task in a static variable.
This should be defined by taking in account the size of the number for which we are counting divisors
-
The results of the job can be obtained one by one.
Each result can be obtained as soon as the respective task has finished. This could be useful if, for instance, you are using a web client and want to refresh the page after each result (write on the web page something like “23 divisors have been found until now. ”).
-
ProActive Scheduler provides the possibility to define also Native Tasks
(instead of Java Tasks), which means that they execute native applications.
-
Dependencies between tasks can also be defined
(Task k use the results of Task i and Task j)
Fast Test
I have launched the application by using 4 nodes/JVMs (2 local JVMs and two JVMs on different machines). The output of my client application is:
Beginning computation in sequential version 12 divisors have been found Answer have been received after 33484 milliseconds. ***************** Beginning computation in distributed version 12 divisors have been found Answer have been received after 9163 milliseconds. *****************
So, by distributing the computation on 4 JVMs, I had an answering time from the server 3.65 times lower then the time for the sequential application.
Advanced
In the distributedCountDivisors method from the DivisorCounterBean class we have created a job, submitted it to the ProActive Scheduler, and then, within a loop, we have “asked” the Scheduler, every n milliseconds, if it our result is available. This solution goes well for our little example but a much better solution would be to subscribe a Listener to the Scheduler in order to be notified when the result is available.
In order to do so, you should create a Listener by implementing the org.ow2.proactive.scheduler.common.scheduler.SchedulerEventListener. You must subscribe your listener to the Scheduler, and let your listener play the role of proxy for the Scheduler. Moreover, your Listener should be an active object or, at least should belong to an Active Object.
But this requires the understanding of some ProActive concepts. I might come back on this advanced solution in some other article. Do not hesitate to let me know if you’re planning to implement this solution, I might have some useful tips for you (especially about how to configure Jboss and ProActive Scheduler in order to solve some ClassLoading conflicts that might appear)
Documentation
See JBoss at www.jboss.org
See ProActive and ProActive Scheduler at www.activeeon.com
No Comments »
No comments yet.
RSS feed for comments on this post. TrackBack URL







