Java EE 7 Developer Handbook

4.5 (2 reviews total)
By Peter A. Pilgrim
  • Instant online access to over 8,000+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Java EE 7 HTML5 Productivity

About this book

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.
If you are a user aiming to get acquainted with the Java EE 7 platform, this book is for you.

"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.

"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.

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.

"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.

"Java EE 7 Developer Handbook" is the reference guide you need beside you at your desk.

Publication date:
September 2013
Publisher
Packt
Pages
634
ISBN
9781849687942

 

Chapter 1. Java EE 7 HTML5 Productivity

Nile Rodgers, Le Freak said, "We called it DHM or Deep Hidden Meaning. Our golden rule was that all our songs had to have this ingredient: understanding the song's DNA."

This is a handbook about Java EE 7. According to the Collins English Dictionary, a handbook is a reference book listing brief facts on a subject or place or directions for maintenance or repair, as of a car. In this book, we will definitely not be repairing automobiles, but instead we will point the way forward on how the developers, designers, and architects, practicing or just interested enthusiasts, can make viable use of Java on the standard Enterprise Platform.

 

Java EE 7


The Java EE 7 standard defines the following extremely important architectural interfaces:

  • EJB Container

  • Web Container

  • Context and Dependency Injection with type safety and events

  • Java Servlet Specification and Configuration

  • Optional application deployment descriptors

  • Servlet and CDI extension points

  • Support for web services RESTful and SOAP

  • Better support for messaging systems

  • Cache management on the enterprise

 

Enhanced HTML5 support


