September 26, 2013

How to Configure Scheduled Tasks in Wildfly

This example shows you how to create a scheduled concurrent task that runs every hour, using the Concurrency Utils API, and how to configure the properties of a ManagedScheduledExecutorService within Wildfly.

Example


Firstly, lets create the Runnable task which will define what work is to be done in the background thread.

public class ReportTask implements Runnable {
 
    public void run() {
        try {
            //do your background task
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            //handle execption
        }
    }
}

Now we schedule the executor to run its first execution immediately, and every hour thereafter. This executor will continue to run until you either terminate it, or until an exception it thrown by the task. We call the scheduledAtFixedRate() method, passing through our runnable task, along with the properties defining our schedule, i.e. the delay, the frequency and time unit.

@Stateless
public class ReportBean {
 
    @Resource(lookup="java:jboss/ee/concurrency/scheduler/MyScheduledExectutorService")
    private ManagedScheduledExecutorService executorService;

    public void runReports() {
        ReportTask reportTask = new ReportTask();
        executorService.scheduleAtFixedRate(reportTask, 0L, 1L, TimeUnit.HOURS);
    }
}

Lastly we need to configure our ManagedScheduledExecutorService in Wildfly.  The 'lookup' attribute of the @Resource annotation maps to 'jndi-name' attribute within the <managed-scheduled-executor-service> tag.

<subsystem xmlns="urn:jboss:domain:ee:2.0">
            <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
            <jboss-descriptor-property-replacement>true</jboss-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-factories>
                <managed-executor-services>
                    <managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" core-threads="5" max-threads="25" 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" core-threads="2" keepalive-time="3000"/>
                    <managed-scheduled-executor-service name="myScheduledExecutorService" jndi-name="java:jboss/ee/concurrency/scheduler/MyScheduledExectutorService" hung-task-threshold="50000" core-threads="4" keepalive-time="5000" reject-policy="RETRY_ABORT"/>
                </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>

Note: If we were not to specify a any lookup or name attribute in the @Resource annotation, Wildfly would inject the default execution service.


Below is the full list of attributes you can use to configure your managed-scheduled-executor-service in Wildfly.
  • name - This is the name of the resource. This attribute is manditory.
  • jndi-name - The JNDI name for this resource. This attribute is manditory
  • context-service - The context service to use, if not supplied, the default context service is used.
  • thread-factory - The name of the thread factory, if not supplied, the default thread factory is used.
  • hung-task-threshold - how long, in milliseconds, to allow threads to run for before they are considered unresponsive. (default=0, 0=no limit, min=0)
  • long-running-tasks - Whether this is a short or long running thread. (default=false)
  • core-threads - The number of threads within the executors thread pool, including idle threads.  This attribute is mandatory. (min=0)
  • keepalive-time - How long threads can remain idle when the number of threads is greater than the core-thread size. This attribute is manditory. (min=0, default=60000)
  • reject-policy - How to handle a failed task. 'ABORT' will cause an exception to be thrown; 'RETRY_ABORT' which will cause a retry, and then an abort if the retry fails. (default=ABORT) 
To view your executor in the Wildfly Admin console, login, and navigate to Runtime > JNDI View > java:jboss > ee > concurrent.  Here, you can see all the concurrent resources including your newly configured scheduledexecutor.


Note: You will notice that I have used the JNDI name of java:jboss/ee/concurrency/scheduler/MyScheduledExectutorService, which at first glance looks excessively long. Using this path ensures that the resource shows under concurrency/scheduler list in the Wildfly admin console.



September 18, 2013

Simple Concurrency Example with Wildfly

Concurrency is the ability to run several threads in parallel, within a single process.

Since its origin Java has had java.lang.Thread for dealing with concurrency. With Java SE 5 improved support was added with the java.util.concurrency package.

Enterprise containers manage their own thread pools and ensure that the other Java EE services are available to these threads. Creating threads using the concurrency API, provided by Java SE, is not recommended in an enterprise environment as there is no guarantee that your thread would have access to these services.

