2021 Call for Code Awards: Live from New York, with SNL’s Colin Jost! Learn more

What’s new in Java EE 8

The much-anticipated release of Java™ EE 8 is nearly upon us. This first release of the Java enterprise platform since June 2013 is half of a two-part release culminating with Java EE 9. Oracle has strategically repositioned Java EE, emphasizing technologies that support cloud computing, microservices, and reactive programming. Reactive programming is now woven into the fabric of many Java EE APIs, and the JSON interchange format underpins the core platform.

We’ll take a whistle-stop tour of the main features found in Java EE 8. Highlights include API updates and introductions, and new support for HTTP/2, reactive programming, and JSON. Get started with the Java EE specifications and upgrades that will surely shape enterprise Java programming for years to come.

New and updated APIs

Java EE 8 introduces major and minor updates to core APIs such as Servlet 4.0 and Context and Dependency Injection 2.0. It also introduces two new APIs—Java API for JSON Binding (JSR 367) and the Java EE Security API (JSR 375). We’ll start with the new APIs, then explore changes to longstanding Java EE specifications.

JSON Binding API

The new JSON Binding API (JSON-B) supports serialization and deserialization between Java objects and RFC 7159-compatible JSON, while maintaining consistency with JAXB (Java API for XML Binding 2.0). It provides default mappings for Java classes and instances to JSON documents that conform to accepted conventions.

JSON-B also allows developers to customize serialization and deserialization. You can use annotations to customize these processes for individual classes, or use the runtime configuration builder to develop custom strategies. The latter approach includes using adapters to support user-defined customization. JSON-B integrates well with the Java API for JSON Processing (JSON-P) 1.1, which I will discuss later in this article.

Entry to the JSON Binding API

Two interfaces provide entry to the new JSON Binding API: JsonbBinding and Jsonb.

  • JsonbBinding provides the client access point to the JSON Binding API. It does this by building Jsonb instances based on set configurations and parameters.
  • Jsonb provides serialization and deserialization operations via the methods toJson() and fromJson().

JSON-B also describes functionality to plug-in external JSON Binding providers, so you aren’t restricted to the binding logic that comes with the API.

Serialization and deserialization with JsonB

Listing 1 serializes and then deserialize an instance of the Book class called book.

Listing 1. Simplest example of serialization and deserialization
String bookJson = JsonbBuilder.create().toJson(book);
Book book = JsonbBuilder.create().fromJson(bookJson, Book.class);

The static create() factory method returns an instance of Jsonb. You may call a number of overloaded toJson() and fromJson() methods on that instance. Note, also, that the specification does not mandate round-trip equivalences: in the above example, feeding the bookJson string into the fromJson() method might not deserialize to an equivalent object.

JSON-B also supports binding collection classes and arrays of primitives and/or instances—including multi-dimensional arrays—in much the same way as objects.

Customizing Jsonb

It’s possible to customize the default behaviour of Jsonb methods by annotating fields, JavaBeans methods, and classes.

For example, you could use the @JsonbNillable and @JsonbPropertyOrder annotations to customize null handling and property order, which you would specify at the class level:

Listing 2. Customizing Jsonb
public class Booklet {

   private String title;

   private Float price;

   private Author author;