Java EE 7 is about features that offer the developers enhanced HTML5 support. HTML stands for HyperText Markup Language and is designed as a structure for presenting and structuring content for the World Wide Web (WWW). Sir Tim Berners-Lee invented HTML and the first web browser in 1990. At the time of writing, the fifth revision of HTML is expected to be announced as an official standard by the end of 2014. HTML5 improves support for latest multimedia. The fruits of its labor have been deliberated upon since the Web Hypertext Applications Technology Group (WHATWG) (http://whatwg.org/html) meetings from 2004. HTML5 is an official standard of the World-Wide Web Consortium (W3C) (http://www.w3c.org/TR/html5), which is built on the joint venture work of the WHATWG and the W3C.

HTML5 now embraces new media types, which are one of the great highlights of it, namely video, audio, and canvas. The canvas is a special type of drawable apparatus in the web browser, where the web client developers can manipulate dynamic content with the JavaScript programs.

There is a series of new tag elements to give a better structure to HTML5 documents. New web applications are encouraged to write or generate HTML5 content with article, section, header, footer, figure, figcaption, hgroup, nav, summary, and detail, time, or aside tags. This is just a small sample of the new semantic and document structure of HTML5 tags. There are several tag elements, such as center, which are deprecated, because these features are better expressed with Cascading Style Sheets (CSS) rather than markup.

HTML5 is also an aggregation term that stands for the set of emerging multimedia technologies that are supported by the markup language. Browser support CSS 3 is regularly expected for HTML5 compatibility. Moreover, our industry is presently undergoing a mobile web application revolution on smartphones and, especially, tablet computing devices. HTML5 not surprisingly also adds the geolocation support, including the location tracking in the browser. It also covers offline session and local storage for web applications that run on mobile devices, such as smartphones or tablets. These applications can save state when the connection to the Internet is lost.

Some of the modern HTML5 supporting browsers actually have the 3D graphics support through a working standard called WebGL , which impacts the amount of data that is streamed from the server to the client. 3D graphics and high-resolution media generally entails a larger server-side push of data compared to lesser media websites. There is a sliding scale of capability with the current versions of Firefox, Safari, Chrome, and Opera browsers. The outlier is typically Microsoft's web browsers Internet Explorer 9 and 10. For those of you who want 3D effects without the reliance of WebGL you should take a look at the CSS 3 3D transformations.

Finally, JavaScript is a single thread in the execution in a web browser. There is no way to spawn multiple threads in modern standard W3C conforming web clients. HTML5 also embraces two fundamental groundbreaking changes: Web Works and WebSocket. Web Works is a JavaScript compatible API that allows web clients to run long-running code that does not block the browser. WebSocket is a new way for a browser and server to exchange an asynchronous communication without having to constantly send the metadata information. WebSocket is an extension of the TCP/IP Socket protocol specifically for HTTP communications.

 

Java EE 7 architecture


Let us start by understanding the non-cloud Java EE model architecture. This is revision material, if you already know the platform. For a beginner, reading this section is frankly essential.

Standard platform components and APIs

Java EE architecture can be thought of as four separate containers. The first one is called the EJB container for lifecycle management of Enterprise Java Beans and the second container is the web container for lifecycle management of Java Servlets and managed beans. The third container is called the Application Client container, which manages the lifecycle of the client-side components. Finally, the fourth container is reserved for Java Applets and their lifecycle.

The Java EE containers are runtime environments that hold Java applications deployed in the Java Archive (JAR) files. You can think of a JAR file as a bundle, but more accurately it is a special annotated ZIP file with a manifest. The JAR files are simply an assembly of compiled Java classes.

A fully conformant Java EE product, such as Glassfish or JBoss Application Server has both containers. As you can see from the following diagram, there are lots of API that these products have to implement in order to be certified as a standard product. The most difficult of these APIs have to do transactional, resource pool connection, and enterprise Java Beans.

Each of these standard API is a specification in its own right, and relevant information can be queried, downloaded, and examined from the Java Community Process website (http://jcp.org). Each specification has a unique number, which identifies the Java Specification Request (JSR) for the API. Indeed, the JSR for the Java EE 7 Platform Edition, is an assembly of many specifications, and has an official number 342.

The platform specification, such as the one that this book is written about, Java EE, then, is an ensemble of the JSRs into a higher-level specification. The platform specifications offer guarantees of interoperability, security, and serviceability of the individual JSR. In other words, not just any JSR can be automatically included in the platform specification. Each JSR fits the remit of the Enterprise Platform.

New productivity themes

The Developer productivity is a key theme for Java EE 7. There are four brand new specifications added to Java EE 7: Batch, Concurrency Utilities, WebSocket, and JSON-P.

Batch Processing API is introduced into Java EE 7 to reduce the dependency on the third-party framework. Batch processing is a field of information technology that predates Java by several decades and has its origins in the mainframe systems. Sadly, this topic of interest is out of the scope of this book.

Concurrency Utilities solves a long-standing issue with enterprise Java: how to spawn Java Thread processes without knowledge and control of the application server. The new Concurrency Utilities enhances the developers productivity with the managed thread pool and executor resources.

Java API for WebSocket specification allows Java enterprise applications to communicate with the new HTML5 WebSocket protocol.

Finally, JSON-P is a new specification that standardizes reading and writing the JSON content for the platform. The additional JSON library further reduces the reliance on the third-party libraries.

Refinements

Java EE 7 takes advantage of the New Input Output (NIO) in the Java SE edition to allow Java Servlets 3.1 to handle an asynchronous communication.

Java EE 7 extends the Java Persistence API (JPA 2.1) abilities for the developers. They can now invoke the stored procedures, execute bulk criteria updates and deletes, and control exactly which entities are eagerly or lazily fetched from the database within reason.

Expression Language (EL) 3.0 is not truly a new specification, but it is a broken-out specification from Servlets, JavaServer Pages, and JavaServer Faces. The developers can access the expression evaluator and invoke the processing custom expressions on, say, their own custom tag libraries or server-side business logic.

Perhaps, the most important change in Java EE 7 is the strengthening of Context and Dependency Injection (CDI) in order to improve type safety and the easier development of the CDI extensions. CDI, Interceptors , and Common Annotations improve type safe, dependency injection, and observing of the lifecycle events inside the CDI container. These three specifications together ensure that the extensions that address the crosscutting concerns can be written, and can be applied to any component. The developers can now write portable CDI extensions to extend the platform in a standard way.

Java EE 7 continues the theme that was started in the earlier editions of the platform, improving the ease-of-development and allowing the developers to write Plain Old Java Objects (POJO).

As if to prove a point, the new Java Transaction API (JTA) introduces a new annotation @javax.transaction.Transactional, which allows any CDI or managed bean to take advantage of the enterprise transactions.

Java for RESTful Services (JAX-RS) has three crucial enhancements, the addition of the client-side API to invoke a REST endpoint, an asynchronous I/O support for the client and server endpoints, and hypermedia linking.

Bean Validation is a constraint validation solution for the domain and value object. It now supports the method-level validation, and also has better integration with the rest of the Java EE Platform.

Java Connector API (JCA) is improved for the Enterprise Integration Architecture (EIA) customers in terms of asynchronous execution, processing, and resources; enhancements in JCA affect the intersystem messaging in Message-Driven Beans in an especially powerful way. Sadly, JCA, JSF, and EL are topics, which are out-of-scope of this book.

 

Java EE Platform


The platform, then, is a balance between the three forces, namely the community of the enterprise Java developers, the product providers, and of course the enterprise that must uphold the business models.

The community requires standardization in order that they can easily embrace technology without the fear of vendor lock-in. They also want to be satisfied with a sound investment in the software development for years to come.

The vendors have an interest in selling their products, services, and support to the community of users for years to come. They also want to have a platform that lowers the barriers to compete against other vendors. It is helpful for them that there is a standard to aim for, a testable certification to achieve, in which they can brand their servers.

The specification for the Full Profile edition of Java EE 7 has the following APIs:

Name

Version

Description

JSR

Web

Profile

Batch Process

1.0

Batch Processing (NEW)

352

 

Bean Validation

1.1

Bean Validation framework

349

Y

Common Annotations

1.1

Common Annotations for the Java EE platform

250

Y

CDI

1.1

Contexts and Dependency Injection for Java EE

346

Y

Concurrency Utilities

1.0

Concurrency Utilities for the Java EE platform (NEW)

236

 

DI

1.0

Dependency Injection for Java

330

Y

EL

3.0

Unified Expression Language for configuration of web components and context dependency injection

341

Y

EJB

3.2

Enterprise Java Beans, entity beans and EJB QL

345

Y (EJB Lite)

Interceptors

1.2

Interceptor technology (NEW)

318

Y

JACC

1.4

Java Authorization Contract for Containers

115

 

JASPIC

1.1 M/B

Java Authentication Service Provider Interface for Containers

196

 

JavaMail

1.4

Java Mail API

919

 

JAXB

2.2

Java API for XML Binding

222

 

JAXP

1.4

Java API for XML Parsing

206

 

JAX-RS

2.0

Java API for RESTful Services

339

Y

JAX-WS

1.3

Java API for XML –based Web Services including SOAP and WSDL

224

 

JCA

1.7

Java EE Connector Architecture

322

 

JMS

2.0

Java Message Service

343

 

JPA

2.1

Java Persistence API

338

Y

JSF

2.2

Java Server Faces

344

Y

JSON-P

1.0

JavaScript Serialization Object Notation Protocol

353

Y

JSP

2.3

Java Server Pages

245

Y

Debugging support

1.0

Debugging Support for Other Languages such as Java Server Pages

45

Y

JSTL

1.2

Java Standard Template Library

245

Y

JTA

1.2

Java Transaction API

907

Y

Managed Beans

1.0

Managed Beans 1.1

342

Y

Servlet

3.1

Java Servlet

340

Y

Web Services

1.3

Web services

224

 

Web Services Metadata

2.1

Web services metadata

181

 

WebSocket

1.0

Java API for WebSocket (NEW)

356

Y

There is also a subset of the Java EE 7 product, known as the Web Profile that only handles the web specific Java enterprise APIs. Examples of this sort of product are open source Apache Tomcat from the Apache Software Foundation, Caucho's proprietary Resin, and the ever popular open source embeddable Jetty Server. The Java EE 7 web container products have a much smaller subset of JSRs to implement.

Note

You might have noticed that some of the Java EE APIs were supported already in some web containers, which existed before the profiles were standard in Java EE 6 (December 10, 2009).

Java Persistence, which maps entity beans, or persistence capable objects, to a relational database, is one of the most crucial and important application interfaces. JPA is a tremendous success for the portable object-relation mapping applications that works across the databases and application servers. Your code can move from one vendor's database connection to another. There is always a slight caveat emptor: there is no such thing as 100 percent portability. But without the standard framework, your developers would have to work an awful lot harder than tweaking a few database tables and configuring a different JDBC connection resource.

Portability and the future of the Java SE and EE platforms will be very important for moving your applications to the diverse, but unstandardized, cloud-computing environment. Although cloud computing was dropped from Java EE 7 late in the establishment of the specification, adopting Java EE 7 will help in the mid-term future when there is an official Java enterprise edition for the cloud. It is rather likely that in those modern utility computing environments, prospective business subscribers will welcome the ability to move from one cloud PaaS (Platform as a Service) vendor to another for a technical and/or business reason.

Standards, then, are very important to Java. It means that we can all move along in a positive direction with less fear of the unknown and that, ladies and gentlemen, is good for everybody. The API that your application code depends on is critical to its software lifecycle. Let's move on to the profiles.

Java EE Profiles

The formal definition of a profile is a specialization of a Java Platform Edition that includes zero or more Java Community Process (JCP) specifications (that are not part of the Platform Edition Specification). Java Enterprise Platform Edition defines two profiles, the Full Profile and the Web Profile product.

Java EE Web Profile, to give it its full official name, is the first profile defined by the standards committee, the JCP. The Web Profile defines a small subset of the Java EE components for delivering the web content. It specifically targets the Java web developers who are responsible for delivering the Java web applications.

The Web Profile offers a degree of completeness with its set of APIs. A business developer can write modern web applications that only access, execute, and perform against Web Profile. Most web applications require state-management and transactional demands. Even though a lot of Java Web Applications, written today rely less on direct calls to the Java Servlet API, in most cases they still tend to use a Java Web Framework.

Web Profile

The Web Profile has the following feature set of APIs:

  • Java Servlet API 3.1: This framework provides handling for an HTTP request and response synchronously and now asynchronously

  • Enterprise Java Bean Lite 3.2: This is a less demanding model of service endpoints, where the business logic of the application lives

  • Context and Dependency Injection 1.1: This is a framework for the application that transfers the lifecycle and management of the connected objects to the container

  • Java Server Faces 2.2: This is a component-based web user interface framework

  • Java Transaction API 1.2: This is a framework for two-phase commit transactions

  • Java Persistence 2.1: This is a framework for persisting POJO to a database

  • Web Socket 1.0: This is a new specification for Java to engage the HTML5 WebSocket clients and servers

  • Bean Validation 1.1: This is an upgraded framework to constrain the fields, properties, and methods of the value objects in an application

  • JAX-RS 2.0: This is an upgraded framework for the Java Enterprise applications to handle the RESTful communications

  • JSON-P 1.0: This is a brand new framework for the Java application read-and-write JavaScript Schema Object Notation (JSON) documents

With these small set of requirements, it is not surprising that the Java EE implementation providers find the Web Profile easier to implement.

Tip

Which Web Frameworks and Java EE 7

Usually the biggest question for the Java Enterprise developers in the past has been, what web framework to use? At the time of writing, JSF 2.2 is the only framework that is compatible. The purveyors of the other frameworks, such as Apache Wicket, WebWork, or even Spring MVC must update their services, especially to support the new asynchronous abilities in Java Servlets 3.1 and JAX-RS 2.0.

The way we build web applications in 2013 is also changing, and the author expects some new innovations here in this space. Some applications are going straight to the RESTful applications by passing the older Front Controller and MVC architecture of traditional web frameworks from Java EE 6 or before. In those web applications, the interface is simply a barrage of the AJAX call-and-response calls from the client side, predominantly a single application communicating with a server-side backend.

Enterprise Profile

The Enterprise Full Profile is the complete set of API that matches the Platform Edition specification, which compliant providers must fulfill, in order to be certified as Java EE 7 compliant.

It's worth looking at each component of the platform and spending some time getting acquainted with them. There are an awful lot of individual specifications here and my advice is to use the Web Profile as a guide to getting into the Java EE 7 experience.

The following table is a guide to the key Enterprise services:

Name

Description

JTA

A standard API for demarcating the transactions in either the application or container.

EJB

Enterprise Java Beans are the transactional service endpoints that represent the interface to business logic for a client. They can be stateless, stateful, or singleton instances.

Managed Beans

Managed beans are endpoints with a contextual scope and they are type safe entities. Managed beans are managed by the Context and Dependency Injection container.

JDBC

JDBC is often quoted (wrongly) as Java Database Connectivity, a standard API for connecting to a relational database system. This component is part of the Standard Platform Edition.

JPA

Java Persistence API is the standard framework for the object-relational mapping of the Java objects to a database. JPA provides management of persistence through a persistence context. It allows the application developers to store data as the Java domain object rather than the relational tables. JPA is also available in the Java SE environments.

JMS

Java Message Service is a standard API for receiving and sending messages in a reliable transport, mostly asynchronously. JMS is based on the point-to-point messages and also publish-subscribe messaging. JMS is the basis for the Enterprise application integration in Java.

JNDI

Java Naming and Directory Interface is a standard API for looking up the location of the resources by name. It is a directory service used by the application components and the containers.

JAX-RS

Java API for RESTful services, a framework for processing the HTTP Representation State Transfer (REST) style requests and responses.

JAX-WS

Java API for the XML-based web services, a framework in Java to process the SOAP, WSDL documents in the distributed systems.

JavaMail

JavaMail is a standard API that allows the Enterprise Java application to send and receive e-mail. It has support for both the MIME and plain text e-mail.

Let's dispense with the theory and look at some of the Java EE 7 code.

 

A working example


In this section, we shall examine Java EE 7 from a sample project management application. The name of the application is XenTracker. It is a web application with EJB, the RESTful web services, and Persistence.

The development version of the XenTracker application, which has minimal styling and user interface enhancement, is shown in the following screenshot:

Entities

Our web application manages a couple of entities (also known as persistence capable objects), named Project and Task. The entities are mapped to the database table using the JPA annotations. We start with the entities in our Java EE 7 application, because it helps model the business requirements, and the domain of our boundaries. A project has zero or more task entries.

The definition for the Project entity is as follows:

package je7hb.intro.xentracker.entity;

import org.hibernate.validator.constraints.NotEmpty;
import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.*;

@Entity
public class Project {
  @Id @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "PROJECT_ID") private Integer id;
  
  @NotEmpty @Size(max = 64)
  private String name;
  
  @OneToMany(cascade = CascadeType.ALL, mappedBy = "project", fetch = FetchType.EAGER)
  private List<Task> tasks = new ArrayList<>();
  
  public Project() {/* Required for JPA */}
  public Project(String name) {this.name = name;}
  
  public Integer getId() {return id;}
  public void setId(Integer id) {this.id = id;}
  public String getName() {return name;}
  public void setName(String name) {this.name = name;}
  
  public List<Task> getTasks() {return tasks;}
  public void setTasks(List<Task> tasks) {this.tasks = tasks;}
  
  public boolean addTask(Task task) {
    if (!tasks.contains(task)) {
      Project oldProject = task.getProject();
      if (oldProject != null) {
        removeTask(task);
        }
      tasks.add(task);
      return true;
      } else {return false;}
    }
  
  public boolean removeTask(Task task) {
    if (tasks.contains(task)) {
      tasks.remove(task);
      task.setProject(null);
      return true;
      } else {return false;}
    }
  
  // hashCode(), equals(), toString() omitted
  }

Tip

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you. Alternatively, you can download the code from the author's GitHub account at https://github.com/peterpilgrim.

We observe that the class Project is declared with several annotations. @Entity marks this type as a JPA entity object and it has a default mapping to a database table called PROJECT. The @Id annotation designates the id field as a primary key. The @Column annotation overrides the default object-relational mapping and changes the table column name to PROJECT_ID instead of ID. The @GeneratedValue annotation informs JPA to automatically generate the primary key value for the project from the database connection provider.

The @NotNull annotation and @Size are from Bean Validation and Hibernate Validator frameworks respectively. They provide constraint checking at the source on the Project entity bean and they validate that the project's name field is not null and that the length of the field must be less than or equal to 64 characters. Incidentally, the Java EE 7 application servers will automatically invoke Bean Validation when this entity is inserted into, or updated to, the database.

Lastly, the @OneToMany annotation declares that the Project entity has a one-to-many relationship with another entity Task. Chapter 5, Object-Relational Mapping with JPA, is dedicated fully to the entity relationships, the database cardinalities, and the fetch types.

The definition for the Task entity is as follows:

package je7hb.intro.xentracker.entity;

import org.hibernate.validator.constraints.NotEmpty;
import javax.persistence.*;
import javax.validation.constraints.*;
import java.util.Date;

@Entity
public class Task {
  @Id @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "TASK_ID") private Integer id;

  @NotEmpty @Size(max = 256)
  private String name;

  @Temporal(TemporalType.DATE)
  @Column(name = "TARGET_NAME") @Future
  private Date targetDate;

  private boolean completed;

  @ManyToOne(cascade = CascadeType.ALL)
  @JoinColumn(name = "PROJECT_ID")
  private Project project;

  public Task() {/* Required by JPA */}
  public Task(String name, Date targetDate, boolean completed) {
    this.name = name;
    this.targetDate = targetDate;
    this.completed = completed;
    }

  // getters and setters omitted()
  public Project getProject() {return project;}
  public void setProject(Project project) {
    this.project = project;
    }

  // hashCode(), equals(), toString() omitted
  }

