New features in Java EE 8

Start by learning about new apis and capabilities for Java security, JSON binding and processing, HTTP/2, and more

Author: Alex Theedom on November 10, 2017 update | published on September 26, 2017


The highly anticipated Release of Java™ EE 8 is imminent. The first release of the Java Enterprise Platform since June 2013 is half the two-part version of Java EE 9. Oracle has strategically repositioned Java EE to emphasize 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 is the foundation of the core platform.

We’ll take a quick look at the main features in Java EE 8. Highlights include API updates and introductions, as well as new support for HTTP/2, reactive programming and JSON. Start using Java EE specifications and upgrades that will certainly shape enterprise Java programming in the years to come.

New and updated apis

Java EE 8 introduces major and minor updates to the core APIS, such as Servlet 4.0 and Context and Dependency Injection 2.0. It also introduces two new apis — the Java API for JSON binding (JSR 367) and the Java EE Security API (JSR 375). We’ll start with the new API and then explore changes to the long-standing Java EE specification.

JSON binding API

The new JSON Binding API (JSON-B) supports serialization and deserialization between Java objects and RFC 7159-compliant JSON, while remaining JAXB (Java API for XML Binding 2.0) compliant. It provides a default mapping of Java classes and instances to JSON documents that conform to accepted conventions.

Json-b also allows developers to customize serialization and deserialization. You can customize these procedures for individual classes using annotations, or develop custom policies using the runtime configuration builder. The latter approach involves using adapters to support user-defined customization. Json-b integrates nicely with the Java API for JSON Processing (JSON-P) 1.1, which I’ll discuss later in this article.

Go to the JSON binding API

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

  • JsonbBindingProvides a client access point to the JSON binding API. It does this byJsonbBuild instances based on the configuration and parameters of the Settings to do this.
  • JsonbSerialization and deserialization operations are provided through these methodstoJson()andfromJson().

Json-b also describes the ability to plug in an external JSON binding provider, so you’re not constrained by the binding logic that comes with the API.

Use JsonB for serialization and deserialization

Listing 1 serializes and then deserializes an instance of the Book class named Book.

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

Copy the code

An instance of Jsonb returned by the static create() factory method. You can call a number of overloaded toJson() and fromJson() methods on this instance. Also note that the specification does not mandate round-trip equivalence: in the example above, entering a bookJson string into the fromJson() method might not deserialize into an equivalent object.

Json-b also supports binding collection classes and primitive arrays and/or instances (including multidimensional arrays) in much the same way as objects.

Custom Jsonb

Jsonb can customize the default behavior of a method through annotation fields, JavaBeans methods, and classes.

For example, you can customize the null handling and property order using the @Jsonbnillable and @JsonBPropertyOrder annotations, which you will specify at the class level:

Listing 2. Customizing Jsonb
@JsonbNillable
@JsonbPropertyOrder(PropertyOrderStrategy.REVERSE)
public class Booklet {

   private String title;

   @JsonbProperty("cost")
   # @ JsonbNumberFormat (" 0.00 ")
   private Float price;

   private Author author;

   @JsonbTransient
   public String getTitle(a) {
       return title;
   }

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

   // price and author getters/setter removed for brevity
 }
Copy the code

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

Listing 3. Custom JSON structure
{
  "cost": "10.00"."author": {
    "firstName": "Alex"."lastName": "Theedom"}}Copy the code

Alternatively, you can choose to handle custom JsonbConfig using the runtime configuration builder:

Listing 4. Runtime configuration of Jsonb
JsonbConfig jsonbConfig = new JsonbConfig()
    .withPropertyNamingStrategy(
        PropertyNamingStrategy.LOWER_CASE_WITH_DASHES)
    .withNullValues(true)
    .withFormatting(true);

Jsonb jsonb = JsonbBuilder.create(jsonbConfig);
Copy the code

Listing 4 configates JSON-b to use the LOWER_CASE_WITH_DASHES convention to keep null values where they exist and to print the decorated JSON.

Open source binding

As mentioned earlier, you don’t need the out-of-the-box option for JSON-B. Listing 5 shows how to configure the open source binding implementation:

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

Java EE security API

A new Java EE security API was introduced to correct inconsistencies in how security is implemented across servlet containers. This problem is particularly evident in Java Web profiles, mainly because Java EE only enforces how the full Java EE profile must implement the standard API. The new specification also introduces modern features, such as CDI, that existing apis cannot take advantage of.

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, regardless of whether there is a vendor-specific or proprietary solution.