   public String getTitle() {
       return title;

   public void setTitle(String title) {
       this.title = title;

   // price and author getters/setter removed for brevity

A call to the method toJson() produces the JSON structure shown in Listing 3.

Listing 3. Customized JSON structure
  "cost": "10.00",
  "author": {
    "firstName": "Alex",
    "lastName": "Theedom"

Alternatively you could choose to handle customization with the runtime configuration builder, JsonbConfig:

Listing 4. Runtime configuration of Jsonb
JsonbConfig jsonbConfig = new JsonbConfig()

Jsonb jsonb = JsonbBuilder.create(jsonbConfig);

Listing 4 configures JSON-B to use the LOWER_CASE_WITH_DASHES convention to preserve nulls where they exist, and to output prettified JSON.

Open source binding

As previously mentioned, you needn’t use out-of-the-box options for JSON-B. Listing 5 shows how to configure an open source binding implementation:

Listing 5. Open source binding configuration
JsonbBuilder builder = JsonbBuilder.newBuilder("aProvider");

Java EE Security API

The new Java EE Security API was introduced to correct inconsistencies in how security concerns are implemented across servlet containers. This issue has been especially noticeable in the Java web profile, primarily because Java EE only mandates how the full Java EE profile must implement standard APIs. The new specification also introduces modern capabilities such as CDI, which existing APIs don’t leverage.

The beauty of this API is that it provides an alternative way to configure identity stores and authentication mechanisms, but does not replace existing security mechanisms. Developers should welcome the opportunity to enable security in Java EE web applications, with or without vendor-specific or proprietary solutions.

What’s in the specification

The Java EE Security API specification addresses three key concerns:

  • HttpAuthenticationMechanism supports authentication for the servlet container.
  • IdentityStore standardizes the JAAS LoginModule.
  • SecurityContext provides an access point for programmatic security.

I’ll touch on each of these components below.


Java EE already specifies two mechanisms for authenticating web application users: The Java Servlet specification 3.1 (JSR-340) specifies a declarative mechanism for application configuration, while JASPIC (Java Authentication Service Provider Interface for Containers) defines an SPI called ServerAuthModule, which supports the development of authentication modules to handle any credential type.

Both of these mechanisms are meaningful and effective, but each is limited from the point of view of a web application developer. The servlet container mechanism is restricted to supporting only a small range of credential types. And while JASPIC is very powerful and flexible, it is also rather complicated to use.

The Java EE Security API seeks to resolve these issues with a new interface: HttpAuthenticationMechanism. Essentially a simplified, servlet-container variant of the JASPIC ServerAuthModule interface, it leverages existing mechanisms while alleviating their limitations.

An instance of the HttpAuthenticationMechanism type is a CDI bean, which is available to the container for injection and is specified for the servlet container only. The specification explicitly excludes other containers such as EJB and JMS.

The HttpAuthenticationMechanism interface defines three methods: validateRequest(), secureResponse(), and cleanSubject(). These closely resemble the methods declared on the JASPIC ServerAuth interface, so they should be familiar to developers. The only method required to be overridden is validateRequest(); all of the other methods have default implementations.


An identity store is a database that stores user identity data such as user name, group membership, and information used to verify credentials. In the new Java EE Security API, an identity store abstraction called IdentityStore is used to interact with identity stores. Its purpose is to authenticate users and retrieve group memberships.

As the specification is written, it is intended that IdentityStore be used by HttpAuthenticationMechanism implementations, although that isn’t a requirement. Using IdentityStore and HttpAuthenticationMechanism together enables an application to control its identity store in a portable and standard way.


Together, IdentityStore and HttpAuthenticationMechanism make a powerful new tool for user authentication. Nevertheless, system-level security requirements could make the declarative model insufficient. This is where SecurityContext comes in: programmatic security allows a web application to perform the tests required to grant or deny access to application resources.

Major updates: Servlet 4.0, Bean Validation 2.0, CDI 2.0

Three enterprise standard APIs get major releases in Java EE 8: Servlet 4.0 (JSR 369), Bean Validation 2.0 (JSR 380), and Contexts and Dependency Injection for Java 2.0 (JSR 365).

We’ll visit the highlights of each one below.

Servlet 4.0

The Java Servlet API is one of the earliest and most ingrained APIs for Java enterprise developers. It debuted in 1999, in J2EE 1.2, and now plays an important role in Java Server Pages (JSP), JavaServer Faces (JSF), JAX-RS, and MVC (JSR 371).


In Servlet 4.0, server push is exposed via a PushBuilder instance. Listing 6 shows a PushBuilder instance obtained from an HttpServletResponse instance, which is passed to a request handling method.

Listing 6. PushBuilder in a servlet
protected void doGet(HttpServletRequest request,
           HttpServletResponse response)
           throws ServletException, IOException {

PushBuilder pushBuilder = request.newPushBuilder();

// Do some processing and return JSP that 
// requires these resources

In Listing 6, the path to the header.png is set on the PushBuilder instance via the path() method, and pushed to the client by calling push(). When the method returns, the path and conditional headers are cleared in readiness for the builder’s reuse.

All major browser vendors implement HTTP/2 over a secure connection, and thus the server push feature is supported only over a TLS connection. This means that if the connection is not secured, a call to newPushBuilder() will return null and therefore an appropriate null check is required.

Runtime discovery of servlet mappings

Servlet 4.0 offers a new API to be used for the runtime discovery of URL mappings. The goal of the HttpServletMapping interface is to make it easier to determine the mapping that caused a servlet to be activated. Inside the API, a servlet mapping is obtained from an HttpServletRequest instance, which has four methods:

  • getMappingMatch() returns the type of the match.
  • getPattern() returns the URL pattern that activated the servlet request.
  • getMatchValue() returns the String that was matched
  • getServletName() returns the fully qualified name of the servlet class that was activated with the request.

Listing 7. All four method on the HttpServletMapping interface
HttpServletMapping mapping = request.getHttpServletMapping();
String mapping = mapping.getMappingMatch().name();
String value = mapping.getMatchValue();
String pattern = mapping.getPattern();
String servletName = mapping.getServletName();

In addition to these updates, Servlet 4.0 includes smaller housekeeping changes and support for HTTP Trailer. New GenericFilter and HttpFilter classes simplify writing filters and effect a general uplift to Java SE 8.

Bean Validation 2.0

Bean Validation 2.0 has been enhanced with a range of new features, many of them requested by the Java developer community. Bean validation is a cross-cutting concern, so the 2.0 specification seeks to ensure data integrity from the client to the database, by applying constraints to values in fields, return values, and method parameters.

Among these enhancements are constraints that validate email addresses, ensure that numbers are positive or negative, test if dates are past or present, and test that fields are not empty or null. These are: @Email, @Positive, @PositiveOrZero, @Negative, @NegativeOrZero, @PastOrPresent, @FutureOrPresent, @NotEmpty, and @NotBlank. Constraints can now act in a wider range of locations, as well. As an example, they can proceed arguments of parameterized types. Support for validating container elements by type arguments has been added, as shown in Listing 8.

Listing 8. Validation container elements by type

private List<@Size(min = 30) String> chapterTitles;

The updated Bean Validation API uplifts Java SE 8’s Date and Time types and offers support for java.util.Optional, as shown in Listing 9.

Listing 9. Bean Validation 2.0 supports the Date and Time types and Optional
Optional<@Size(min = 10) String> title;

private @PastOrPresent Year released;
private @FutureOrPresent LocalDate nextVersionRelease;
private @Past LocalDate publishedDate;

Cascaded validation of containers is a handy new feature. Annotating any type argument of a container with @Valid will cause every element to be validated when the parent object is validated. In Listing 10, every String and Book element will be validated as shown:

Listing 10. Cascaded validation of container types
Map<@Valid String, @Valid Book> otherBooksByAuthor;

Bean Validation also adds support for custom container types by plugging in value extractors. Built-in constraints are marked as repeatable, parameter names are retrieved using reflection, and ConstraintValidator#initialize() is a default method. JavaFX also gets support for its types.

Contexts and Dependency Injection for Java 2.0

The Context and Dependency Injection API (CDI) is a backbone technology that has been in Java EE since version 6. Since then it has become a key feature for ease of development.

In its newest incarnation, the API has been extended to work with Java SE. To accommodate this change, the CDI specification has been split into three sections: Part 1 deals with concepts common to both Java EE and Java SE; Part 2 deals with rules just for CDI with Java SE; and Part 3 deals with rules just for Java EE.

CDI 2.0 also makes an important change to the way observers and events behave and interact.

Observers and events in CDI 2.0

In CDI 1.1, observers are invoked synchronously when an event is fired, with no mechanism to define the order in which they are executed. The issue with this behavior is that if an observer throws an exception, all subsequent observers are not invoked and the observer chain ceases. In CDI 2.0, this has been mitigated to some extent by introducing the @Priority annotation, which specifies the order in which observers should be called, with smaller numbers being called first.

Listing 11 shows an event firing and two observers with different priorities. Observer AuditEventReciever1 (priority 10) is called before AuditEventReciever2 (priority 100).

Listing 11. Demonstration of observer priority
private Event<AuditEvent> event;

public void send(AuditEvent auditEvent) {

// AuditEventReciever1.class
public void receive(@Observes @Priority(10) AuditEvent auditEvent) {
    // react to event

// AuditEventReciever2.class 
public void receive(@Observes @Priority(100) AuditEvent auditEvent) {
    // react to event

It’s worth noting that observers with the same priority are invoked in an unpredictable order and the default order is javax.interceptor.Interceptor.Priority.APPLICATION + 500.

Asynchronous events

Another interesting addition to the observer feature is the capability to fire events asynchronously. A new firing method (fireAsync()) and a corresponding observer annotation (@ObservesAsync) have been added to support this feature. Listing 12 shows an AuditEvent being fired asynchronously, and the observer methods that receive notification of the event.

Listing 12. Firing events asynchronously
private Event<AuditEvent> event;

public CompletionStage<AuditEvent> sendAsync(AuditEvent auditEvent) {
   return event.fireAsync(auditEvent);

// AuditEventReciever1.class
public void receiveAsync(@ObservesAsync AuditEvent auditEvent) {}

// AuditEventReciever2.class
public void receiveAsync(@ObservesAsync AuditEvent auditEvent) {}

If an exception is thrown by any of the observers, the CompletionStage will complete with CompletionException. This instance holds a reference to all the suppressed exceptions thrown during observer invocation. Listing 13 shows how you might manage this scenario.

Listing 13. Managing exceptions in asynchronous observer

public CompletionStage<AuditEvent> sendAsync(AuditEvent auditEvent) {
   System.out.println("Sending async");
   CompletionStage<AuditEvent> stage = event.fireAsync(auditEvent)
           .handle((event, ex) -> {
               if (event != null) {
                   return event;
               } else {
                   for (Throwable t : ex.getSuppressed()) {}
                   return auditEvent;

   return stage;

As previously mentioned, CDI 2.0 also gets a general uplift to Java SE 8 features such as streams, lambdas, and repeatable qualifier. Other noteworthy additions are:

  • A new Configurators interface.
  • Capability to configure or veto observer method.
  • Built-in annotation literals.
  • Capability to apply interceptor on producer.

A full list of all changes has been posted here. See the spec’s proposed final draft for full details.

Minor updates: JAX-RS 2.1, JSF 2.3, JSON-P 1.1

While relatively minor, changes to Java API for RESTful Web Services (JSR 370), JavaServer Faces 2.3 (JSR 372), and the Java API for JSON Processing 1.1 (JSR 374) are worth noting, especially for embracing elements of reactive and functional-style programming.

Java API for RESTful Web Services 2.1

The JAX-RS 2.1 API release focuses on two main features: a new reactive client API and support for server sent events.

Reactive client API

RESTful Web Services has included a client API since release 1.1, offering a high-level way to access web resources. JAX-RS 2.1 adds support for reactive programming to this API. The most noticeable difference is to Invocation.Builder, which is used to construct client instances. The new rx() method, shown in Listing 14, has a return type of CompletionStage, with the parameterized type of Response:

Listing 14. Invocation builder with the new rx() method
CompletionStage<Response> cs1 = ClientBuilder.newClient()

The CompletionStage interface was introduced in Java 8, and suggests some interesting possibilities. In Listing 15, two calls are made to different endpoints and the results are combined:

Listing 15. Combined results from calling different endpoints
CompletionStage<Response> cs1 = // from Listing 14
CompletionStage<Response> cs2 = ClientBuilder.newClient()

cs1.thenCombine(cs2, (r1, r2) -> 
    r1.readEntity(String.class) + r2.readEntity(String.class))

Server-sent events

Introduced in HTML 5 by the W3C and maintained by the WHATWG community, the Server Sent Events API (SSE) allows a client to subscribe to server-generated events. In an SSE architecture, a one-way channel is created from the server to the client, through which the server can send multiple events. The connection is long-lived and kept open until it is closed by either side.

The JAX-RS API includes a client and a server API for SSE. The entry point from the client side is the SseEventSource interface, which is modified with a configured WebTarget, as shown in Listing 16. In this code snippet, the client registers a consumer. The consumer outputs to the console, and then opens the connection. Handlers for onComplete and onError life-cycle events are also supported.

Listing 16. JAX-RS client API for server sent events
WebTarget target = ClientBuilder.newClient()

try (SseEventSource source = SseEventSource
    .target(target).build()) {

On the other end, the SSE server API accepts the connection from the client and sends events to all connected clients:

Listing 17. Server API for server sent events
public void eventStream(@PathParam("report_id")String id,
                        @Context SseEventSink es,
                        @Context Sse sse) {
    executorService.execute(() ‑> {
    try {
                "Commencing process for report " + id)
            es.send(sse.newEvent("Progress", "25%"));
            es.send(sse.newEvent("Progress", "50%"));
            es.send(sse.newEvent("Progress", "75%"));
    } catch (InterruptedException e) {

In Listing 17, the SseEventSink and Sse resources are injected into the resource method. The Sse instance gets a new outbound event builder and sends progress events to the client. Note the media type is a new text/event-stream type used exclusively with event streams.

Broadcasting server sent events

Events can be broadcast to multiple clients simultaneously. This is done by registering multiple SseEventSink instances on the SseBroadcaster:

Listing 18. Broadcasts to all registered subscribers
public class SseResource {

    private Sse sse;
    private SseBroadcaster broadcaster;
    public void initialise() {
       this.broadcaster = sse.newBroadcaster();
    public void subscribe(@Context SseEventSink eventSink) {
       eventSink.send(sse.newEvent("You are subscribed"));
    public void broadcast(@FormParam("message") String message) {

The example in Listing 18 receives a subscription request on the URI /subscribe. The subscription request provokes the creation of an SseEventSink instance for that subscriber, which is then registered with the SseBroadcaster for the resource. The message broadcast to all subscribers is retrieved from a web page form submitted to the URL /broadcast, then handled by the broadcast() method.

Additional updates to JAX-RS 2.1

JAX-RS 2.1 brings in a few more small changes worth mentioning:

  • The Resource method now supports CompletionStage<T> as a return type.
  • Full support has been added for Java API for JSON Processing (JSON-P) and the Java API for JSON Binding (JSON-B).
  • @Priority is supported for all providers including entity providers—namely MessageBodyReader and MessageBodyWriter.
  • Defaults have been removed for all environments not supporting the Java Concurrency Utilities API.

JavaServer Faces 2.3

The JavaServer Faces (JSF) 2.3 release targets community-requested features and better integration for CDI and websockets. It hits a substantial number of issues (several hundred at the last count) and has attempted to redress many small but outstanding issues. JSF is a mature technology, so the issues being addressed now are ones that have been hard to solve previously, or they are minor. Among these, JSF 2.3 gets an uplift to Java SE 8 with support for Java Date/Time types and class-level bean validation. For a complete list I suggest downloading the final release specification.

Server push in JSF 2.3

JSF 2.3 integrates Servlet 4.0’s support for server push. JSF is ideally positioned to identify needed resources in a server push implementation, and is now set up to do that during the RenderResponsePhase lifecycle phase.

JSON Processing 1.1

JSON-P get a point release, bringing it up to date with the latest IEFT standards. These are JSON Pointer, JSON Patch, and JSON Merge Patch.

Querying JSON is also simplified by the new JsonCollectors class, introduced in javax.json.streams.


A JSON Pointer defines a string expression that identifies a specific value within a JSON document. Akin to XPointer, which is used to identify fragments within XML, a JSON Pointer references values within a JSON document. For example, given the JSON document in Listing 19, the second element in the topics array would be referred to via the JSON pointer expression of /topics/1.

Listing 19. A JSON object with an array
   "Java" }

The entry API is the JsonPointer interface. An instance is created by calling the static factory method createPointer() on the Json class. The code snippet in Listing 20 creates a JsonPointer and references the second element in the topic array:

Listing 20. JsonPointer referencing an array element

The JsonPointer API can also mutate the JSON document by adding, replacing, and removing properties. Listing 21 adds the value “Big Data” to the topics list:

Listing 21. Add value to array using JsonPointer
    .add(jsonTopicData, Json.createValue("Big Data"));

JSON Patch

JSON Patch expresses a sequence of operations to apply against a target JSON document in JSON Pointer notation. It can perform the operations add, copy, move, remove, replace, and test.

The JsonPatchBuilder interface is the gateway into this API, and is created from the static method createPatchBuilder() on the Json class. A JSON Pointer expression is passed to one of the operation methods and applied to a JSON document. Listing 22 shows the replacement of the first element of the topics array with the value of “Spring 5”:

Listing 22. JsonPatchBuilder replacing a value in an array
    .replace("/topics/0", "Spring 5")

Multiple operations can be chained and are applied sequentially to the result of the previous patch result.

JSON Merge Patch

JSON Merge Patch is a JSON document that describes a set of changes to be made to a target JSON document. Table 1 shows three of the operations available.

Table 1. Select merge patch operations
Operation Target Patch Result
Replace {“color”:”blue”} {“color”:”red”} {“color”:”red”}
Add {“color”:”blue”} {“color”:”red”} {“color”: null}
Remove {“color”:”red”} {“color”:”blue”,”color”:”red”} {}

The static method createMergePatch() on the Json class provides an instance of the type JsonMergePatch, to which you may pass the patch. Then the apply() method of the resulting JsonMergePatch instance is passed the target JSON, and the patch is applied. Listing 23 shows how to perform the replace operation from Table 1.

Listing 23. Use JSON Merge Patch to replace a value


Querying JSON has become much simpler with Java 8’s introduction of the JsonCollectors class to the javax.json.streams package. Listing 24 shows the topics array being filtered by the letter c and collecting the result into a JsonArray.

Listing 24. Using JsonCollectors to filter and collect to a JsonArray
JsonArray topics = jsonObject.getJsonArray("topics")
    .filter(jv -> ((JsonString) jv).getString().startsWith("C"))


Java EE is being repositioned for the cloud, and the first half of the planned two-part release features technology promoting that goal. As soon as Java EE 8 is out, work will begin on Java EE 9. Currently the goal is to release Java EE 9 within one year.

Already on the roadmap for Java EE 9 is an enhancement to the Java EE Security API, which will include features that didn’t fit into Java EE Security 1.0. Developers can also expect to see deepening support for enterprise development in the cloud, with more Java EE technologies using the reactive manifesto as a blueprint to promote resilience and scalability.

My wishlist for Java EE 9 includes a boost for microservices-friendly technology. Two APIs that would support microservices are Configuration API 1.0 (JSR 382) and Health Check, both dropped for Java EE 8 but under consideration for the next update.

I also welcome the recent announcement that Java EE is being adopted by Eclipse. I expect the open source foundation will embrace greater community involvement from vendors and developers. We should expect an accelerated cadence of Java EE releases, and ongoing enhancements to this powerful enterprise specification.