back to all blogsSee all blog posts

More Jakarta EE 10 and MicroProfile 6 features make their debut in Open Liberty 22.0.0.12-beta!

image of author
Michal Broz on Oct 27, 2022
Post available in languages:

As we progress towards full Jakarta EE 10 compliance, the 22.0.0.12-beta release includes six new Jakarta EE 10 specifications, alongside the ones that were included in previous beta releases.

Jakarta Batch 2.1 provides improved CDI integration while Jakarta XML Web Services 4.0 now incorporates Jakarta Web Services Metadata. Jakarta Pages 3.1 provides developers an option to raise Exceptions for undefined Expression Language Identifiers, while Jakarta Tags 3.0 includes Tag URI renaming when referencing tag libraries. Jakarta Messaging 3.1 makes connection factory and destination definition annotations repeatable, while Jakarta WebSocket 2.1 allows for the registration of endpoints outside of the deployment phase.

But this beta includes more than just Jakarta EE 10 features; two new MicroProfile 6.0 features are also included! MicroProfile JSON Web Token 2.1 includes simplified JWT validation and MicroProfile Metrics 5.0 provides user-defined metric registry scopes.

The Open Liberty 22.0.0.12-beta includes the following beta features (along with all GA features):

For a full list of new and updated MicroProfile 6.0 features in Open Liberty, see the 22.0.0.13-beta post.

Option to raise Exceptions for undefined Expression Language Identifiers (Jakarta Pages 3.1 and Jakarta Tags 3.0)

Jakarta Pages is a template engine that allows developers to mix various content, such as HTML, XML, and Java code, and translate it into a Jakarta Servlet. Jakarta Standard Tag Library allows for tags to encapsulate common functionality used in many web applications. The Open Liberty pages-3.1 feature is an implementation of both the Jakarta Pages 3.1 and Jakarta Standard Tag Library 3.0 specifications. It includes new features, behavior clarifications, and deprecations from the previous 3.0 version.

The new pages-3.1 feature allows developers to identify undefined Expression Language variables by using a new option, which raises a PropertyNotFoundException and can be set in one of two ways. The errorOnELNotFound attribute is set as a page or tag directive. The <error-on-el-not-found> element is set in the web.xml file.

Previously, imported packages and classes were only available to the scripting environment (i.e. scriptlet tags). However, with version 3.1, they are also available in the Expression Language environment within the page. Default imports (such as jakarta.servlet, jakarta.servlet.jsp, jakarta.servlet.jsp.http) are consistent between both environments. Related changes included internal refactoring of the ScopedAttributeELResolver to create ImportELResolver and the addition of the NotFoundELResolver, which always resolves the requested value and returns null.

Other significant changes include the deprecation of the isThreadSafe directive, the jsp:plugin (including the related jsp:params and jsp:fallback) actions, and any methods which overrode ELResolver.getFeatureDescriptors().

As for Jakarta Tags 3.0, the largest change includes the Tag URI renaming when referencing tag libraries. For example, jakarta.tags.core now replaces the http://xmlns.jcp.org/jsp/jstl/core URI when importing the core tag library. However, the implementation kept older URIs for backwards compatibility. The remaining changes related to general clean up of the documentation.

To enable the new Jakarta Server Pages 3.1 and Jakarta Standard Tag Library 3.0 features, add the pages-3.1 feature to your server.xml:

<featureManager>
   <feature>pages-3.1</feature>
</featureManager>

For more information about Jakarta Server Pages and Jakarta Standard Tag Library, refer to the following links:

Register endpoints outside of the deployment phase (Jakarta WebSocket 2.1)

Jakarta WebSocket allows communication via the WebSocket protocol, allowing for full-duplex communication between endpoints. This means that a single, persisted connection is made across the endpoints, allowing both the server and client to continuously and simultaneously push information to each other.

Jakarta WebSocket 2.1 is the latest version of the specification and provides several new features and behavior clarifications aimed at improving WebSocket development. Firstly, when setting up dependencies, developers are likely to notice the API JARs are refactored into client and server JARs. However, both APIs are available as part of the websocket-2.1 feature.

HTTP connection upgrades to the WebSocket protocol can now occur via the ServerContainer.upgradeHttpToWebSocket() method​ rather than IBM’s specific WsWsocServerContainer.doUpgrade() method.

