New Features in Jersey Client

Jersey 2.30 comes with multiple new features, and this post describes three new interfaces on the client. They are PreInvocationInterceptor, PostInvocationInterceptor, and InvocationBuilderListener.

Suppose a case that the start of the request is to be logged and even measured. This can be done by ClientRequestFilter, which is usually invoked before the request is wired on the network. However, the filter may be called as a last of the filters in the chain. Sure, it can have the highest priority, but the other filters can have the very same priority! Some long-running operations can be performed before the measuring can actually start. Even worse, the filter may even be skipped from the chain by the previous #abortWith!

PreInvocationInterceptor

For this, PreInvocationInterceptor, the code that executes before the ClientRequestFilters are invoked, has been added to the client request chain. Jersey ensures all the interceptors are invoked with each request. The interceptor contains a single #beforeRequest method, which corresponds to ClientRequestFilter:

    /**
     * The method invoked before the request starts.
     * @param requestContext the request context shared with
     * ClientRequestFilter.
     */

   void beforeRequest(ClientRequestContext requestContext);

Note that only a single #abortWith is allowed in all PreInvocationInterceptors, otherwise an IllegalStateException is thrown. All the exceptions accumulated in PreInvocationInterceptors are thrown in a single Exception, available through #getSuppressed().

PostInvocationInterceptor

Similarly, ClientResponseFilter seems to be a good place where the total time of the HTTP request can be measured, but similarly to ClientRequestFilter, the response filter may not be invoked at all. For this, PostInvocationInterceptor has been introduced. Jersey runtime ensures that every PostInvocationInterceptor is called. Since an exception can occur during the HTTP request, PostInvocationInterceptor comes with two methods:

 /**
     * The method is invoked after a request when no
     * is thrown, or the Throwables are resolved
     * by previous PostInvocationInterceptor.
     *
     * @param requestContext the request context.
     * @param responseContext the response context
     * of the original Response or response context
     * defined by the new resolving Response.
     */

    void afterRequest(ClientRequestContext requestContext,
                      ClientResponseContext responseContext);

    /**
     * The method is invoked after a Throwable is caught
     * during the client request chain processing.
     *
     * @param requestContext the request context.
     * @param exceptionContext the context available to handle the
     * caught Throwables.
     */

    void onException(ClientRequestContext requestContext,
                     ExceptionContext exceptionContext);

The #afterRequest method is executed when no exception has been thrown during the HTTP request, #onException method is executed if the exception has been thrown during the request. It is possible to set a response in #onException, and the consecutive PostInvocationInterceptor will execute its #afterRequest method.

The measuring example can looks as follows, then:

String response = ClientBuilder.newClient().target("path")
.register(
new PreInvocationInterceptor() {
   @Override
    public void beforeRequest(ClientRequestContext requestContext) {
        startTime = System.currentTimeMillis();
    }  
})
.register(new PostInvocationInterceptor() {
   @Override
   public void afterRequest(ClientRequestContext requestContext,
                            ClientResponseContext responseContext) {
     logDuration(System.currentTimeMillis() - startTime);
   }
  @Override
   public void onException(ClientRequestContext requestContext,
                           ExceptionContext exceptionContext) {
     logDuration(System.currentTimeMillis() - startTime);
   }
 })
.request().get().readEntity(String.class);

InvocationBuilderListener

InvocationBuilderListener is an interface that is inspired by Microprofile REST Client RestClientBuilderListener and it contains a single method:

 /**
     * Whenever an Invocation.Builder is created, (i.e. when
     * WebTarget#request() is called, this method would be invoked.
     *
     * @param context the updated InvocationBuilderContext.
     */

    void onNewBuilder(InvocationBuilderContext context);

InvocationBuilderContext a subset of methods of the Invocation.Builder. It can be used to call the default values of the Invocation.Builder. Since it is invoked at the time Invocation.Builder is instantiated, any consequent calls of the Invocation.Builder‘s methods will replace the defaults set by the InvocationBuilderListener.

For instance, if all the HTTP requests should contain a custom HTTP header, there can be created a feature that would be registered on the client:

  public static class MyFeature implements Feature {
        @Override
        public boolean configure(FeatureContext context) {
            context.register(
                 (InvocationBuilderListener)(l)->
                     l.getHeaders().add("MY_HEADER", "MY_VALUE"));
            return true;
        }
    }

