private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ... scalability guidance for your apps and Ajax/Comet projects ... development services from 1 day to full product delivery
The development of new web protocols such as SPDY and HTTP 2.0 raised the need of protocol negotiation within a Transport Layer Security (TLS) handshake. Two protocol negotiation solutions have been proposed: an older one, called NPN (see Chapter 16, NPN) and a newer one, called ALPN (Application Layer Protocol Negotiation).
ALPN is going to replace NPN very soon, and major browsers already support ALPN, as well as major servers such as Jetty.
The Jetty project provides an implementation of the TLS extension for ALPN for OpenJDK 7 and OpenJDK 8. ALPN allows the application layer to negotiate which protocol to use over the secure connection.
Any protocol can be negotiated by ALPN within a TLS connection. The protocols that are most commonly negotiated are SPDY (for browsers that support it) and, currently in an experimental way, HTTP 2.0. The ALPN implementation is therefore not SPDY-specific in any way. Jetty's ALPN implementation, although hosted under the umbrella of the Jetty project, is independent of Jetty (the Servlet Container); you can use the ALPN implementation in any other Java network server.
To enable ALPN support, start the JVM as follows:
path_to_alpn_boot_jar is the path on the
file system for the ALPN Boot Jar file, for example, one at the Maven
To use ALPN in an OSGi environment, in addition to putting the ALPN jar on the boot classpath for the container, you will also need to deploy the jetty-osgi-alpn jar. This jar contains a Fragment-Host directive that ensures the ALPN classes will be available from the system bundle.
You can download the jetty-osgi-alpn jar from Maven Central.
Applications need to interact with ALPN TLS extension protocol negotiations. For example, server applications need to know whether the client supports ALPN, and client applications needs to know whether the server supports ALPN.
To implement this interaction, Jetty's ALPN implementation provides
an API to applications, hosted at Maven coordinates
org.eclipse.jetty.alpn:alpn-api. You need to declare this dependency as
provided, because the
alpn-boot Jar already includes it (see the previous
section), and it is therefore available from the boot classpath.
The API consists of a single class,
org.eclipse.jetty.alpn.ALPN, and applications need to
register instances of
(depending on whether the application is a client application or server
application). Refer to
ALPN Javadocs and to the examples below
for further details about client and server provider methods.
The ALPN implementation calls
so that the client application can:
decide whether to support ALPN.
provide the protocols supported.
know whether the server supports ALPN.
know the protocol chosen by the server.
The example for SSLEngine is identical, and you just need to replace the SSLSocket instance with an SSLEngine instance.
The ALPN implementation calls
select(List<String>), so that the
server application can:
know whether the client supports ALPN.
select one of the protocols the client supports.
It is important that implementations of
ALPN.ClientProvider remove the
sslEngine when the negotiation is complete, like shown in
the examples above.
Failing to do so will cause a memory leak.
You can write and run unit tests that use the ALPN implementation. The solution that we use with Maven is to specify an additional command line argument to the Surefire plugin:
You can enable debug logging for the ALPN implementation in this way:
ALPN.debug = true;
Since the ALPN class is in the boot classpath, we chose not
to use logging libraries because we do not want to override application
logging library choices; therefore the logging is performed directly on
The ALPN implementation relies on modification of a few OpenJDK
classes and on a few new classes that need to live in the
sun.security.ssl package. These classes are released
under the same GPLv2+exception license of OpenJDK.
The ALPN class and its nested classes are released under same license as the classes of the Jetty project.
The ALPN implementation, relying on modifications of OpenJDK classes, updates every time there are updates to the modified OpenJDK classes.
Table 15.1. ALPN vs. OpenJDK versions
|OpenJDK version||ALPN version|
This section is for Jetty developers that need to update the ALPN implementation with the OpenJDK versions.
Clone the OpenJDK repository with the following command:
$ hg clone http://hg.openjdk.java.net/jdk7u/jdk7u jdk7u # OpenJDK 7 $ hg clone http://hg.openjdk.java.net/jdk8u/jdk8u jdk8u # OpenJDK 8 $ cd !$ $ ./get_source.sh
To update the source to a specific tag, use the following command:
$ ./make/scripts/hgforest.sh update <tag-name>
Then you need to compare and incorporate the OpenJDK source changes
into the modified OpenJDK classes at the ALPN GitHub
openjdk7 for OpenJDK 7 and
master for OpenJDK 8.