Another change regards the Session#getUserProperties() method. The returned map is now a copy per endpoint instance, per WebSocket session. Additionally, the server session’s user properties are initially populated by the ServerEndpointConfig.getUserProperties() method, so endpoints can retrieve properties set in the ServerEndpointConfig.Configurator.modifyHandshake() method​. This is similar to the client session as the user properties are a shallow copy from the EndpointConfig.getUserProperties() method.

Lastly, there were many clarifications in the spec, such as requiring the Session.getRequestURI() method to return the whole URI. These clarifications can be viewed on the Jakarta WebSocket 2.1 page.

You can enable the Jakarta WebSocket 2.1 feature by using the websocket-2.1 feature in the server.xml file,

<featureManager>
   <feature>websocket-2.1</feature>
</featureManager>

For more information about Jakarta WebSocket, refer to the following links:

Improved CDI integration (Jakarta Batch 2.1)

The updates in Jakarta Batch 2.1 primarily focus on improved integration with Context Dependency Injection (CDI). Discovery of Batch artifacts is now standardized via CDI, whereas before it was not fully defined in the specification.

Previously, the default JobOperator was only made available from a static factory method, BatchRuntime.getJobOperator(). With Jakarta Batch 2.1, the default JobOperator is provided as a CDI bean unless one is defined by the user application, if an injectable field is available as defined by:

@Inject
JobOperator jobOperator;

Previously, the @BatchProperty annotation allowed for injection of String-type values only, but is now expanded to most other primitive types. For example:

@Inject @BatchProperty(name="p1") String p1;

This property can have other types in Jakarta Batch 2.1, including Boolean, Integer, Long, Float, and Double. For example:

@Inject @BatchProperty(name="p1") Integer p1;

The batch-2.1 feature is the implementation of Jakarta Batch 2.1 for use with other Jakarta EE 10 features. It can be activated by including the batch-2.1 feature directly, or by including batchManagement-1.0 along with another Jakarta EE 10 feature. For example:

<featureManager>
   <feature>batchManagement-1.0</feature>
   <feature>servlet-6.0</feature>
</featureManager>

For more information regarding Jakarta Batch 2.1, refer to the following links:

Connection factory and destination definition annotations are now repeatable (Jakarta Messaging 3.1)

Jakarta Messaging is a set of APIs to standardize message communication between applications, defining how the messages are created, sent, received, and interpreted. Jakarta Messaging 3.1 provides minor changes and enhancements to the specification. Two noteworthy updates are the requirement for Java 11 and making the @JMSConnectionFactoryDefinition and @JMSDestinationDefinition annotations repeatable.

To enable the new Jakarta Messaging 3.1 feature, add the messaging-3.1 feature to your server.xml:

<featureManager>
   <feature>messaging-3.1</feature>
</featureManager>

For more information about Jakarta Messaging, refer to the following links:

Jakarta Web Services Metadata incorporated into XML Web Services 4.0

Jakarta XML Web Services 4.0 is a set of APIs that allows applications to deploy SOAP-based web services on the Jakarta EE 10 platform. This set of APIs includes both the XML Web Services 4.0 specification, which now incorporates the Jakarta Web Services Metadata specification, as well as the Jakarta SOAP with Attachments 3.0 specification.

Although the changes introduced in XML Web Services 4.0 are relatively minor, they do include the requirement for Java SE 11, as well as incorporating the Jakarta Web Services Metadata specification into XML Web Services 4.0.

To enable the new Jakarta XML Web Services 4.0 feature, add the xmlWS-4.0 feature to your server.xml:

<featureManager>
   <feature>xmlWS-4.0</feature>
</featureManager>

For more information about Jakarta XML Web Services, refer to the following links:

Simplified JWT Validation (MicroProfile JSON Web Token 2.1)

The MicroProfile JSON Web Token 2.1 specification allows the use of a JWT to authenticate and authorize requests to a service. The specification simplifies managing the validation of the JWT by introducing three new MicroProfile Config properties, along with corresponding mpJwt attributes.

mp.jwt.verify.token.age

The mp.jwt.verify.token.age property allows you to specify the number of seconds since the JWT token was issued. The iat (issued at) claim must be present in the JWT and the configured number of seconds since iat must not have elapsed. If it has elapsed, then the request is rejected with an Unauthorized (401) response.

The new tokenAge attribute of the mpJwt element overrides the mp.jwt.verify.token.age property.

mp.jwt.verify.clock.skew

The mp.jwt.verify.clock.skew property allows you to specify the clock skew in seconds used during the token expiry and age verification. The default value is 0 seconds. In order to use this new property, set a negative value for the clockSkew attribute of the mpJwt element since the mpJwt element already has a default value of 5 minutes for the clockSkew attribute. For example:

<mpJwt id="myMpJwt" clockSkew="-1"/>

If clockSkew is not specified or it has a value greater than 0, then it will override the mp.jwt.verify.clock.skew property.

mp.jwt.decrypt.key.algorithm

The mp.jwt.decrypt.key.algorithm property allows you to specify the Key Management Algorithm for decrypting the Content Encryption Key (CEK) when receiving JWE tokens. There is no default value. The alg header parameter must be present in the JWE and must be the same value as the mp.jwt.decrypt.key.algorithm property. If it is not the same value, then the request is rejected with an Unauthorized (401) response. For example:

mp.jwt.decrypt.key.algorithm=RSA-OAEP

The new keyManagementKeyAlgorithm attribute of the mpJwt element overrides the mp.jwt.decrypt.key.algorithm property.

You can enable the MicroProfile JSON Web Token 2.1 feature by using the mpJwt-2.1 feature in the server.xml file:

<featureManager>
   <feature>mpJwt-2.1</feature>
</featureManager>

For more information regarding MicroProfile JSON Web Token, refer to the following links:

User-defined metric registry scopes (MicroProfile Metrics 5.0)

The MicroProfile Metrics 5.0 feature is the implementation of the Eclipse MicroProfile Metrics 5.0 release and is compatible to run only with other Jakarta EE 10 features. This latest version of MicroProfile Metrics includes both new functionality and significant changes to the functionality in MicroProfile Metrics 4.0 (i.e. the Open Liberty mpMetrics-4.0 feature).

Before we cover the new, lets first quickly go over the changes to existing functionality. Most notable is the removal of the Meter, ConcurrentGauge and SimpleTimer metrics. A consequence of this change is that the REST.request metric, which was previously backed by a SimpleTimer metric, is now a Timer metric. For the publishing of metrics, only the Prometheus format is now available, and the JSON formatted output has been removed. Additionally, the metrics endpoint for a specific metric registry scope and metric is no longer accessed through a tree hierarchy, but rather through query params. For example, /metrics/base/jvm.uptime is accessed through /metrics?scope=base&metric=jvm.uptime. The /metrics?scope=base endpoint by itself retrieves the metrics for the base metric registry.

New in this release is the introduction of user-defined custom scopes. Prior to this release, there was only the base, vendor and application scopes and only the application scope could be used to register metrics. Now, metrics can be registered to a user-defined metric registry scope in one of the following two ways.

Scope attribute in a the metric annotations

@Counted(name = "myCounter", scope ="customScope")
public void foo(){
   ...
}

Inject a metric registry with a custom scope using the new @RegistryScope annotation

@Inject
@RegistryScope(scope="customScope")
MetricRegistry metricRegistry;
The @RegistryType injection qualifier is still available, but is now deprecated.

Furthermore, the mp.metrics.smallrye.timer.precision and mp.metrics.smallrye.histogram.precision MicroProfile Config properties are introduced in this release. These properties specify the percentile accuracy used by the Timer and Histogram metrics. The valid values are 1-5. The default value is 3. The higher the number, the greater the precision, but the greater the memory usage.

These only the most notable and impactful changes. There are further changes to the API that are not covered in this blog. For a comprehensive list of changes to the MicroProfile Metrics technology, go to the Eclipse MicroProfile Metrics project page.

You can enable the MicroProfile Metrics 5.0 feature by using the mpMetrics-5.0 feature in the server.xml file,

<featureManager>
   <feature>mpMetrics-5.0</feature>
</featureManager>

For more information about MicroProfile Metrics, refer to the following links:

Try it now

To try out these features, just update your build tools to pull the Open Liberty All Beta Features package instead of the main release. The beta works with Java SE 19, Java SE 17, Java SE 11, and Java SE 8.

If you’re using Maven, here are the coordinates:

<dependency>
  <groupId>io.openliberty.beta</groupId>
  <artifactId>openliberty-runtime</artifactId>
  <version>22.0.0.12-beta</version>
  <type>pom</type>
</dependency>

Or for Gradle:

dependencies {
    libertyRuntime group: 'io.openliberty.beta', name: 'openliberty-runtime', version: '[22.0.0.12-beta,)'
}

Or take a look at our Downloads page.

We welcome your feedback

Let us know what you think on our mailing list. If you hit a problem, post a question on StackOverflow. If you hit a bug, please raise an issue.