The entity Task represents a task in the business domain. The Task entity has a primary key too, mapped by the @Id annotation, which is also automatically generated on a database insertion. We also override the database column name to TASK_ID.

We declare Bean Validation constraints on the Task entities name field in exactly the same way as we do on Project, except a task has a longer length of string.

The targetDate is the due date for the task, which is optional, meaning that its value can be null. We use Bean Validation's @Future to constrain the target date to any date in the future. Finally, JPA requires us to explicitly define the temporal type whenever we map java.util.Date. In this case, we map targetDate to only SQL date types with the @TemporalType annotation.

A Task entity has a reverse mapping back to Project. In other words, a task is aware of the project that it belongs to; we call this a bi-directional relationship. We declare the project field with the annotation @ManyToOne.

Business logic

In order to be operational, we write business logic for our web application XenTracker. We require methods to create, update, and delete Projects and for Tasks. We also want to retrieve the list of projects and tasks for each project.

We shall use the session EJB for this purpose, because we want the lifecycle of business logic to be available as soon as our application is deployed to a Java EE 7 application server product or web container. EJBs support the transactions by default, they can be pooled by the server, their methods can be declared as asynchronous, and they are normally participants in monitoring with Java Management Extensions (JMX). EJBs are discussed in detail in Chapter 3, Enterprise Java Beans.

