Book Image

Java EE 7 Developer Handbook

By : Peter A. Pilgrim
Book Image

Java EE 7 Developer Handbook

By: Peter A. Pilgrim

Overview of this book

<p>The seventh edition of the Enterprise Java platform is aimed at helping Java engineers take advantage of the advancements in HTML5 and web standards. Web Sockets, asynchronous input and output with Servlets, and strong type safety through the CDI containers will ensure that Java EE 7 remains popular for server-side applications.<br />If you are a user aiming to get acquainted with the Java EE 7 platform, this book is for you.</p> <p>"Java EE 7 Developer Handbook" provides a solid foundation of knowledge for developers to build business applications. Following the lead of Agile practices, there is a focus on writing tests to demonstrate test-driven development principles, using the embedded GlassFish 4.0 container examples and the Gradle build system. You will learn about CDI, EJB, JPA, JMS, MDB, Servlets, WebSocket, JAX-RS, Bean Validation, and so much more.</p> <p>"Java EE 7 Developer Handbook" is designed as a companion to the professional software developer who quickly needs to lookup some working code, understand the basics of the framework, and then go out and fulfill the business contract with the customer. Typically, engineers are under pressure to develop professional code that is of high quality and contains a low number of bugs. Java EE 7 Developer Handbook relies heavily on the Arquillian framework to illustrate how much easier it is to write Java EE tests, and together with the modern practice of writing containerless applications that actually embed an application container, developing agile Java EE suddenly becomes reasonable, smart, pragmatic, and achievable.</p> <p>You will start off with an overview of the Java EE platform: the containers, the design, and architecture. From there, you can follow the path of the CDI, the true gem of the framework, and then the server side end point, EJB. It is completely up to you when and if you want to learn about Java persistence. However, don’t miss out on the highlights of Java EE 7 such as WebSocket, Bean Validation, and asynchronous Servlet API.</p> <p>"Java EE 7 Developer Handbook" is a vertical slice through standard Java enterprise architecture. If you have been wondering why developers have invested so much time and effort into learning topics such as Enterprise Java Beans, you will quickly understand why when you find out the difference between stateful and stateless Beans. Best of all, this book covers the topic from the perspective of new API and new modern practices. For instance, you, the developer and designer, are expected to write applications with annotations in comparison with J2EE. Java EE 7 Developer Handbook incorporates helpful hints and tips to get the developer up to speed in a short amount of time on EJB, CDI, Persistence, Servlet, JMS, WebSocket, JAX-RS and Bean Validation, and much more.</p> <p>"Java EE 7 Developer Handbook" is the reference guide you need beside you at your desk.</p>
Table of Contents (23 chapters)
Java EE 7 Developer Handbook
Credits
About the Author
Acknowledgment
About the Reviewers
www.PacktPub.com
Preface
Index

Concurrency utilities


JSR 236, the concurrency utilities API, is a new edition to the Java EE 7 platform that provides asynchronous processing to applications using container-managed threads. In Java EE standards prior to 7, it was expressly forbidden or undefined for service endpoints, like servlets or EJBs, to spawn their own threads, because those Java threads were outside the control of the container. Although it was not portable, many applications broke this rule and found ways for the application to manage threads for the lifecycle of its deployment, sometimes using vendor specific APIs.

In Java EE 7, concurrency utilities provide managed versions of the Java SE concurrency facilities. The new concurrency utilities facilities live inside the Java package javax.enterprise.concurrent. The following table describes the interfaces:

Interface Name

Description

ManagedExecutorService

A container-managed implementation of the Java SE ExecutorService. This type of executor asynchronously invokes tasks that are submitted to it by the application.

ManagedScheduled-ExecutorService

A container-managed implementation of the Java SE ScheduledExecutorService. This type of executor invokes submitted tasks at a set future time and tasks can be invoked periodically.

ContextService

This provider component allows an application to create contextual tasks. A context here means an application context containing concurrent encapsulation of the Java EE environment including transactions.

ManagedThreadFactory

A container-managed implementation of the Java SE ThreadFactory. A thread factory is a facility for Java threads mostly from a pool.

Environment reference

In Chapter 1, Java EE 7 HTML 5 Productivity, we briefly showed some code for ManagedExecutorService. It was injected into the component with the following code:

    @Resource(name="concurrent/LongRunningTasksExecutor")
    ManagedExecutorService executor;

The application server does not automatically provision the ManagedExecutorService instances. Unfortunately, they must be configured in an XML deployment descriptor. Here is a web.xml file that illustrates the additional configuration:

<?xml version="1.0" encoding="UTF-8"?>
<web-app ...>
    <display-name>Xen Tracker</display-name>
  <!-- ... -->
    <resource-env-ref>
        <description>
            A Executor for RESTful operations.
        </description>
        <resource-env-ref-name>
            concurrent/LongRunningTasksExecutor
        </resource-env-ref-name>
        <resource-env-ref-type>
            javax.enterprise.concurrent.ManagedExecutorService
        </resource-env-ref-type>
    </resource-env-ref>
</web-app>

A similar configuration is required for the other two types: ManagedThreadFactory and ManagerScheduledExectorService. All Java EE 7 products are required to supply a default ManagedThreadFactory under the JNDI lookup name java:comp/DefaultManagedThreadFactory. The resource-env-ref-name reference specifies the reference name of the environment resource and the resource-env-ref-type reference specifies the Java data type of the resource.