By using the new Concurrency Utils you can run asynchronous operations with java.util.concurrent.ExecutorService which will result in your thread being managed by the container.

The main concurrency components are:

ManagedExecutorService - used to execute tasks in a second thread. These threads are started and managed by the container

ManagedScheduledExecutorService - Same as the ManagedExecutorService except that you can schedule the thread to start as specific times

ContextService - used for creating dynamic proxy objects

ManagedThreadFactory - used by applications to create threads that are managed by the container

Example

This example demonstrates the use of the ManagedExecutorService.

First we need to create a task object that implements Callable. Within the call() method we will define the work that we want carried out in a separate thread.

public class ReportTask implements Callable<Report> {

    Logger logger = Logger.getLogger(getClass().getSimpleName());

    public Report call() {
        try {
            Thread.sleep(3000);
        catch (InterruptedException e) {
            logger.log(Level.SEVERE, "Thread interrupted", e);
        }
    return new Report();
    }
}

Then we need to invoke the task by passing it though to the submit() method of the ManagedExecutorService.

@Stateless
public class ReportBean {

    @Resource
    private ManagedExecutorService executorService;

    public void runReports() {
        ReportTask reportTask = new ReportTask();
        Future<Report> future = executorService.submit(reportTask);
    }
}

By not specifying the lookup attribute of the @Resource annotation, Wildfly will inject a managed executor service with default configuration as configured within the ee subsystem in standalone.xml.

<subsystem xmlns="urn:jboss:domain:ee:2.0">
    <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
    <jboss-descriptor-property-replacement>true</jboss-descriptor-property-replacement>
    <concurrent>
        <default-context-service/>
        <default-managed-thread-factory/>
        <default-managed-executor-service hung-task-threshold="60000" core-threads="5" max-threads="25" keepalive-time="5000"/>
        <default-managed-scheduled-executor-service hung-task-threshold="60000" core-threads="2" keepalive-time="3000"/>
    </concurrent>
</subsystem>


September 11, 2013

Java EE 7 Key Features

The prime focus of Java EE7 is to continue the simplification brought about with EE6, and to add support for new web technologies, in particular HTML5.  The 3 core objectives of Java EE7 being:

Improved Developer Productivity

  • Simplified application architecture
  • Greater user of annotations 
  • Less boiler-point code

Support for HTML5

  • Improved scalability with asynchronous RESTful Services
  • Reduced network latency with WebSocket API
  • JSON support
  • Non blocking Servelet API

Meeting Enterprise Demands

  • Multithreaded concurrent tasks
  • Uninterrupted On Line Transaction Processing
  • Overhall of JMS


Below are some of the main improvements that come with the Java EE 7 release. Over the next few weeks, I will be posting simple examples demonstrating each one of these features.


JSF 2.2:

  • HTML5 Friendly Markup 
  • Resource Library Contracts 
  • Faces Flows 
  • Stateless views


Servlet 3.1:

  • Non-blocking I/O API 
  • Support for WebSockets 
  • Various Security enhancements


CDI 1.1

A number of smaller updates help further standardization the CDI API in enterprise Java. Some of these features are:
  • Alignment of JSF scoping to CDI
  • Decoupling declarative transactions from EJB with @Transactional inteceptor
  • Binding of interceptors to constructors
  • Automatic discovery of managed beans
  • Improved support for CDI in Bean Validation


Expression Language 3.0

  • Overhauled API
  • Support for lambda expressions
  • Static field and method access
  • Improvements for collection processing
  • A standalone processor mode


Bean Validation 1.1

  • Use expression language within your constraint messages.
  • Refer to the returned value in your message
  • Format your message as you would using Formatter.format()

Enterprise JavaBeans 3.2: 

  • Transactional life cycle enhancements 
  • Extended TimerService API 
  • Optional bean passivation 
  • Asynchronous session bean invocations 
  • Improved alignment with JMS 


Java Persistence API 2.1