First, we add some named queries to one of the entity beans. A named query is a way of storing a persistence query with the domain object. JPA only allows named queries to be declared with the entities.

Let us modify the Project entity as follows:

@NamedQueries({
  @NamedQuery(name = "Project.findAllProjects", query = "select p from Project p order by p.name"), @NamedQuery(name = "Project.findProjectById", query = "select p from Project p where p.id = :id"), @NamedQuery(name = "Project.findTaskById", query = "select t from Task t where t.id = :id"),})
@Entity
public class Project {/* ... */}

The annotation @NameQueries declares a set of @NamedQuery annotations attached to the Project entity bean. Each named query must have a distinct name and a Java Persistence Query Language (JPQL) statement. JPQL can have named parameters, which are denoted with the prefix of a colon character (:id).

In order to define a stateless session EJB, all we need to do is annotate a concrete class with the type @javax.ejb.Stateless. Our ProjectTaskService stateless session EJB is as follows:

package je7hb.intro.xentracker.boundary;
import je7hb.intro.xentracker.entity.*;
import javax.ejb.*;
import javax.persistence.*;
import java.util.List;

@Stateless
public class ProjectTaskService {
  @PersistenceContext(unitName = "XenTracker")
  private EntityManager entityManager;
  
  public void saveProject(Project project) {
    entityManager.persist(project);
    }
  
