Java EE Wildfly Concurrency Utility

In this post, I'll demonstrate how to use Wildfly to manage concurrency (thread) in the container.The advantage of this, rather than using java.lang.Thread is that your new thread will have access to the other Java EE services. Using the ManagedThreadFactory ensures your threads are created, and managed, by the container.

Create Thread In Java

First, we need to get a container-managed thread. We could use the ManagedThreadFactory and pass it through the Runnable instance. To get a container-managed thread, we need to configure the Wildfly Container, so we need to edit standalone.xml as below.
<subsystem xmlns="urn:jboss:domain:ee:4.0">
            <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
            <concurrent>
                <context-services>
                    <context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
                </context-services>
                <managed-thread-factories>
                    <managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
                    <managed-thread-factory name="myManagedThreadFactory" jndi-name="java:jboss/ee/concurrency/factory/MyManagedThreadFactory" context-service="default" priority="1"/>
                </managed-thread-factories>
                <managed-executor-services>
                    <managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" keepalive-time="5000"/>
                </managed-executor-services>
                <managed-scheduled-executor-services>
                    <managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" keepalive-time="3000"/>
                </managed-scheduled-executor-services>
            </concurrent>
            <default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" jms-connection-factory="java:jboss/DefaultJMSConnectionFactory" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
        </subsystem>

Create and Register Thread in ManagedThreadExecutor

Next is to create a thread. I just create a new EJB project as below.

Fig01.Create a Project
Inside the project create Java Class as below.
package pro.itstikk.wildfly;

import java.util.logging.Level;
import java.util.logging.Logger;

public class SampleTask implements Runnable {
private static Logger logger = Logger.getLogger(SampleTask.class.getName());
@Override
public void run() {
while (true) {
logger.log(Level.INFO, "New thread running...");
try {
System.out.println("Hello World");
Thread.sleep(10000);
} catch (InterruptedException e) {
logger.log(Level.SEVERE, "Thread interrupted", e);
}
}
}

}

Next is to create EJB to run the thread.
package pro.itstikk.wildfly;

import javax.annotation.Resource;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.enterprise.concurrent.ManagedThreadFactory;

/**
 * Session Bean implementation class SampleBean
 */
@Stateless(mappedName = "sampleBean")
@LocalBean
public class SampleBean {

    /**
     * Default constructor. 
     */
    @Resource(lookup="java:jboss/ee/concurrency/factory/MyManagedThreadFactory")
    private ManagedThreadFactory threadFactory;
    public SampleBean() {
        super();
    }
    
    public void runReports() {
        SampleTask sampleTask = new SampleTask();
        Thread thread = threadFactory.newThread(sampleTask);
        thread.start();
    }
}


In order to execute this EJB, we could create a web project. Then, we create a managed bean to call this EJB.

package com.jsf.bean;

import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

import pro.itstikk.wildfly.SampleBean;

@Named("taskBean")
@RequestScoped
public class TaskBean {
@EJB
private SampleBean sampleBean;
public String run() {
sampleBean.runReports();
return "save.xhtml";
}
}
Next, we create xhtml interface.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:rich="http://richfaces.org/rich"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:a4j="http://richfaces.org/a4j"
      xmlns:h="http://java.sun.com/jsf/html"> 

<h:head></h:head> 
<body>
    <rich:panel>
        <f:facet name="header">
        Write your own custom rich components with built-in AJAX support
        </f:facet>
<h:form>
<h:commandButton action="#{taskBean.run}" value="run" />
</h:form>
</rich:panel>
</body> 
</html>

Next is to start the server, and execute the program to run the thread and the result should appear as below.

4:04:25,956 INFO  [stdout] (EE-ManagedThreadFactory-myManagedThreadFactory-Thread-1) Hello World

14:04:35,956 INFO  [pro.itstikk.wildfly.SampleTask] (EE-ManagedThreadFactory-myManagedThreadFactory-Thread-1) New thread running...
14:04:35,956 INFO  [stdout] (EE-ManagedThreadFactory-myManagedThreadFactory-Thread-1) Hello World

14:04:45,957 INFO  [pro.itstikk.wildfly.SampleTask] (EE-ManagedThreadFactory-myManagedThreadFactory-Thread-1) New thread running...
14:04:45,957 INFO  [stdout] (EE-ManagedThreadFactory-myManagedThreadFactory-Thread-1) Hello World

Or you could start from listener when you start your container. You could do that by creating class that implement ServletContextListener as below.

package com.jsf.bean;

import javax.ejb.EJB;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import pro.itstikk.wildfly.SampleBean;

public class AppServletContextListener implements ServletContextListener {
@EJB
private SampleBean sampleBean;
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContextListener destroyed");

}

@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContextListener started");
sampleBean.runReports();
}

}
Next is to edit web.xml, added below listner and start container.
 <listener>
<listener-class>
        com.jsf.bean.AppServletContextListener
    </listener-class>
   </listener>

No comments:

Post a Comment

Feature Recently

Running Wildfly Application Server in Domain Mode

  Wildfly application server provides two modes of how to run application one wildfly application server. It is very simple if you run your ...

Most Views