Friday, 20 July 2018

The Top 5 New Features in Java EE 8

The much-anticipated release of Java Enterprise Edition 8 boasts two exciting new APIs (JSON-Binding 1.0 and Java EE Security 1.0) and improvements to current APIs (JAX-RS 2.1, Bean Validation 2.0, JSF 2.3, CDI 2.0, JSON-P 1.1, JPA 2.2 and Servlet 4.0). This is the first release of Oracle’s enterprise Java platform for nearly four years and it contains hundreds of new features, updated functionality and bug fixes. So what are the best new features? I attempt to answer this highly subjective question in this blog post.

Top 5 new features TL;DR


1. The new Security API: Annotation-driven authentication mechanism: The brand new Security API which contains three excellent new feature: an identity store abstraction, a new security context and a new annotation-driven authentication mechanism that makes web.xml file declarations obsolete. This last one is what I’ll be talking about today.

Java EE 8, Oracle Java Tutorials and Materials, Oracle Java Study Materials

2. JAX-RS 2.1: New reactive client: The new reactive client in JAX-RS 2.1 that embraces the reactive programming style and allows the combination of endpoint results.

3. The new JSON Binding API: The new JSON-binding API that provides a native Java EE solution to JSON serialization and deserialization.

4. CDI 2.0: Use in Java SE: The interesting new feature in CDI 2.0 allows bootstrapping of CDI in Java SE application.

5. Servlet 4.0: Server Push: The server push feature in Servlet 4.0 aligns the servlet specification with HTTP/2.

Are you ready? So let's get to it.

1. The New Security API


Probably, the single most significant new feature added to Java EE 8 is the new security API. The primary motivations for this new API were to simplify, standardize and modernize the way security concerns are handled across containers and implementations. And they have done a great job. The configuration of web authentication has been modernized thanks to three new annotations that make web.xml file declaration redundant. More on this later. The new security context API standardizes the way the servlet and EJB container perform authentication and The new Identity store abstraction to simplifies the use of identity stores. So let's look at the first of these additions.

Annotation-Driven Authentication Mechanism

This feature is all about configuring web security. Which traditional required XML declaration in the web.xml file. This is no longer necessary, thanks to the HttpAuthenticationMechanism interface which represents an HTTP authentication and comes with three built-in CDI-enabled implementations each representing one of the three ways web security can be configured. They are trigger with the use of one of these annotations.

@BasicAuthenticationMechanismDefinition
@FormAuthenticationMechanismDefinition
@CustomFormAuthenticationMechanismDefinition

They replicate the functionality of the classic HTTP basic authentication, form and custom form based authentication already available in the servlet container. For example, to enable Basic authentication all that is necessary is to add the BasicAuthenticationMechanismDefinition annotation to your servlet and that's it.

@BasicAuthenticationMechanismDefinition(realmName="${'user-realm'}")
@WebServlet("/user")
@DeclareRoles({ "admin", "user", "demo" })
@ServletSecurity(@HttpConstraint(rolesAllowed = "user"))
public class UserServlet extends HttpServlet { … }

You can now throw away your XML configurations and use one of these new annotations to drive web security.

2. JAX-RS 2.1: New Reactive Client


Let's look at the new reactive client in JAX-RS 2.1 and how it embraces the reactive programming style. The reactive approach is centered on the idea of data-flows with an execution model that propagates changes through the flow. A typical example would be a JAX-RS method call. When the call returns, the next action is performed on the result of the method call (which might be a continuation, completion or error). You can think of it as an asynchronous pipeline of processes with the next process acting on the result of the previous process and then pass the result of its process to the next one in the chain. The flow of data is composable so you can compose and transform many flows into the one result. The reactive feature is enabled by calling the rx() method on an instance of the Invocation.Builder used to construct client instances. Its return type is a CompletionStage with the parameterised Response type. The CompletionStage interface was introduced in Java 8 and suggests some interesting possibilities. For example, in this code snippet, two calls are made to different endpoints and the results are then combined:

CompletionStage<Response> cs1 = ClientBuilder.newClient()
     .target(".../books/history")
     .request()
     .rx()
     .get();
 
CompletionStage<Response> cs2 = ClientBuilder.newClient()
     .target(".../books/geology")
     .request()
     .rx()
     .get();