  public void updateProject(Project project ) {
    Project projectToBeUpdated = entityManager.merge(project);
    entityManager.persist(projectToBeUpdated);
    }
  
  public void removeProject(Project project) {
    Project projectToBeRemoved = entityManager.merge(project);
    entityManager.remove(projectToBeRemoved);
    }
  
  public List<Project> findAllProjects() {
    Query query = entityManager.createNamedQuery("Project.findAllProjects");
    return query.getResultList();
    }
  
  public List<Project> findProjectById(Integer id) {
    Query query = entityManager.createNamedQuery("Project.findProjectById").setParameter("id", id );
    return query.getResultList();
    }
  
  public List<Task> findTaskById(Integer id) {
    Query query = entityManager.createNamedQuery("Project.findTaskById").setParameter("id", id );
    return query.getResultList();
    }
  }

Our session EJB depends upon persistence objects, so we inject an EntityManager object into it with the special annotation @PersistenceContext. The entity manager operation represents a resource connection to the database.

The methods saveProject(), updateProject(), and removeProject() respectively create, update, and delete the project entities from the database. The entity manager operations are covered in Chapter 4, Essential Java Persistence API 3.2. Because of the CascadeType.ALL definitions on the actual entities themselves, the dependent detail entity Task is looked after with the changes on the Project entity. You will learn about the cascade operations in Chapter 5, Object-Relational Mapping with JPA. So do we retrieve data back from the database?

The methods findAllProjects(), findProjectById(), and findTaskById() are so-called finder operations, the R in the acronym CRUD (Create Retrieve Update Delete). Each of the methods accesses a particular named query, which we attach to the Project entity. The findTaskById() method, for example, gets the JPQL command named Project.findTaskById as a query instance. Notice that we can invoke the methods on that instance by chaining, so that the local variable is in fact unnecessary, and just serves as an education artifact.

The ProjectTaskService session has all of the operations to allow users to add, edit, and remove projects, and also to add, update, and remove tasks to and from projects. So now that we have our business logic, we can go forward and add a controller endpoint for web clients.

The service endpoints

Let's dive straight into the Java EE 7 pool and show off a Java-based WebSocket endpoint for our XenTrack application. We shall create a straightforward server-side endpoint that accepts a text message, which simply is the project ID, and returns the results as a JSON.

A WebSocket endpoint

The definition of the class ProjectWebSocketServerEndpoint is as follows:

package je7hb.intro.xentracker.control;
import je7hb.intro.xentracker.boundary.ProjectTaskService;
import je7hb.intro.xentracker.entity.*;

import javax.ejb.*;
import javax.inject.Inject;
import javax.json.Json;
import javax.json.stream.*;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.*;

@ServerEndpoint("/sockets")
@Stateless
public class ProjectWebSocketServerEndpoint {
  static SimpleDateFormat FMT = new SimpleDateFormat("dd-MMM-yyyy");
  @Inject ProjectTaskService service;
  