  • Schema generation 
  • Support for ON Conditions 
  • Bulk update and delete enhancements to Criteria API 
  • Support for stored procedures 
  • Injection of entities into entity listeners


Java Message Service 2.0

  • Overhauled and Simplified API
  • Delivery delay 
  • Asynchronous message sending 
  • Shared subscriptions 
  • AutoCloseable resources


RESTful Web Services 2.0

  • Addition of a client API 
  • Asynchronous processing, by taking advantage of the new Concurrency API. 
  • The ability to filter/intercept requests


Java API for WebSocket 1.0

A brand new API for working with Web Sockets, a new feature of the HTML5 specification. Web Sockets define a full-duplex single socket connection that allows messages to be sent between a client and a server and vastly reduce network latency.


JSON Processing 1.0:

  • Build JSON Objects from a JSON string 
  • Programatically build JSON Objects 
  • Serialize JSON Objects 
  • Parse JSON 


Concurrency Utilities for Java EE 1.0

A new API providing a standard way to concurrently process tasks in a Java EE environment. The Concurrency Utilities API builds on the concurrency API found in the standard Java environment.

Simple Concurrency Example


Batch Applications for the Java Platform 1.0

The new Batch Processing API supports both chunk processing and task-oriented processing, meaning that developers no longer need to write there own custom batch processing code.


Pruned Technologies

The following will be completely removed in Java EE 8:

  • EE Management (JSR-77)
  • Application Deployment (JSR-88)
  • JAXR (JSR-93)
  • JAX-RPC (JSR-101)
  • EJB 2.x CMP





September 5, 2013

Mapping enums with a fixed ID in JPA - An alternative to String and Ordinal

There are currently 2 ways you can map enums within your JPA entities using the @Enumerated annotation. Unfortunately both EnumType.STRING and EnumType.ORDINAL have their limitations.

If you use EnumType.String then renaming one of your enum types will cause your enum value to be out of sync with the values saved in the database. If you use EnumType.ORDINAL then deleting or reordering the types within your enum will cause the values saved in the database to map to the wrong enums types.

Both of these options are fragile. If the enum is modified without performing a database migration, you could jeopodise the integrity of your data.

A possible solution is to use the JPA lifecycle call back annotations, @PrePersist and @PostLoad. This feels quite ugly as you will now have two variables in your entity. One mapping the value stored in the database, and the other, the actual enum.

The preferred solution is to map your enum to a fixed value, or ID, defined within the enum. Mapping to predefined, fixed value makes your code more robust. Any modification to the order of the enums types, or the refactoring of the names, will not cause any adverse effects.

If you are using JPA 2.1 you have the option to use the new @Convert annotation. This requires the creation of a converter class, annotated with @Converter, inside which you would define what values are saved into the database for each enum type. Within your entity you would then annotate your enum with @Convert.

The reason why I prefer to define my ID's within the enum as oppose to using a converter, is good encapsulation. Only the enum type should know of its ID, and only the entity should know about how it maps the enum to the database.

Here is an example:

public class Player {

    @Id
    @Column(name="player_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    //...

    private Integer position;

    public Position getPosition() {
        return Position.getType(this.position);
    }

    public void setPosition(Position position) {

        if (position == null) {
            this.position = null;
        } else {
            this.position = position.getId();
        }
    }
}


public enum Position {

    FORWARD(1),
    DEFENCE(2),
    MIDFIELD(3),
    GOALKEEPER(4);

    private int id;   

    private Position(int id) {
        this.id = id;
    }

    public static Position getType(Integer id) {
      
        if (id == null) {
            return null;
        }

        for (Position position : Position.values()) {
            if (id.equals(position.getId())) {
                return position;
            }
        }
        throw new IllegalArgumentException("No matching type for id " + id);
    }

    public int getId() {
        return id;
    }
}

Note: by using an integer data type rather than a String data type, will mean quicker database queries when using the value in where clause. While this may not matter in smaller datasets of say 10,000 records, much larger datasets may notice a reduction in performance.