What’s in the specification

The Java EE Security API specification addresses three key issues:

  • HttpAuthenticationMechanismSupport for authentication of servlet containers.
  • IdentityStoreStandard JAASLoginModule.
  • SecurityContextProvides an access point for program security.

I’ll describe each of these components below.

HttpAuthentication mechanism

Java EE has specified two mechanisms for authenticating Web application users: The Java Servlet specification 3.1 (JSR-340) specifies a declarative mechanism for application configuration, And Java Authentication Service Provider Interface for Containers (JASPIC) defines a SPI ServerAuthModule named, It supports the development of authentication modules for handling any type of credential.

Both mechanisms are meaningful and effective, but each is limited from a Web application developer’s point of view. The servlet container mechanism is limited to supporting a narrow range of credential types. While JASPIC is very powerful and flexible, it is also quite complex to use.

Java EE Security API attempts through to solve these problems, a new interface: HttpAuthenticationMechanism. Is essentially a simplified servlet-Container variant of the JASPICServerAuthModule interface that leverishes existing mechanisms while mitigating their limitations.

As a case of the HttpAuthenticationMechanism type of CDI beans, it can be used in the container for injection, and specify only used for the servlet container. The specification explicitly excludes other containers, such as EJB and JMS.

The HttpAuthenticationMechanism interface defines three methods: validateRequest (), secureResponse (), and cleanSubject (). These are very similar to the methods declared on the JASPICServerAuth interface, so developers should be familiar with them. The only method that needs to be overridden is validateRequest(); All other methods have default implementations.

Identity is stored

The identity store is a database that stores user identity data such as user names, group memberships, and information used to authenticate credentials. In the new Java EE Security API, the IdentityStore abstraction IdentityStore is used to interact with the IdentityStore. The purpose is to authenticate the user and retrieve group membership.

When writing specification, it is for the purpose of IdentityStore for HttpAuthenticationMechanism implementation, although this is not required. Using IdentityStore with HttpAuthenticationMechanism enables applications to control its identity in the form of standard and portable storage.

Security context

Together, IdentityStore and HttpAuthenticationMechanism let user authentication powerful new tools. However, system-level security requirements can make declarative models inadequate. This is the problem with SecurityContext: Programmatic security allows Web applications to perform the tests needed to grant or deny access to application resources.

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

Three enterprise standard apis in Java EE 8 have received major releases: Servlet 4.0 (JSR 369), Bean Validation 2.0 (JSR 380), and Context and dependency injection for Java 2.0 (JSR 365).

We’ll visit each of the highlights below.

Applets 4.0

What is server push? Server push predicts client resource demand by pushing these resources into the browser’s cache. When the client sends the request and receives the response from the server, the required resources are already in the cache.

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

Push generator

In Servlet 4.0, server push is exposed through the PushBuilder instance. Listing 6 shows the HttpServletResponse instance that PushBuilder gets from the instance, which is passed to the request handler.

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

PushBuilder pushBuilder = request.newPushBuilder();
pushBuilder.path("images/header.png").push();
pushBuilder.path("css/menu.css").push();
pushBuilder.path("js/ajax.js").push();

// Do some processing and return JSP that 
// requires these resources
}
Copy the code

In Listing 6, the path path() is set on the PushBuilder instance through the method header.png and pushed to the client through the call push(). When the method returns, the path and condition headers are cleared, ready for reuse by the builder.

All major browser vendors implement HTTP/2 over secure connections, so server push is supported only over TLS connections. This means that if the connection is unsafe, newPushBuilder() will return null for the call to the pair, so proper nullchecking is required.

Runtime discovery of servlet mappings

Servlet 4.0 provides a new API for runtime discovery of URL mappings. The goal of the HttpServletMapping interface is to make it easier to identify the mappings that cause servlets to be activated. Inside the API, a servlet map is taken from an instance of HttpServletRequest, which has four methods:

  • getMappingMatch()Returns the matching type.
  • getPattern()Returns the URL pattern that activates the servlet request.
  • getMatchValue()returnStringThe matching
  • getServletName()Returns the fully qualified name of the servlet class activated with the request.
Listing 7. All four methods 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();
Copy the code

In addition to these updates, Servlet 4.0 includes minor housekeeping changes and HTTP Trailer support. The new GenericFilter and HttpFilter classes simplify filter writing and provide general improvements to Java SE 8.