  @OnMessage
  public String retrieveProjectAndTasks(String message) {
    int projectId = Integer.parseInt(message.trim());
    List<Project> projects = service.findProjectById(projectId);
    StringWriter swriter = new StringWriter();
    
    JsonGeneratorFactory factory = Json.createGeneratorFactory(new HashMap<String, Object>(){{put(JsonGenerator.PRETTY_PRINTING, true);}});
    JsonGenerator generator = factory.createGenerator(swriter);
    
    generator.writeStartArray();
    for (Project project: projects) {
      generator.writeStartObject()
      .write("id", project.getId())
      .write("name", project.getName())
      .writeStartArray("tasks");
      
      for (Task task: project.getTasks()) {
        generator.writeStartObject()
        .write("id", task.getId())
        .write("name", task.getName())
        .write("targetDate", task.getTargetDate() == null ? "" : FMT.format(task.getTargetDate()))
        .write("completed", task.isCompleted())
        .writeEnd();
        }
      generator.writeEnd().writeEnd();
      }
    generator.writeEnd().close();
    
    return swriter.toString();
    }
  }

Although the ProjectWebSocketServerEndpoint class looks complicated, it is actually easy to write. We declare POJO with the @ServerEndpoint annotation, which annotates it as a Java WebSocket endpoint, and it becomes available as a server. The WebSocket clients can interact with this endpoint, by sending text data to a web context defined URL. For example, on my test this is http://localhost:8080/xentracket/sockets. The @ServerEndpoint annotation accepts a URL pattern value.

In Java EE 7 we must also declare ProjectWebSocketServerEndpoint as a stateless EJB with @Stateless in order to inject the ProjectTasksService EJB as a dependency. (This is a consequence of Java for WebSocket 1.0 specification.) Note that we can use @javax.annotation.Inject from CDI.

The unit test ProjectRESTServerEndpointTest running in the IDE is as shown in the following screenshot:

Next, we annotate the method retrieveProjectAndTasks() with the WebSocket annotation @OnMessage, which declares this method as the reception point for the incoming requests. There can be only one message per class per web application deployment.

Our method retrieveProjectAndTasks() accepts a text message, which we parse into a project ID integer. We then invoke the ProjectTasksService session to retrieve a list collection of the Project entities. Afterwards, we immediately turn that list into a JSON array output string using a StringWriter as a text buffer, and two new classes from the JSON-P streaming API namely: JsonGeneratorFactory and JsonGenerator.

We instantiate a JsonGeneratorFactory class with the literal Java HashMap trick to set up JSON output that is prettily printed. With the factory, we can write the JSON output using the fluent API JsonGenerator. The method call writeStartArray() starts the output stream for a JSON array. The method call writeStartObject() starts the output stream for a JSON object. We just call the generator's write(String, X) to send the JSON name and value pair. When we finish writing the JSON object and array, we must call writeEnd() to properly close JsonValue.

Finally, once we finish writing the JSON output, we call the generator's close() method. The target java.io.StringWriter now contains the JSON text value. The Java EE 7 WebSocket provider takes the return value and sends that data, the JSON array, to the other WebSocket peer. We shall quickly look at a JAX-RS example.

A RESTful endpoint

JAX-RS 2.0 is the RESTful standard framework for Java EE 7. We shall use JAX-RS to create the beginnings of a web application with a POJO that serves as a RESTful resource. In the interest of space in this book, we only consider the HTTP GET and POST methods. The GET method accepts a project ID and returns a JSON object that represents a project. The POST method accepts a JSON object and creates a new Project with or without dependent Task instances. The new Project instance returns as JSON.

The POJO class ProjectRESTServerEndpoint with a definition of a RESTful endpoint in the class called is as follows:

package je7hb.intro.xentracker.control;
import je7hb.intro.xentracker.boundary.ProjectTaskService;
import je7hb.intro.xentracker.entity.*;

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.json.*;
import javax.json.stream.*;
import javax.ws.rs.*;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.*;
import static javax.ws.rs.core.MediaType.*;

@Path("/projects")
@Stateless
public class ProjectRESTServerEndpoint {
  static SimpleDateFormat FMT = new SimpleDateFormat("dd-MMM-yyyy");
  static JsonGeneratorFactory jsonGeneratorFactory = Json.createGeneratorFactory();
  
  @Inject ProjectTaskService service;
  
  @GET @Path("/item")
  @Produces(APPLICATION_JSON)
  public String retrieveProject(@PathParam("id") @DefaultValue("0") int projectId ) {
    List<Project> projects = service.findProjectById(projectId);
    StringWriter swriter = new StringWriter();
    JsonGenerator generator = jsonGeneratorFactory.createGenerator(swriter);
    generateProjectsAsJson(generator, projects).close();
    return swriter.toString();
    }
  /* ... */
  }

The ProjectRESTServerEndpoint is also a stateless session EJB and there really is no penalty in modern Java EE 7 products for how heavy a session EJB is. In fact, they are extremely lean; an application server for Java EE 7 can easily handle 10000 beans or more without issues. In the not too distant future, when we have Java EE standard for the cloud environment, the Java EE application server products will handle millions of EJBs and CDI managed beans.

We annotate the ProjectRESTServerEndpoint type with the JAX-RS annotation@Path, which notifies the JAX-RS provider that a POJO is an endpoint at the URL context path of /projects. For the JAX-RS projects, normally we also define an application path root, and it stands in front of the individual endpoints. For instance, on my test server the full URL context is http://localhost:8080/xentracker/rest/projects/item.