And More!

Jersey 2.30 comes with more new features on the client, most notably a possible hanging when using the Apache Client Connector has been fixed and the Microprofile Rest Client implementation has been allowed to use connectors.

Posted in Jersey | Leave a comment

Jersey Apache Connector Hangs …?

Jersey comes with various connectors to third-party HTTP clients. The way the connector is used is simple, put the connector and the third-party client to the classpath, and tell the client to use it. For Apache Connector, use:

ClientConfig clientConfig = new ClientConfig();
clientConfig.connectorProvider(new ApacheConnectorProvider());
Client client = ClientBuilder.newClient(clientConfig);

Switching from the default HttpUrlConnectorProvider to ApacheConnectorProvider may not be as smooth as expected, and the connection can hang. Surprisingly, even switching the provider in Jersey tests and examples in Jersey workspace. For instance, adding Apache connector to org.glassfish.jersey.tests.e2e.sse.BroadcasterCloseTest can result in a thread lock similar to:

java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for  <0x00000000ee799320> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
 at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:379)
 at org.apache.http.pool.AbstractConnPool.access$200(AbstractConnPool.java:69)
 at org.apache.http.pool.AbstractConnPool$2.get(AbstractConnPool.java:245)
 - locked <0x00000000ed700070> (a org.apache.http.pool.AbstractConnPool$2)
at org.apache.http.pool.AbstractConnPool$2.get(AbstractConnPool.java:193)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:304
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:280)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:190)
 at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
 at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
 at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
 at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
 at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
 at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:478)

The problem is the test code, the response is never closed. The Apache Connection pool does not have enough threads to execute all the requests since the response is not closed and thus the connection is not closed. The solution can be simple, call response.close() after the assertion in the for-each loop as well as for 2 more responses. Note that the third request is closed automatically when response.get(String.class) is called.

The general rule is to close anything that can be closed if not needed (Client, Response, SseEventSink, SseEventSource). Response.close() does not close the buffered entity, it can be read multiple times. If the entity is an InputStream, do not forget to close it, too.

Sometimes, the response cannot be closed, yet, and multiple connections need to be open. This time, the Apache Connector needs to be provided with more threads. For BroadcasterCloseTest, eleven is enough (in case the responses are not closed):

@Override
protected void configureClient(ClientConfig config) {
    PoolingHttpClientConnectionManager cm
            = new PoolingHttpClientConnectionManager();
    cm.setMaxTotal(11);
    cm.setDefaultMaxPerRoute(11);
    config.property(
            ApacheClientProperties.CONNECTION_MANAGER , cm);
    config.connectorProvider(new ApacheConnectorProvider());
}

There is a case where the Jersey Apache Connector hangs even if everything is done properly. Apache HttpClient 4.5.1 comes with a change that may cause Jersey Apache Connector in the case where chunked streams are used. An example when this happens is StreamingTest#clientCloseTest. Jersey 2.28 depended on Apache HttpClient 4.5, and the Apache Connector did not hang with it. Jersey 2.29 came with newer Apache Connector and for the StreamingTest#clientCloseTest to pass, a timeout 1000ms has been added:

 client.property(ClientProperties.READ_TIMEOUT, 1_000);

Without the timeout, the connector hangs, and the stack trace is as follows:

java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280)
at org.apache.http.impl.io.ChunkedInputStream.getChunkSize(ChunkedInputStream.java:261)
at org.apache.http.impl.io.ChunkedInputStream.nextChunk(ChunkedInputStream.java:222)
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:183)
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:210)
at org.apache.http.impl.io.ChunkedInputStream.close(ChunkedInputStream.java:312)
at org.apache.http.impl.execchain.ResponseEntityProxy.streamClosed(ResponseEntityProxy.java:142)
at org.apache.http.conn.EofSensorInputStream.checkClose(EofSensorInputStream.java:228)
at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:172)
at java.io.BufferedInputStream.close(BufferedInputStream.java:483)
at java.io.FilterInputStream.close(FilterInputStream.java:181)
at org.glassfish.jersey.apache.connector.ApacheConnector...

Jersey 2.30 contains a workaround for the changed Apache Http Client 4.5.1+ and the timeout is not needed to be added in the client code anymore.

Posted in Jersey | Leave a comment

