24

I want to implement a JAX-RS client that support HTTP/1.1 and HTTP/2 for a JAX-RS client.

The idea is to use HTTP/2 if the server supports ALPN with HTTP/2 and uses HTTP/1.1 if the server does not provide any information.

I have read some articles about ALPN and it seems to be possible but I don't find anything supporting these protocol at the same time. I did not manage to plug these together.

I am currently using the Jetty HTTP/1.1 transport connector for Jersey and a custom implementation for HTTP/2 transport connector.

4
  • 4
    You want to open an issue to Jetty to support dynamic selection of the transport to use based on ALPN. That way, you will only write one Jersey transport that works with both protocols. Thanks ! Commented Feb 20, 2017 at 16:48
  • 2
    @sbordet I have just created the issue Commented Feb 22, 2017 at 19:58
  • Are you trying to use any async calls in your application Commented Dec 6, 2017 at 12:25
  • @SaurabhJhunjhunwala Just sync for the moment Commented Dec 6, 2017 at 13:32

5 Answers 5

4

Java HTTP client provided with Java 11 is supporting HTTP/1.1 and HTTP/2 (see Introduction to the Java HTTP Client).

I have built a connector using it Jersey Connector using java.net.http.HttpClient. You can use it adding the following dependency.

<dependency>
  <groupId>com.github.nhenneaux.jersey.connector.httpclient</groupId>
  <artifactId>jersey-httpclient-connector</artifactId>
  <version>0.2.2</version>
</dependency>

Maven Central

Sign up to request clarification or add additional context in comments.

1 Comment

Fantastic! Thank you. Question remains why this is not the default for Jersey.
-1

In fact ALPN is only support by jdk starting at JDK9 http://unrestful.io/2015/10/09/alpn-java.html.

That's is not handle by JAX-RS client api

3 Comments

It can be supported using a library (Jetty ALPN) with the TLS client of the JVM or using another TLS client (e.g. conscrypt). It can be handled through JAX-RS if the underlying transport handle it. For the moment there is none but the Jetty project would like to implement it github.com/eclipse/jetty.project/issues/1350.
OK but to implement JAX-RS you use an existing http client implementation i suppose Jetty's HttpClient that handle ANPL for you ?
I use Jersey implementation of JAX-RS that uses under the hood Java HttpUrlConnectionHTTP1 client. Jetty HTTP/1.1 client can also be configured. I have also written an HTTP/2 client based on Jetty. However, there is no underlying transport supporting HTTP/1.1 and HTTP/2 by using ALPN.
-2

A solution could be to use nginx (or apache2) as revers proxy to handle that requirement.

Nginx can proxy your jetty server (using http/1.1 or http/2 only protcol) and server http/2 with alpn (with the latest version) to the clients.

1 Comment

Indeed it could be a solution. However there are several drawback, i.e. you need to break the TLS encryption in the reverse proxy, you have to change the server whereas it could be an external party and you have to choose one protocol in your client while the point of the question is having a client supporting both protocols.
-2

If this question is still open to contribute, then there is one way of implementing client with < JDK 9 version.

As you know, HTTP/2 requires ALPN support if using TLSv1.2 (h2).

netty package has some support for HTTP/2 provided that you have openssl (version 1.0.2 or later) installed on platform.

Netty package will use OpenSSL for ALPN support by invoking native libraries.

We implemented a client with JDK8 and manage to generate http2 request for operation where server only accepts http2 request. We used below mentioned dependency

    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <!--<version>5.0.0.Alpha2</version> -->
        <version>4.1.29.Final</version>
    </dependency>

5 Comments

Actually I'm looking for a client being able to do both and I don't think your client is doing HTTP/1 and HTTP/2 ?
My client is doing both HTTP/1.1 & HTTP/2. By default, it is using HTTP/1.1 & for specific service where only HTTP/2 is accepted, we create HTTP/2 request
can it select dynamically from ALPN output the protocol?
application is already aware of specific service which only support HTTP/2 and if this service is being invoked, then we build ssl context and a request required for HTTP/2 .
ok I already got this working (I have an individual client for HTTP/1 and HTTP/2, see links in the question) but not dynamically which is my question actually.
-2

It sounds like your question, in abstract, is you want a Java servlet than can negotiate and terminate a single REST endpoint, so avoiding one interface for HTTP/1 and another for HTTP/2, and avoiding termination externally, like via a proxy that can handle multiple protocols. So an all-in-one servlet.

This was already implemented in Undertow by Stuart (& JBoss folks) at least as late as 2017 when Steve Hu added test cases and PR. 1

You need to pass in the ENABLE_HTTP2 option in the OptionsMap. For http URI's this means that the client will attempt an upgrade on the first request, for https URI's ALPN will be used to try and negotiate HTTP/2. This is how browsers behave, and will work even if the target does not support HTTP/2. 2

It looks like Simone is pushing changes to implement this in Jetty. 3 So if you want this now, switch from Jetty to Undertow, or change the question to "Support ... in Jetty".

4 Comments

This seems promising but actually I have not found so far a way to integrate JAX-RS and an HTTP client supporting both HTTP/1 and HTTP/2 depending on the target server. As far as I know there is no Undertown client connector with a JAX-RS implementation? The implementation of Simone is related to the issue I have created in Jetty. However, if there is another connector being able to connect HTTP/1 and HTTP/2 I can switch ;-)
Undertow is already integrated as the servlet for Wildfly and Wildfly has JAX-RS, it's implemented as RESTEasy b/c ... well it's a JBoss project not an Apache project, but you can get both. I'm just as curious to try out your scenario on it to verify it works, so do you have a test case somewhere public?
Actually I don't want the Servlet implementation but the HTTP JAX-RS client implementation side which does not seem to be implemented by Undertown unless I have missed something?
Ah, I misunderstood then.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.