You have already seen the injection of the EJB ProjectTaskService, but we now see the @GET annotation from JAX-RS on the method retrieveProject(), which designates the endpoint for the HTTP GET requests from the client.

The @PathParam annotation identifies a parameter in the URL; it actually extracts a key parameter in the URL pattern. In this case, the parameter is called id in the input URL. For example, http://localhost:8080/xentracker/rest/projects/item/1234 maps to the JAX-RS URL pattern /projects/item/{id}. Meanwhile, the @DefaultValue annotation defines a default String value, just in case the client did not specify the parameter, which avoids an error inside the server.

We refactor out the JSON generator code from before and simply call a static method in order to generate the correct output. Finally, the @Produces annotation informs the JAX-RS provider that his RESTful resource endpoint produces JSON.

Let's examine one RESTful endpoint for the HTTP POST request, where we want to insert a new project into the database. The definition method createProject() is as follows:

@POST @Path("/item")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public String createProject(JsonObject projectObject)
throws Exception {
  Project project = new Project(projectObject.getString("name"));
  JsonArray tasksArray = projectObject.getJsonArray("tasks");
  if (tasksArray ! = null) {
    for (int j = 0; j<tasksArray.size(); ++j) {
      JsonObject taskObject = tasksArray.getJsonObject(j);
      Task task = new Task(taskObject.getString("name"), (taskObject.containsKey("targetDate") ?
      FMT.parse(taskObject.getString("targetDate")): null), taskObject.getBoolean("completed"));
      project.addTask(task);
      }
    }
  
  service.saveProject(project);
  StringWriter swriter = new StringWriter();
  JsonGenerator generator = jsonGeneratorFactory.createGenerator(swriter);
  writeProjectAsJson(generator, project).close();
  return swriter.toString();
  }

The method is annotated with @POST from JAX-RS. It consumes and produces JSON, so we annotate it with @Consumes and @Produces. JAX-RS knows about JSON-P in the Java EE 7 edition, so our method directly accepts a JsonObject instance. In other words, we get the conversion from a String to a JsonObject object for free!

Unfortunately, we must retrieve individually the name, value, and array pairs from the JSON input, and create our domain objects. There is no substitute for work. Given JsonObject, we build a new Project instance, and optionally the associated Task objects. JsonObject has a number of convenient calls such as getString(), getNumber(), and getBoolean(). Unfortunately, we must convert the formatted target date string and we must deal with the optional JSON tasks array, because it can be null. It is possible to check if the value exists in the JsonObject object by calling containsKey(), since a JsonObject is a type of java.util.Map.

Once we have the Project instance, we save it to the database using the ProjectTaskService boundary service. Afterwards, we use the refactored JSON generator method to write the Project instance to the client.

To complete our brief tour of JAX-RS, we shall add another HTTP GET method to our RESTful endpoint. This time, however, we will make it asynchronous in operation. The home page of our web application XenTracker always executes an AJAX request; whenever it loads in the browser, it queries all of the projects in the database. Let's say 1000 web users are simultaneously accessing the application in a couple of minutes and each user has say an average of 10 projects with an average of 25 tasks between them, how would we scale this query?

With a stateless session EJB such as ProjectRESTServerEndpoint, we can use the new Concurrency Utilities API in Java EE 7 to achieve an asynchronous output. Let us apply it to the method getProjectList() now as follows:

/* ... */
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;

/* ... */
public class ProjectRESTServerEndpoint {
  /* ... */
  @Resource(name = "concurrent/LongRunningTasksExecutor")
  ManagedExecutorService executor;
  
  @GET
  @Path("/list")
  @Produces(MediaType.APPLICATION_JSON)
  public void getProjectList(@Suspended final AsyncResponse asyncResponse) {
    executor.submit(new Runnable() {
      @Override
      public void run() {
        List<Project> projects = service.findAllProjects();
        StringWriter swriter = new StringWriter();
        JsonGenerator generator = jsonGeneratorFactory
        .createGenerator(swriter);
        generateProjectsAsJson(generator, projects)
        .close();
        Response response = Response.ok(swriter.toString()).build();
        asyncResponse.resume(response);
        }
      });
    }
  }

In JAX RS 2.0 we must also add a special class as a method parameter. AsyncResponse is the object context for an asynchronous response. The AsyncResponse object has all of the server-side information to enable the JAX-RS API to send data back to the client from another Java thread from the executor thread pool. Typically, the application retrieves a Concurrent Utility Task (new in Java EE 7, see Appendix D, Java EE 7 Assorted Topics), which is the responding thread, and for long-running operations it is not associated with the main JAX-RS request processing thread. The parameter asyncResource is also annotated with @Suspended in order to suspend the output of the response, because we want to halt the response until the application invokes the long-running task. Inside the task, given an AsyncResponse object, we call the resume method with the JAX-RS response to send back to the client. Note that in this example, because we are using an inner class Runnable, we must set the method parameter's modifier to final.

We take advantage of the Concurrency Utilities API; in particular, we inject a ManagedExecutorService into the EJB with the @Resource annotation. The @Resource annotation is from Common Annotation API such as, @Inject, but it injects the database connection, connectors, and now managed concurrency services. The method getProjectList() is exactly one statement long. It creates a Runnable task, an anonymous inner class, and then submits it to the executor pool running inside the Java EE 7 application server. At some point after the submission, the task is invoked, and it delivers a response to the RESTful client on a separate thread.

Tip

Ramping up on Java concurrency