Configuring Jersey Application

It is a common issue, I am asked about every now and then, how to pass the user data to a user application? The user needs to change the code behavior depending on the configuration data. This is where the @Context Configuration comes handy.

In the following text, I try to describe the possible methods to pass the user’s property to the Configuration object so that it is available when it is injected.

Hardcode in the Application/ResourceContext

This is the simplest way, just set the property just like:

new ResourceConfig().property("NAME","VALUE")

Using web.xml Initial Parameters

For classic war bundled applications, the properties can be defined in the web.xml:

    <servlet>
         <init-param>
            <param-name>NAME</param-name>
            <param-value>VALUE</param-value>
        </init-param>
    </servlet>

Using the AutoDiscoverable

Jersey comes with AutoDiscoverable SPI, which allows for being detected by a JDK’s ServiceLoader when anywhere on a classpath. Such AutoDiscoverable is then used as if it were a part of the application. The advantage is that the application itself does not need to be rebuilt, only the AutoDiscoverable with the properties.

The org.glassfish.jersey.internal.spi.AutoDiscoverable service needs to be added to META-INF/services, and it needs to point to the AutoDiscoverable implementation:

public class MyAutoDiscoverable implements AutoDiscoverable {
    @Override
    public void configure(FeatureContext context) {
        context.property("NAME", "VALUE");
    }
}

Using the System Properties

Quite often, the administrators come and ask to configure Jersey application, mainly to use any of the CommonProperties property, but they do not want to recompile their Jersey application, nor the AutoDiscoverable. Since Jersey 2.29 it is possible to turn on the ability to convert the System properties into Configuration properties. That can be done by using the System property, too:

java -Djersey.config.allowSystemPropertiesProvider=true -DNAME=VALUE

Note that with the security manager turned on, write access permission is required to execute System.getProperties(). With insufficient permissions, the warning message is logged (with Level.FINER) and only CommonProperties, ClientProperties, and ServerProperties properties are used, as the property names are known and System.getProperty(name) method can be used, which does not require the write access permission.

Using Microprofile Config

Microprofile platform became very popular lately and Microprofile Config Specification is a recommended way in the Jakarta EE world to configure the specifications under the Jakarta EE umbrella.

Jersey 2.29 comes with support for Microprofile Config implementation such as Helidon or SmallRye. To configure the Jersey application, the microprofile-config.properties file needs to be created in the META-INF folder. The required properties are then simply set in the microprofile-config.properties:

NAME=VALUE

Then Jersey Microprofile Config extension is needed to be added:

        <dependency>
            <groupId>org.glassfish.jersey.ext.microprofile</groupId>
            <artifactId>jersey-mp-config</artifactId>
            <version>2.29.1</scope>
        </dependency>

And the Microprofile Config implementation, such as Helidon:

        <dependency>
            <groupId>io.helidon.microprofile.config</groupId>
            <artifactId>helidon-microprofile-config</artifactId>
            <version>1.3.1</version>
        </dependency>

Or SmallRye:

        <dependency>
            <groupId>io.smallrye</groupId>
            <artifactId>smallrye-config</artifactId>
            <version>1.3.6</version>
        </dependency>

or any other suitable Microprofile Config implementation.

Other Methods

There are other methods that are variants to the described methods, or they are less straightforward and significantly more complicated. However, if you have any other favorite method that was not discussed, I’d love to hear about it in the comments.

Posted in Jersey | Leave a comment

Jersey 2.29.1 has been released!

What a busy summer! Jersey 2.29 has been released in June and Jakarta EE 8 release was the next goal to be achieved before Oracle Code One.

It has been a lot of work. Jakarta EE 8 contains almost 30 different APIs, one-third of which Jersey depends on. Fujitsu, IBM, Oracle, Payara, RedHat, Tomitribe, Eclipse Foundation, the individual contributors, everyone worked hard to follow the new certification process to get the Certification of Compatibility of the new APIs released as part of Jakarta EE together with the respective implementations.

As of today, three application servers were announced to be certified Jakarta EE 8 Application Servers, Eclipse Glassfish 5.1, IBM OpenLiberty and RedHat WildFly announced they are fully certified as a compatible implementation of the Jakarta EE 8 profiles.