The Bean validation 2.0

Bean Validation 2.0 enhances a number of new features, many of which are requested by the Java developer community. Bean validation is a crosscutting concern, so the 2.0 specification strives to ensure data integrity from the client to the database by applying constraints to values in fields, return values, and method parameters.

These enhancements include validating E-mail addresses, ensuring that numbers are positive or negative, testing dates past or present, and constraints that test fields are not empty or null. They are: @email, @positive, @positiveorZero, @Negative, @negativeOrZero, @pastorPresent, @FutureOrPresent, @Notempty, and @notBlank. Constraints can now also work in a wider range of locations. For example, they can handle parameters of parameterized types. Added support for validating container elements by type parameters, as shown in Listing 8.

Listing 8. Verifying container elements by type
private List<@Size(min = 30) String> chapterTitles;
Copy the code

The updated Bean Validation API enhances the Java SE 8Date and Time types and provides support for java.util.Optional, as shown in Listing 9.

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

private @PastOrPresent Year released;
private @FutureOrPresent LocalDate nextVersionRelease;
private @Past LocalDate publishedDate;
Copy the code

Cascading validation of containers is a handy new feature. Using any of the annotation container’s type arguments @valid causes each element to be validated when the parent object is validated. In Listing 10, each String and Book element is validated as follows:

Listing 10. Cascading validation of container types
Map<@Valid String, @Valid Book> otherBooksByAuthor;
Copy the code

Bean Validation also adds support for custom container types by inserting a value extractor. The built-in constraints are marked repeatable, parameter names are retrieved using reflection, and ConstraintValidator#initialize() is the default method. JavaFX has also gained support for its types.

Java 2.0 context and dependency injection

Context and Dependency Injection API (CDI) has been a backbone technology since Java EE version 6. Since then, it has become a key feature that is easy to develop.

In its latest release, the API has been extended for use with Java SE. To accommodate this change, the CDI specification is divided into three parts: Part 1 deals with common concepts of Java EE and Java SE; Part 2 deals with CDI rules for Java SE; Part 3 deals with rules that apply only to Java EE.

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

Observers and events in CDI 2.0

In CDI 1.1, observers are called synchronously when events are triggered, and there is no mechanism to define the order in which they are executed. The problem with this behavior is that if an observer throws an exception, all subsequent observers are not called and the observer chain stops. In CDI 2.0, this situation was mitigated to some extent by the introduction of the @Priority annotation, which specifies the order in which observers should be called, with smaller numbers called first.

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

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

public void send(AuditEvent auditEvent) {
   event.fire(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
}
Copy the code

It is important to note that with the same Priority calls in an unpredictable order observer, the default order is javax.mail interceptor. The interceptor. Priority. APPLICATION + 500.

Asynchronous events

Another interesting addition to the observer feature is the ability to trigger events asynchronously. A new triggering method (fireAsync()) and the corresponding observer annotation (@observesAsync) have been added to support this functionality. Listing 12 shows an AuditEvent asynchronous firing, along with the observer method that receives notification of the event.

Listing 12. Asynchronous trigger events
@Inject
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) {}
Copy the code

If any observer throws an exception, the CompletionStage will use CompletionException. This instance holds references to all suppressed exceptions thrown during the observer call. Listing 13 shows how you can 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()) {}
                   returnauditEvent; }});return stage;
}
Copy the code

As mentioned earlier, CDI 2.0 also offers comprehensive improvements to Java SE 8 features such as streams, lambda, and repeatable qualifiers. Other notable additions are:

  • A newConfiguratorsInterface.
  • Ability to configure or reject observer methods.
  • Built-in comment text.
  • Function applicationinterceptoronproducer.

A full list of all changes has been published here. See the final draft of the specification for complete details.

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

Although relatively small, Java apis for RESTful Web services (JSR 370), JavaServer Faces 2.3 (JSR 372), and JSON Processing 1.1 (JSR 374) The changes are noteworthy, especially in the inclusion of responsive and functional elements – style programming.

Java API 2.1 for RESTful Web services

The JAX-RS 2.1 API version focuses on two main features: the new reactive client API and support for sending events to the server.

Reactive client API

RESTful Web services have included a client API since version 1.1 that provides an advanced way to access Web resources. Jax-rs 2.1 adds support for reactive programming to this API. The most notable difference is to Invocation Builder, which is used to construct the client instance. The new method shown in Listing 14 of rx() has a return type of CompletionStage and a parameterized type of Response:

Listing 14. Call builder using the new rx() method
CompletionStage<Response> cs1 = ClientBuilder.newClient()
       .target("http://localhost:8080/jax-rs-2-1/books")
       .request()
       .rx()
       .get();
Copy the code

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

Listing 15. The combined result of calling different endpoints
CompletionStage<Response> cs1 = // from Listing 14
CompletionStage<Response> cs2 = ClientBuilder.newClient()
       .target("http://localhost:8080/jax-rs-2-1/magazines")
       .request()
       .rx()
       .get();

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

Events sent by the server

Introduced by W3C in HTML 5 and maintained by the WHATWG community, the Server send Event API (SSE) allows clients to subscribe to events generated by the server. In 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 persistent and remains open until it is closed by either side.

The JAX-RS API includes client and server apis for SSE. The entry point from the client is the SseEventSource interface, which modifies the WebTarget through a configured one, as shown in Listing 16. In this snippet, the client registers a consumer. The consumer outputs to the console, then opens the connection. Lifecycle events are also supported for handlers onComplete and onError.

Listing 16. Jax-rs client API for server sending events
WebTarget target = ClientBuilder.newClient()
    .target("Http://localhost:8080/jax 2 ‑ ‑ ‑ rs 1 / sse/");

try (SseEventSource source = SseEventSource
    .target(target).build()) {
       source.register(System.out::println);
       source.open();
}
Copy the code

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