The best book of multiple threads programming in Java with JVM at the time of writing is Java Concurrency in Practice by Brian Goetz, Oracle's Java language architect. The author strongly recommends this book to learn how to use the Java concurrency features such as synchronization primitives, executors as in Java EE 7, atomic wrappers, futures, and scheduled services.

The Runnable task instantiates a java.ws.rs.core.Response object instance in order to build a generic entity, which is the list of projects generated as JSON. Our most important responsibility is to cause the output to be sent back to the client by resuming an asynchronous response context; we invoke the method AsyncResponse.resume() with the generic response.

This is the end of the worked example tour of some new features of Java EE 7. The full application can be found with this book's source code. There are two variations of the XenTracker application: an initial edition, and a completely refined and finessed business example.

The Entity Control Boundary pattern

This worked example is based on a recent Java EE design pattern called the Entity Control Boundary (ECB) design pattern. It identifies a component part of a system from key perspectives: the entity, the control, and the boundary.

The boundary layer of the component represents the separation of the business and presentation code. In our worked example, we placed the ProjectTaskService EJB in the boundary subpackage, because effectively it is the business façade of the application.

The control layer of the component manages the flow of data to the internal data inside the component. We placed ProjectWebSocketServerEndpoint and ProjectRESTServerEndpoint in the control subpackage because these POJOs are manipulating the entities on behalf of the client side. Of course, it is a matter of debate and decent architectural sense whether business logic is placed either on the boundary or on the control layers in the application's architecture.

Finally, the entity layer of the component is reserved for the application's domain objects. We placed the entity beans Project and Task in the entity subpackage, because they are rich domain objects managed by JPA.

 

Summary


Java EE 7 is a step towards moving the Enterprise platform to a cloud-computing platform. Until we get to the next standard, Java EE 7 offers HTML5 productivity, and it delivers new features such as WebSocket, asynchronous communications over Servlets, RESTful endpoints, and Concurrent Utilities.

We covered in the first chapter the new features in Java EE 7 by first explaining the HTML5 movement. HTML5, we learned, is more than just a markup language, it also embraces semantics, a much improved document structure, APIs for mobile-device awareness, 3D graphics, support for the Canvas drawing, offline storage, styling content through CSS3, and exciting new APIs such as WebSocket and Web Worker.

By now we understand the overall architecture of the Java EE 7 platform. The platform sits between the infrastructure of the hardware including the operating system, network, filing systems, and the JVM-and the thousands of web clients and other business-to-business consumers. All of these are boundaries and are considered endpoints. There are two different profiles available in Java EE 7 standard: the Full and Web Profiles. The Web Profile is a reduced set of JSRs.

We took the time to examine a worked example of Java EE 7 new features with a web application called XenTracker. We saw highlights such as WebSocket and an asynchronous JAX-RS output.

In the subsequent chapters, we will introduce Gradle as a build system. The book's source code relies entirely on Gradle. We will learn how to write the integration tests with Java EE 7 application by using an open source framework called Arquillian. We use some Arquillian to clearly demonstrate the features of Java EE 7 and also rely on the embedded application server container, the reference implementation GlassFish 4 open source application server.

The next chapter gets us further in understanding the DHM of Java EE 7, by rolling the ball with CDI.

About the Author

  • Peter A. Pilgrim

    Peter A. Pilgrim is the 91st Oracle Java Champion, an independent contractor, a professional software developer and designer. Peter is an honors degree graduate of London South Bank University in 1990. He had already secured a Master's degree course for September 1991, but then instead elected to live and work in Germany for a few years in order to beat off the then, economic recession. He spent productive years at a joint-venture company developing spectroscopic scientific software in Fortran 77, C, Solaris, and X Windows. After four years abroad Peter returned to London and continued his career in the industry with more C, C++, and UNIX development. He then leapt at a chance to get into investment banking with Deutsche Bank in 1998. It was at Deutsche Bank a week after joining them that Peter discovered Java was the next best thing since sliced bread, when a colleague dropped out of a programming Java training course. As the substitute person, Peter realized this peculiar Java language and platform was the future and the answer. Peter applied his studies to his day job and learnt Java applets, then Java Swing and switched over to the server side with Java Servlets with web applications involving the Struts framework. In 2004, Peter created the JAVAWUG user group in London for the burgeoning development community who were interested in web development on the Java EE. What started as the Struts Networking Users Group in London quickly expanded to lot of other areas. The JAVAWUG ran for six years until 2010. He built a reputation for travelling to Java technology conferences in the US and Europe and being heavily involved in the wider community. He spoke at several developer conferences including QCon London, ACCU, Devoxx, Devoxx UK, and JavaOne. In 2007, Peter was elected to the Sun Microsystems' Java Champions program. Today, Peter A. Pilgrim is a well-known specialist in Java Enterprise Edition (Java EE) technology, focused on the server-side and the implementation of electronic commerce. Peter has built professional Java EE applications for Blue-chip companies and top-tier investment and retail banks including Lloyds Banking Group, Barclays, UBS, Credit Suisse, Royal Bank of Scotland, and LBi. He is also a fan of Agile practices and Test Driven Development. Peter, currently, lives in South London with his long-term partner Terry, who is a Scottish Diva, business communication coach, and a singer—her voice is phenomenal. Peter writes a blog at http://www.xenonique.co.uk/blog/ and is on Twitter as peter_pilgrim.

    Browse publications by this author

Latest Reviews

(2 reviews total)
Es un libro para tener como referencia de JavaEE, aunque es recomendable para personas que tengan alguna experiencia previa con Java EE.
great deals on great books and videos! :D
Book Title
Access this book, plus 8,000 other titles for FREE
Access now