Enterprise grade Java.
You'll read about Conferences, Java User Groups, Java, Integration, Reactive, Microservices and other technologies.

Thursday, November 19, 2015

HTTP/2 With JBoss EAP 7 - Tech Preview

12:42 Thursday, November 19, 2015 Posted by Markus Eisele
, ,
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.

Network Connection Properties in Chrome


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.