Thursday, October 27, 2022 - 05:00
  • Share this article:

After a lot of hard work, Jakarta EE 10 was finally released on September 22, 2022. This not only marked a great milestone for the Jakarta EE community but was proof that Jakarta EE was able to move forward under the governance of the Eclipse Foundation. 

When Java EE was moved to the Eclipse Foundation in September 2017, a massive effort got underway to address the IP and copyright transfer, which culminated in Jakarta EE 9/9.1. This release laid a stable foundation for the specifications, rebranded the project, and renamed the namespace from javax to jakarta. However, end users had not benefited from any additional functionalities since Java EE’s release in 2016. 

But that stable foundation made it possible to provide end users with many feature updates in Jakarta EE 10. This article briefly outlines some of the updates and demonstrates how to use Open Liberty to access the implementations of Jakarta EE 10.

What’s New in Jakarta EE 10

Jakarta EE 10 introduces a new profile, called Core Profile, which was created to be used by MicroProfile. Core Profile also highlights the specs most relevant to cloud-native applications and can be used by new runtimes to embrace Jakarta EE technologies.

The Jakarta EE 10 Core Profile includes seven specifications, as shown in the following illustration.

image 1 - jakarta ee 10

The Jakarta RESTful Web Services 3.1 specification provides Multipart as a media type. Multipart was widely supported by a number of languages and even Java libraries including Open Liberty, via internal IMultipartBody and IAttachment APIs. However,there was not a standard for multipart support in Jakarta EE before this release, with the introduction of the, spec defined, EntityPart API.

We are looking at how to use this feature from both the producer and consumer perspective. Below are the snippets that demonstrate how to produce a Multipart.

This code snippet demonstrates how to produce a list of EntityPart, which might be in multiple files:

@GET

@Produces(MediaType.MULTIPART_FORM_DATA)

List<EntityPart> getFiles(…) {

     List<EntityPart> parts = new ArrayList<>();
     …

     for(File f: dir.listFiles()) {

         parts.add(EntityPart.withFileName(f.getName)

                    .content(new FileInputStream)

                    .mediaType(“application/pdf”)

                    .build();

     }

     return parts;

}

When receiving the Multipart info, you can use one of the two formats to consume the information:

@Path("/apply")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response postSomething (List<EntityPart> parts) 

     for (EntityPart part : parts) {

         String name = part.getName();

         Optional<String> fileName = part.getFileName(); 

         InputStream is = part.getContent();

         doSomethingWithPart(name, filename, is);

     }
     return Response.ok("Application received").build();
}

You can also use this snippet:

@Path("/apply")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response postSomething (
     @FormParam(”part1") String name, 
     @FormParam(”part2") InputStream myStr, 
     @FormParam(”part3") EntityPart resume) 

     processApplication(name, myStr, resume);
     return Response.ok("Application received").build();
}

 

CDI Lite Now Supports Build Time Compilation


The other significant specification update in Jakarta EE 10 is CDI Lite. CDI Lite is not a new specification, but a new section in CDI 4.0. This means that any runtime that supports CDI 4.0 automatically supports CDI Lite. 

The CDI Lite section supports build time compilation so that the runtimes that use GraalVM can still take advantage of the rich injection framework provided by CDI Lite. 

CDI Lite supports:

  • Basic Injection: @Inject and programmatically bean lookup via CDI.current().get() are supported.
  • Supported Scopes: The supported scopes are @Dependent, @ApplicationScoped, @RequestScoped. CDI Lite does not support @SessionScoped and @ConversationScoped beans.
  • beans.xml (bean-discovery-mode=annotated/none): A beans.xml must be present in your archive , otherwise CDI Lite will not perform an injection. An empty beans.xml and beans.xml with bean-discovery-mode=annotated are the same. Any other content of the beans.xml will be ignored. The only valid value for bean-discovery-mode is either annotated or none. If you specify bean-discovery-mode=all, you should expect an error to be thrown in a CDI Lite-only runtime. The location of beans.xml must be under META-INF/.
  • Interceptor and Alternative: You must use @Priority to globally enable the interceptors or alternatives. The option to enable per archive via beans.xml is not supported. 
  • Events: Events can be delivered or observed synchronously and asynchronously. New events of Shutdown and Startup are also available to state when the application starts or shuts down, so that event observers can observe these events and perform any necessary actions.

  public void observStartup(@Observes Startup started){

  System.out.println("Observed startup event!");

}

public void observeShutdown(@Observes Shutdown shutdown){

  System.out.println("Observed shutdown event again!");

}

  • Extension Framework: The extension framework in CDI helped make CDI a great success. However, the extension framework of CDIExtension relies on reflection and only operates at runtime. That does not work for build time compilation, which needs to be reflection-free. To satisfy this need, CDI Lite uses a new reflection-free language model and an extension framework that works for both build time and runtime. In this case, any runtime that builds on GraalVM, such as Quarkus or Micronault, can use the extension framework at build time, while other runtimes that use the extension framework at runtime, such as Open Liberty, can do so.

Jakarta JSON-P 2.1 Supports Duplication Keys 

The Jakarta JSON-P specification supports the duplication of keys and specifies that the last occurrence of the duplication will be the winner:

JsonConfig.KEY_STRATEGY=LAST

JSON-P also added some interface for primitives, lists, and objects:
 

jakarta.json.JsonNumber,

jakarta.json.JsonString,

jakarta.json.JsonArray,

jakarta.json.JsonObject

Significant Changes Made to JSON-B 3.0

The JSON-B specification underwent multiple changes, and though it operates on the top of JSON-P, some of those changes are backwards-incompatible. Changes include:

  • Deserializing of null to be JsonValue.NULL
  • @JsonbTypeDeserializer and @JsonbTypeAdapter annotations can be used on JsonCreator parameters
  • Provides a default PropertyVisibilityStrategy implementation
  • Defines a new Class-level annotation for PropertyNamingStrategy definition
  • Deprecates @JsonbProperty.nillable()
  • Makes @JsonbCreator parameters optional. This change breaks backward compatibility. Therefore, this specification release is a major release.

Minor Updates to Jakarta Common Annotations 2.1

There were also a few minor updates made to the Jakarta Common Annotations specification:

  • Allow @Priority to be used in all kinds of targets: This update allows @Priority to be used on CDI Stereotype, which can then be able to enable interceptors together with defining Interceptor Bindings and Scope.
  • Add @Nullable and @NotNull: This annotation is for IDE usage. IDE can flag some warnings if the condition is not met.

Jakarta Interceptor has only had a minor update, due to the update of the dependency of Jakarta Common Annotations 2.1. 

Try Out Jakarta EE 10 Core Profile with Open Liberty 

If you want to try out the Jakarta EE 10 Core Profile, you can use the latest Open Liberty beta to give it a go. Read this blog to learn how. 

Open Liberty is the first certified implementation for Jakarta EE 10 Core Profile after this Core Profile was released. In your application, you can specify the following in your pom.xml if you use Maven:

<dependency>

     <groupId>jakarta.platform</groupId>

     <artifactId>jakarta.jakartaee-core-api</artifactId>

     <version>10.0.0</version>

     <scope>provided</scope>

</dependency>

If you use Gradle, you can specify the following dependencies:

dependencies {

     Jakarta EE 10 Core Profile group: 'jakarta.platform', name: 'jakartaee-core-api', version: '10.0.0'

    }

With either of the above dependencies specified, you can use any APIs included in the Jakarta EE 10 Core Profile Open Liberty 22.0.0.9-beta. 

If you are using MicroProfile APIs, don’t worry. The release of MicroProfile 6.0 in 4Q 2022 will align with Jakarta EE 10 Core Profile. Open Liberty is currently the driving force towards this release.

Jakarta EE 10 Web Profile Adds Jakarta Concurrency

In addition to Jakarta EE 10 Core Profile, the Jakarta EE 10 release includes the Jakarta EE 10 Web Profile and Platform.

The Jakarta EE 10 Web Profile includes 15 specification updates and 1 new specification: Jakarta Concurrency 3.0.

jakarta ee 10 web profile

Prior to Jakarta EE 10, Jakarta Concurrency was not in the Web Profile release. It was only available in the Platform release. Due to its popularity, it was adopted by Jakarta EE 10 Web Profile. 

Jakarta Concurrency 3.0 adopts several functionalities from MicroProfile Context Propagation, including:

  • Asynchronous methods: A new annotation @Asynchronous was provided with the specified executor, so that the method can be executed using a new thread from the specified executor.

@Asynchronous(executor = "java:comp/concurrent/myExecutor")

public CompletableFuture<Integer> find(String key) {

    …

}

In the above code snippet, a thread from the executor java:comp/concurrent/myExecutor can be used to execute the method find(). The method return type can be java.util.concurrent.CompletableFuture, java.util.concurrent.CompletionStage, or void. This feature was influenced by MicroProfile Fault Tolerance @Asynchronous annotation.

  • Self-contained configuration of context propagation: This concept came from MicroProfile Context Propagation, but it was done annotatively within Concurrency 3.0 rather than with builders in MicroProfile Context Propagation. The following code snippets demonstrate how to use it:

@ContextServiceDefinition(name = "java:comp/concurrent/myContext",

           propagated = APPLICATION,

           cleared = ALL_REMAINING)

In the above code snippet, the annotation @ContextServiceDefinition is used to define the Context Service and its policy on which contexts are to be propagated or cleared. In this example, all contexts except APPLICATION are to be cleared when executing methods using a new thread.

Jakarta CDI 4.0 Divides Core CDI Into Full and Lite


In addition to Jakarta Concurrency 3.0, CDI 4.0 introduces several changes, some of which are backwards-incompatible. 

Jakarta CDI 4.0 divides Core CDI into CDI Full and CDI Lite, as illustrated in the following diagram.

image 3 - jakarta ee 10

CDI Full includes all lite functionalities defined in CDI Lite and other existing functionalities in previous releases of CDI:

  • CDI Lite (see CDI Lite section for more details).
  • Support the existing @SessionScoped, @ConversationScoped
  • Enabling decorators, interceptors, and alternatives via beans.xml
  • Interceptors bound using @Interceptors
  • Explicit bean archives (bean-discovery-mode=all)
  • @AroundInvoke interceptors declared on target classes
  • Existing Portable extensions
  • Support Decorators, specialization, and passivation

CDI 4.0 also introduces some backwards-incompatible changes:

  • Removed some APIs
    • @New qualifier
    • Some methods on the BeanManager interface
  • Empty beans.xml
  • The empty beans.xml in CDI 3.0 means all classes are potential CDI beans. However, in CDI 4.0, it means only the classes annotated with Bean Defining Annotations, such as ApplicationScoped, are CDI Beans. However, CDI 4.0 requests implementations of this specification to provide a mechanism to preserve the behavior of the CDI 3.0.

Jakarta EE 10 Platform Release Allows Direct API Dependency Specification

In addition to Jakarta EE 10 Core Profile and Web Profile, Jakarta EE 10 also includes the Platform release, which packages the Jakarta EE 10 Web Profile with a few more specifications.

This package includes many Jakarta EE specifications and provides a single API jar and aggregate TCK. This allows end users to directly specify the API dependencies on this release and any runtime can certify against this release, instead of certifying the individual specifications. This release also ensures specification integration. The illustration below shows the specifications that are included in this release.

jakarta ee 10 platform

Learn More

If you’d like to learn more about Jakarta EE 10, please visit the Jakarta EE Specifications Page. If you enjoyed this article and have comments or questions, feel free to connect with me via my LinkedIn or Twitter profile.

About the Author

Emily Jiang

Emily Jiang

Emily Jiang is an architecture council appointee, and a project lead and committer to many Jakarta projects, including Jakarta Config, Contexts and Dependency Injection, Data, and Interceptors.