Listing 17. The server API for the server to send events
@POST
@Path("progress/{report_id}")
@Produces(MediaType.SERVER_SENT_EVENTS)
public void eventStream(@PathParam("report_id")String id,
                        @Context SseEventSink es,
                        @Context Sse sse) {the executorService. Execute (() ‑ > {try {
        eventSink.send(
            sse.newEventBuilder().name("The report ‑ progress." ")
                .data(String.class, 
                "Commencing process for report " + id)
                .build());
            es.send(sse.newEvent("Progress"."25%"));
            Thread.sleep(500);
            es.send(sse.newEvent("Progress"."50%"));
            Thread.sleep(500);
            es.send(sse.newEvent("Progress"."75%"));
    } catch(InterruptedException e) { e.printStackTrace(); }}); }Copy the code

In Listing 17, 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 that the media type is a new type of text/event-stream dedicated to event streams.

The broadcast server sends the event

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

Listing 18. Broadcast to all registered subscribers
@Path("/")
@Singleton
public class SseResource {

    @Context
    private Sse sse;
    
    private SseBroadcaster broadcaster;
    
    @PostConstruct
    public void initialise(a) {
       this.broadcaster = sse.newBroadcaster();
    }
    
    @GET
    @Path("subscribe")
    @Produces(MediaType.SERVER_SENT_EVENTS)
    public void subscribe(@Context SseEventSink eventSink) {
       eventSink.send(sse.newEvent("You are subscribed"));
       broadcaster.register(eventSink);
    }
    
    @POST
    @Path("broadcast")
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public void broadcast(@FormParam("message") String message) { broadcaster.broadcast(sse.newEvent(message)); }}Copy the code

The example in Listing 18 receives a subscription request /subscribe on a URI. Subscription request SseEventSink will create an instance for the subscriber and SseBroadcaster will register the instance with the resource. The message /broadcast broadcast to all subscribers is retrieved from the web form submitted to the URL and processed by the broadcast() method.

Other updates to JAX-RS 2.1

Jax-rs 2.1 brings some minor changes worth mentioning:

  • theResourceMethods are now supportedCompletionStage<T>As a return type.
  • Added full support for the Java API for JSON processing (JSON-P) and the Java API for JSON binding (Json-b).
  • @PrioritySupport for all providers, including entity providers — i.eMessageBodyReaderandMessageBodyWriter.
  • The default has been removed for all environments that do not support the Java Concurrency Utilities API.

JavaServer Faces 2.3

JavaServer Faces (JSF) version 2.3 aims for community-required functionality and better CDI and WebSocket integration. It solves a large number of problems (hundreds at last count) and tries to solve many small but unresolved ones. JSF is a mature technology, so the problems that are being solved are previously difficult or minor. Among them, JSF 2.3 improves on Java SE 8 with support for JavaDate/Time types and class-level bean validation. For the full list, I recommend downloading the final version specification.

Server push in JSF 2.3

JSF 2.3 integrates Servlet 4.0 support for server push. JSF is well suited for identifying required resources in the server push implementation, and is now set to do this in the RenderResponsePhase lifecycle phase.

JSON processing 1.1

Json-p gets point publishing to keep it up to date with the latest IEFT standards. These are JSON Pointer, JSON Patch, and JSON Merge Patch.

Query JSON also through JsonCollectors in javax.json.streams.

JSON pointer

A JSON pointer defines a string expression that identifies a specific value within a JSON document. Similar to XPointer, used to identify fragments in XML, JSON Pointers refer to values in JSON documents. For example, given the JSON document in Listing 19, the second element in the Topics array will reference /topics/1 through the JSON pointer expression.

Listing 19. JSON object with array
{
 "topics": 
   "Cognitive"."Cloud"."Data"."IoT"."Java" }
Copy the code

The entry API is the JsonPointer interface. Create the instance by calling the static factory method on the Json class with createPointer(). The code snippet in Listing 20 creates an aJsonPointer and references the second element in the theme array:

Listing 20. JsonPointer that references an array element
Json.createPointer("/topics/1").getValue(jsonTopicData);
Copy the code

The JsonPointerAPI also provides adding, replacing, and removing properties through JSON files that vary. Listing 21 adds the value “Big Data” to the list of topics:

Listing 21. Adding a value to an array using JsonPointer
Json.createPointer("/topics/0")
    .add(jsonTopicData, Json.createValue("Big Data"));
Copy the code

JSON patch

JSON Patch represents a series of operations to be applied to the target JSON document in JSON pointer notation. It can perform operations add, copy, move, remove, replace, and test.

The JsonPatchBuilder interface is the gateway to the API and creates the Json class createPatchBuilder() from the static method. The JSON pointer expression is passed to one of the action methods and applied to the JSON document. Listing 22 shows replacing the first element of the theme array with the value “Spring 5” :

Listing 22. JsonPatchBuilder replaces the values in the array
Json.createPatchBuilder()
    .replace("/topics/0"."Spring 5")
    .build()
    .apply(jsonTopicData);
Copy the code

Multiple actions can be linked together and 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 the target JSON document. Table 1 shows the three operations available.

Table 1. Select merge patch operations
surgery The target repair The results of
Instead of {” color “:” blue “} {} “red” {} “red”
add {” color “:” blue “} {} “red” {” color “: empty}
eliminate {} “red” {” color “:” blue “, “color” : “red”} {}

The static method Json on the createMergePatch() class provides an instance of type JsonMergePatch to which you can pass the patch. The target JSON is then passed to the method of the apply() resulting JsonMergePatch instance and the patch is applied. Listing 23 shows how to perform the actions in Replace table 1.

Listing 23. Replacing values with JSON Merge Patch
Json.createMergePatch(Json.createValue("{\"colour\":\"blue\"}"))
    .apply(Json.createValue("{\"colour\":\"red\"}"));
Copy the code

JsonCollectors

With the introduction of the JsonCollectors class into the Javax.json. streams package, querying JSON has become much easier. Listing 24 shows the array of topics filtered by letter C and collects the results into the JsonArray in A.

Listing 24. Using JsonCollectors to filter and collect the JsonArray
JsonArray topics = jsonObject.getJsonArray("topics")
    .stream()
    .filter(jv -> ((JsonString) jv).getString().startsWith("C"))
    .collect(JsonCollectors.toJsonArray());
Copy the code

conclusion

Java EE is repositioning itself for the cloud, and the first half of the planned two-part release adopts technologies that advance this goal. Work on Java EE 9 will begin as soon as Java EE 8 is released. The current goal is to release Java EE 9 within a year.

Enhancements to the Java EE Security API are already on the Roadmap for Java EE 9, which will include features not suitable for Java EE Security 1.0. Developers can also expect to see deep support for enterprise development in the cloud, with more Java EE technologies using the Reactive manifesto as a blueprint to improve resilience and extensibility.

My wish list for Java EE 9 includes improvements to microservices-friendly technologies. The two apis that support microservices are Configuration API 1.0 (JSR 382) and Health Check, both of which have been removed from Java EE 8 but are being considered for the next update.

I also welcome the recent announcement that Eclipse will adopt Java EE. I expect open source foundations to accept more community involvement from vendors and developers. We should expect an accelerated pace of Java EE releases and continued enhancements to this powerful enterprise specification.