Jersey team provided a great deal of help with the certification, building some of the APIs, creating the TCK jobs and run some of the TCKs, …, and yet the team was able to deliver a new version of Jersey!

Jersey 2.29.1 is mainly a maintenance release, with a couple of fixes, and three main new features. It depends on the new Jakarta EE 8 APIs (mainly JAX-RS 2.1.6), it provides ApacheHttpClientBuilderConfigurator to improve the ability to configure Apache Http Client, and it provides a Microprofile Rest Client 1.3.3 implementation. The full list of features is available here.

Please give it a try and let us know how you like it.

Posted in Jakarta EE, Jersey | Leave a comment

Jersey 2.29 has been released!

It is a pleasure to announce that Jersey 2.29 has been released. It is rather a large release. While Jersey 2.27 was the last non-Jakarta EE release and Jersey 2.28 was the first release of Jersey under a Jakarta EE umbrella, and both of them stayed compatible with Jersey 2.26 as much as possible (binary compatibility, no new API, only updated dependencies and fixes that did not change the Jersey API or behavior), Jersey 2.29 brings many fixes that stacked up since 2.26 and lot of new features, most notably:

  • JDK 11 support
  • Possibility to pass configuration properties through the environment variables
  • Possibility to pass configuration properties using a Microprofile Config implementation
  • Implementation of Microprofile REST Client specification
  • Extension module for Spring 5
  • Possibility to use HK2 Abstract Binder removed in 2.26 again for backward compatibility
  • Enhanced Jetty connector configuration possibilities

Please let us know how you like it!

We are still working on the documentation, though. We have updated the design of a User Guide to correspond with the Jakarta EE style. Now we need to focus on the content, fix what is obsolete and describe new features, that’s our main goal for the silly season!

Posted in Jersey | Leave a comment

Jersey 2.28 has been released

Jersey 2.28 has been released and is available in maven central! Jersey 2.28, the first Jakarta EE implementation of JAX-RS 2.1 has finally been released. Please let us know how you like it!

After whole Java EE has been contributed to the Eclipse Foundation, every project mainly focused on introducing the project and on bringing it closer to the community. From all the tools made available for the community, I’d like to mention Travis CI. It is a great tool that can be used by the community to verify the functionality of provided pull requests. As always Jersey team is happy for them as well as for any other help from the community.

Another goal of Jakarta EE was to create a new release of every project with new versions of dependencies released in the Jakarta EE. In the case of Jersey, the dependencies were updated as much as possible. Of course, sometimes that’s not desired, such as when testing integration with Servlet 2.5 the dependency on Servlet 4.x is not exactly right.

Functionally, we mainly focused on fixing issues, first with building Jersey that was reported by the community, and later some reported differences between Jersey and JAX-RS Specification. This is common for every Jakarta EE project this release: it was required not to provide any changes in API and functionality to ensure the compatibility between last Java EE and initial Jakarta EE releases.

Jersey master contains quite a list of changes, fixes, and improvements to be available in next Jersey release. Currently, there are a few legal details left that need to be resolved so that Jakarta EE projects are allowed to release a version that has API changed, that brings new features, and/or modifies some behavior. Once those legal matters are resolved, a next Jersey release will be created!

Posted in Jersey | 1 Comment

Eclipse Glassfish 5.1.0.RC2 has been released!

That’s right, Eclipse Glassfish 5.1.0.RC2, the Jakarta EE implementation, has been published in maven central. Eclipse Glassfish 5.1.0 release is terribly close.

Latest Glassfish in maven central, Eclipse Glassfish 5.1.0.RC1, publicly available couple of months, is mostly identical to Oracle Glassfish 5.0.1, the latest Java EE reference implementation. It contains many Java EE projects and dependencies, and it has been released mainly for the Eclipse community to introduce Jakarta EE, its functionality, and to demonstrate the commitment of all people working on Jakarta EE.

Eclipse Glassfish 5.1.0.RC2 is very close to the final version, all the Java EE compatibility tests passed there, while it depends on Jakarta EE APIs and implementation rather than Java EE ones.

Comparing Java EE and Jakarta EE, functionally, there is only a minimal difference. That was the goal, to transfer the Java EE to Jakarta EE without changes in the API, so that the community can smoothly deploy the projects from a Java EE application server to the Jakarta EE application server. Only major bug fixes in the functionality were allowed.

