Enterprise Java

HTTP/2 With JBoss EAP 7

Just a couple of days ago, the new JBoss EAP 7 ALPHA version was released.  And I already blogged about how to get started with it. One very interesting part is the HTTP/2 support which has been added as a technical preview. It is provided by the new webserver Untertow.  HTTP/2 reduces latency by compressing headers and multiplexing many streams over the same TCP connection. It also supports the ability for a server to push resources to the client before it has requested them, leading to faster page loads.

Tech Preview Components

A short remark about what technology preview actually means. Some features in JBoss EAP are provided as technology preview. This means that while these components have been included in JBoss EAP but they’re not considered functionally complete and are not suitable for production use. So they’re supported in development  but not recommended or supported for production use. But they help us to get wider exposure and feedback. So, if you encourage something that does not work as expected or have ideas about the future direction of this feature, feel free to reach out to us.

Red Hat intends to fully support technology preview features in a future release.

Prepare Your EAP Installation

The Application Layer Protocol Negotiation (ALPN) is an extension for the SSL protocol that helps to make HTTPS connections faster. It was defined together with HTTP/2 and this uses ALPN to create HTTPS connections. As most browsers implement HTTP/2 only over HTTPS, The OpenJDK implements SSL in the sun.security.ssl package. The current implementations in Java 7 and Java 8 do not support ALPN. With Java 9,there will (hopefully) be native support for ALPN (JEP 244). EAP requires you to use Java 8. You can’t run the HTTP/2 example on Java 7 at all, because of missing cyphers.

Since HTTP/2 is also a goal for Java EE8, it is also expected to be made available in a future Java SE 8 update, likely after Java 9 is released.

To get around this limitation today on Java 8 we need to add a library that provides ALPN support to the JVM’s boot class path. The version of the jar file that you need is tied to the JVM version in use, so you must make sure you are using the correct version for you JVM. Jetty provides a ALPN implementation for java. Go to the jetty website and find the correct version for your JDK. In this example, I’m using JDK 1.8.0u60 which needs ALPN version: “8.1.5.v20150921”.

Switch working folder to your JBOSS_HOME and download the alpn library to the /bin folder.

curl http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar >bin/alpn-boot-8.1.5.v20150921.jar

The library now needs to be added to the server’s bootclasspath. Add the following lines to the standalone configuration files

//standalone.conf on Linux
JAVA_OPTS="$JAVA_OPTS  -Xbootclasspath/p:$JBOSS_HOME/bin/alpn-boot-8.1.5.v20150921.jar"

//standalone.conf.bat on Windows
set "JAVA_OPTS=%JAVA_OPTS% -Xbootclasspath/p:%JBOSS_HOME%/bin/alpn-boot-8.1.5.v20150921.jar"

The next step is to install certificates for the https connector. For testing purposes you can download the ones from the Undertow test suite. Learn how to generate and run your own SSL certificates in an older blog-post of mine.

curl https://raw.githubusercontent.com/undertow-io/undertow/master/core/src/test/resources/server.keystore >standalone/configuration/server.keystore
curl https://raw.githubusercontent.com/undertow-io/undertow/master/core/src/test/resources/server.truststore >standalone/configuration/server.truststore

When you’re done with that, start the server and add a https connector via the command-line tool (connect to your running server and issue the commands highlighted in the following):

$>jboss-cli.bat|sh

You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.

[disconnected /] connect

[standalone@localhost:9990 /] /core-service=management/security-realm=https:add()

{"outcome" => "success"}

[standalone@localhost:9990 /]  /core-service=management/security-realm=https/authentication=truststore:add(keystore-path=server.truststore, keystore-password=password, keystore-relative-to=jboss.server.config.dir)

{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}

[standalone@localhost:9990 /] /core-service=management/security-realm=https/server-identity=ssl:add(keystore-path=server.keystore, keystore-password=password, keystore-relative-to=jboss.server.config.dir)

{
    "outcome" => "success",
    "response-headers" => {
        "operation-requires-reload" => true,
        "process-state" => "reload-required"
    }
}

[standalone@localhost:9990 /] /subsystem=undertow/server=default-server/https-listener=https:add(socket-binding=https, security-realm=https, enable-http2=true)

{
    "outcome" => "success",
    "response-headers" => {"process-state" => "reload-required"}
}
[standalone@localhost:9990 /]

Shutdown and re-start your EAP instance.

Testing The Connection

When the server is up again, point your browser to https://localhost:8443. After clicking through the security warning about the self signed certificate you see the normal EAP 7 welcome page.

But how do you find out, that the connection is actually using HTTP/2? You can do this in various ways. If you’re using Chrome, you can enter “chrome://net-internals” in the browser bar and select “HTTP/2” in the dropdown. If you re-load the EAP homepage and come back to the network page in chrome, you can see the HTTP/2 session with all headers and information.

eap7-http2-session

Another option is to use a little JavaScript and deploy it in your application:

<p style="font-size: 125%;">You are currently connected using the protocol: <b style='color: darkred;' id="transport">checking...</b>.</p>
<p id="summary" />
<script>
    var url = "/";
    var xhr = new XMLHttpRequest();

    xhr.onreadystatechange = function(e) {
        if (this.readyState === 4) {
            var transport = this.status == 200 ? xhr.getResponseHeader("X-Undertow-Transport") : null;
            transport = transport == null ? "unknown" : transport;
            document.getElementById("transport").innerHTML = transport;
            var summary = "No HTTP/2 Support!";
            if (transport.indexOf("h2") == 0) {
                summary = "Congratulations! Your client is using HTTP/2.";
            }
            document.getElementById("summary").innerHTML = summary;
        }

    }
    xhr.open('HEAD', url, true);
    xhr.send();
</script>

Congratulations! You just upgraded your EAP installation to HTTP/2! Don’t forget to give feedback and learn more about JBoss EAP 7: And please keep in mind:  just like with any Alpha release, please anticipate issues. If you find any please report them in the
corresponding JIRA.

Markus Eisele

Markus is a Developer Advocate at Red Hat and focuses on JBoss Middleware. He is working with Java EE servers from different vendors since more than 14 years and talks about his favorite topics around Java EE on conferences all over the world. He has been a principle consultant and worked with different customers on all kinds of Java EE related applications and solutions. Beside that he has always been a prolific blogger, writer and tech editor for different Java EE related books. He is an active member of the German DOAG e.V. and it's representative on the iJUG e.V. As a Java Champion and former ACE Director he is well known in the community. Follow him on Twitter @myfear.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button