cs1.thenCombine(cs2, (r1, r2) ->
     r1.readEntity(String.class) + r2.readEntity(String.class))
     .thenAccept(System.out::println);

3. The new JSON Binding API


Now let's move on to the next great feature. The new JSON Binding API, this API provides a native Java EE solution to JSON serialization and deserialization. Previously if you wanted to serialize and deserialize Java to and from JSON you would have to rely on third-party APIs like Jackson or GSON. Not anymore. With the new JSON Binding API, you have all the feature you could possibly want natively available. It couldn’t be simpler to generate a JSON document from a Java object. Just call the toJson() method and pass it the instance you want to serialize.

String bookJson = JsonbBuilder.create().toJson(book);

And it is just as simple to deserialize a JSON document to a Java object. Just pass the JSON document and target class to the fromJson() method and out pops your Java object.

Book book = JsonbBuilder.create().fromJson(bookJson, Book.class);

But that’s not all.

Behaviour Customisation

It’s possible to customize the default serialization and deserialization behavior by annotating fields, JavaBeans methods, and classes. For example, you could use the @JsonbNillable to customize null handling and @JsonbPropertyOrder annotations to customize property order, which you specify at the class level. You could specify the number format with the @JsonbNumberFormat() annotation and change the name of a field with the @JsonbProperty() annotation.

@JsonbNillable
@JsonbPropertyOrder(PropertyOrderStrategy.REVERSE)
public class Booklet {
   @JsonbProperty("cost")
   @JsonbNumberFormat("#0.00")
   private Float price;
}

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

JsonbConfig jsonbConfig = new JsonbConfig()
    .withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_DASHES)
    .withNullValues(true)
    .withFormatting(true);

Jsonb jsonb = JsonbBuilder.create(jsonbConfig);

Either way, the JSON Binding API provides extensive capabilities for the serialization and deserialization of Java objects.

4. CDI 2.0: Use in Java SE


Now let's move on to the next API. The CDI 2.0 API. This version boasts many new features and one of the more interesting features is the capability to bootstrap CDI in Java SE applications. To use CDI in Java SE the CDI container must be explicitly bootstrapped. This is achieved by calling the static method newInstance() on the SeContainerInitializer abstract class. It returns an SeContainer instance that is a handle to the CDI runtime with which you can do CDI resolution as shown in this code snippet. It has access to the BeanManager which is the core entry point to CDI.

SeContainer seContainer = SeContainerInitializer.newInstance().initialize();
Greeting greeting = seContainer.select(Greeting.class).get();
greeting.printMessage("Hello World");
seContainer.close();

The CDI bean is retrieved with the select() method by passing it the class name of the bean you want to retrieve and use.

Configuration Options

Further configurations can be made to the SeContext by adding interceptors, extensions, alternatives, properties, and decorators.

.enableInterceptors()
.addExtensions()
.selectAlternatives()
.setProperties()
.enableDecorators()

The container is manually shut down by calling the close() method on SeContainer or automatically when using a try-with-resources structure because SeContainer extends the AutoCloseable interface.

5. Servlet 4.0: Server Push


And finally, but not least, the Server Push feature in Servlet 4.0 which aligns the servlet specification with HTTP/2. To understand this feature you first need to know what server push is.

What is Server Push?

Server push is one of the many new features in the HTTP/2 protocol and is designed to anticipates client-side resource requirements by pushing those resources into the browser’s cache, so that when the client sends a request for a webpage and receives a response back from the server, the resources it needs are already in the cache. This is a performance enhancing feature that improves the speed that web pages load.

How is it exposed in Servlet 4.0?

In Servlet 4.0, the Server Push feature is exposed via a PushBuilder instance which is obtained from an HttpServletRequest instance. Take a look at this code snippet. You can see that 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. The menu.css file is pushed and then the ajax.js javascript file is pushed to the client.

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
     PushBuilder pushBuilder = request.newPushBuilder();
     pushBuilder.path("images/header.png").push();
     pushBuilder.path("css/menu.css").push();
     pushBuilder.path("js/ajax.js").push();
     // Return JSP that requires these resources
}

By the time the Servlet doGet() method finishes executing, the resource will have arrived at the browser. The HTML generated from the JSP, that requires these resources, will not need to request them from the server as they will already be browsers cache.

Related Posts