Jakarta EE was focused on bringing the projects close to the community. Everyone with enough enthusiasm can start contributing to a project and become a committer. Most of the projects do use Travis CI and the projects contain Travis scripts so that anyone who wants to contribute can run the tests in his own GitHub fork on Travis CI (after registering there). For the projects, committers have access to Eclipse Jenkins infrastructure, where any build and test jobs can be set up. Unlike with Java EE, the compatibility tests are available, with a description of how to use them. There is a Jakarta EE wikipedia, and each project has its own mailing list.

Apart from these new things, the license of projects has been changed. The code is available under EPL 2.0 license, whereas examples are available under EDL 1.0 license.

The main positive thing, though, is that it is the interest of the community that decides about the future of the Jakarta EE projects.

Posted in Jakarta EE | Leave a comment

Jersey 2.28-RC4 has been released

Jersey 2.28-RC4 is available in maven central! Jersey 2.28-RC4, the first Jakarta EE publicly available version of Jersey, is an almost final version of Jersey 2.28.

Jersey 2.28, is to be released soon. It will be part of Eclipse Glassfish 5.1.0, which is to be officially released January 29. Only a few changes are yet to be made, mainly in versions of dependencies that are yet to come. Unlike the three previous internal RCs, Jersey 2.28-RC4 is mature enough to be available in maven central. Check it out and let us know how you like it!

Posted in Jersey | Leave a comment

Glassfish 5.1.0 is to be released!

Glassfish Application Server has been the reference implementation of Java EE since Java EE 5. Those days, it was Glassfish version 2. Java EE 6 reference implementation was Glassfish 3.x, Java EE 7 reference implementation was Glassfish 4.0, Java EE 8 reference implementation was Glassfish 5.0.

A little bit over a year ago it was announced that Java EE is to be contributed to the Eclipse Foundation. The process was not a trivial task, the code to be contributed was revisioned and updated to be legally correct, secure, and cleaned. Right before each project on GitHub was archived and transferred under Eclipse Foundation and Jakarta EE, one last version of it was released. This is what makes Oracle Glassfish 5.0.1, the latest reference implementation of Java EE 8.

Eclipse Glassfish 5.1.0, on the other hand, is Jakarta EE implementation. It is the initial Jakarta EE release, that has a binary compatible API with Java EE and Java EE Compatibility Test Suite should pass with this initial Jakarta EE release. There is some difference between Java EE 8 and Jakarta EE, though.

The contributed Java EE projects were subject of community revision. While only small changes that do not change the API were allowed for the initial release, the projects updated their dependencies, updated functionality to work with them, fixed some possible bugs, polished documentation, and javadoc, and adopted the Eclipse license.

After the hard work that started at the end of 2017 by Oracle contributing millions of rows of Java EE code, and continued by the Eclipse Foundation and the community, after a little more than a year, January 29 is to be the Eclipse Glassfish 5.1.0, the Jakarta EE implementation, release date.

Posted in Jakarta EE | Leave a comment

Happy New Year: But Where Are the Christmas Presents?

The year 2018 is to be over soon. Christmas is over, but there is no Jakarta EE for a Christmas present –  the Jakarta EE release is postponed to January 2019. Not even Jersey 2.28 is released. While it may seem so – the GitHub repository already contains tag and branch 2.28 – the tag and branch are erased and recreated again, from time to time.

This is confusing, but it actually is how the Jakarta release is planned. In order to minimize the effort to release Jakarta EE, this one time only, each project is staged with a final version, so that any other project depending on it can immediately have a reference to the project, without a need to update the version in dependency list every time the project is updated. Each project is possibly staged a couple of times, with git tag and branch updated.

It has some advantages, but it goes against the maven intention. Without comparing all the pros and cons, it is obvious the community can be under an impression that the 2.28 is final already. I am really sorry for the confusion, it is not only Jersey related, it is Jakarta EE wide, caused by good intentions of trying the release to be as fast and smooth as possible.

The final release will be well announced, of both Jakarta EE and Jersey (by email, twitter, blog…). Jersey will merge GitHub EE4J_8 branch to master. And Jersey and Eclipse Glassfish will be available in maven central.

Enjoy what’s left of 2018, Very Happy New Year, and best wishes to Jakarta EE in 2019.

Posted in Jakarta EE, Jersey | Leave a comment