Application container context

The application server is responsible for transferring a context, an application container context, to the non-container thread of context. This allows the application thread to interact with the application server in a responsible way. However, the container must manage the application thread from its internal thread pool: it is the most important stipulation. In particular, the application server does the following:

  • Saves the existing context of the current application thread

  • Identifies the correct application container context

  • Applies the identified application container context to the application thread and then allows the task to proceed

  • After the task completes it restores the previous context to the thread

The application server will apply an application container context to the following tasks: java.lang.Runnable and java.util.concurrent.Callable. This procedure is known as applying contextual services to tasks.

The concurrency utilities specification describes optional contextual support for the following classes: ManagedTaskListener and Trigger.

Contextual tasks

A contextual task is essentially the bundling of a concurrent task (runnable and callable) with the application context container. A task becomes a contextual task whenever it is submitted to a managed execution service or thread factory.

In order to access additional information, a contextual task can optionally implement the Java interface javax.enterprise.concurrency.ManagedTask. The task can invoke getExecutionProperties(), which returns a map of properties. The execution properties permit the task to set an identity with the property name IDENTITY_NAME.

The task can communicate hints back to the container. For example, property LONGRUNNING_HINT (or javax.enterprise.concurrent.LONGRUNNING_HINT can be set to true or false, which informs the container that this task is going to be long running or not. The other execution property TRANSACTION may be set to SUSPEND or USE_TRANSACTION_OF_EXECUTION_THREAD in order to communicate a hint about the transaction context in the contextual task.

In 2005 whilst working for an investment banking client in the city of London, I developed an asynchronous task with a proprietary J2EE asynchronous API. It was part of the CommonJ IBM/BEA specification. The project was to read client valuation data from an external system by FTP, parse these valuation files into domain object, and store them inside the bank's client trading portal. Given that we now have Java EE 7 technology, how would I have refactored my 2005 code into modern use?

Here is my initial stab at the code:

public class ClientValuationsProcessTask 
implements Callable<ClientValuation>, ManagedTask {
    Map<String,String> properties = new HashMap<>();
    TaskListener listener = new TaskListener();

    public ClientValuationProcessTask(
        String fileId) {
        properties = new HashMap<>();
        properties.put(ManagedTask.IDENTITY_NAME, 
            "ClientValuationsProcessTask_"+fileId);
        properties.put(ManagedTask.LONGRUNNING_HINT,"true");
    }

    public ClientValuation call() {
        // Parse the XML file referenced from id
        // Create a value object
        ClientValuation valuation = foo();
        return valuation;
    }
    
    public Map<String, String> getExecutionProperties() {
        return properties;
    }

    public ManagedTaskListener getManagedTaskListener() {
        return listener;
    } 

    class TaskListener implements ManagedTaskListener { ... }
}

Because I can work with Java SE 7 now rather than J2EE 1.4, the first refactoring is to use Callable to return the domain object, ClientValuation. This allows another contextual task to reclaim the domain object in reduce operation (or fold) the results. I could have several ClientValuationProcessTask instances all running concurrently in a map operation. Furthermore, I can hint to the application server that, actually, my ClientValuationProcessTask is going to take a long time, since this task will parse a XML file and create some value object, by supplying LONGRUNNING_HINT key setting the value to true.

ManagedTask must also implement the getManagedTaskListener() call, which can return a null or an instance ManagedTaskListener. The ManagedTaskListener allows the task to listen to life cycle events about the associated contextual task.

Here is the exposition of the TaskListener inner class:

    class TaskListener implements ManagedTaskListener { 
        public void taskSubmitted( Future<?> future,
            ManagedExecutorService executor, Object task) {
            /* ... */ }

        public void taskAborted(Future<?> future,ManagedExecutorService executor, Object task,Throwable exception) {
            /* ... */ }

        public void taskDone(Future<?> future,
            ManagedExecutorService executor, Object task,Throwable exception) {
            /* ... */ }

        public void taskStarting(Future<?> future,
            ManagedExecutorService executor, Object task) {
            /* ... */ }
     }

The ManagedTaskListener provides a way to take some action when the contextual task is aborted. For example, the ManagedExecutorService is about to shut down when the Future is cancelled from the user side.

ContextService is a way for a Java EE application to create contextual tasks without using the standard ManagedExecutor facilities. This is an advanced facility for developers and designers who know concurrency programming very well. Teams who provide libraries in enterprise integration and workflow management and open source frameworks should get involved here and take advantage of porting their products over to standard Java EE 7.

Here is some sample code of a singleton EJB that encapsulates ExecutorService with ContextService:

@Singleton
ClientValuationTaskManager {
  @Resource(name="concurrent/ThreadFactory")
  ThreadFactory threadFactory;
  @Resource(name="concurrent/ContextService")
  ContextService contextService;
  
  ExecutorService executor;
  
  @PostConstruct 
  public void setup() {
    executor = Executors.newThreadPool(10, threadFactory);
  }

  public Future submitTask( 
    ClientValuationProcessTask callable ) {
    Runnable proxyRunnber = 
      contextService.createContextualProxy(callable, Callable.class);
    Future future = executor.submit(proxyRunner);
    return future;
  }
  
  /* ... */
}

This completes the short discussion on concurrency utilities.