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 Jetty project provides an implementation of the Transport Layer Security (TLS) extension for Next Protocol Negotiation (NPN) for OpenJDK 7 or greater. NPN allows the application layer to negotiate which protocol to use over the secure connection.
NPN currently negotiates using SPDY as an application level protocol on port 443, and also negotiates the SPDY version. However, NPN is not SPDY-specific in any way. Jetty's NPN implementation, although hosted under the umbrella of the Jetty project, is independent of Jetty (the servlet container); you can use it in any other Java network server.
To enable NPN support, start the JVM as follows:
path_to_npn_boot_jar is the path on the
file system for the NPN Boot Jar file, for example, one at the Maven
Be aware that the current versions of the npn packages no longer align with Jetty versions. Look at the dates in those file paths before looking at the version number.
To use NPN in an OSGi environment, in addition to putting the NPN jar on the boot classpath for the container, you will also need to deploy the jetty-osgi-npn jar. This jar contains a Fragment-Host directive that ensures the NPN classes will be available from the system bundle.
You can download the jetty-osgi-npn jar from maven central: http://repo1.maven.org/maven2/org/eclipse/jetty/osgi/jetty-osgi-npn/
Applications need to interact with NPN TLS extension protocol negotiations. For example, server applications need to know whether the client supports NPN, and client applications needs to know the list of protocols the server supports, and so on.
To implement this interaction, Jetty's NPN implementation provides an API to applications, hosted at Maven coordinates org.eclipse.jetty.npn:npn-api. You need to declare this dependency as provided, because the npn-boot Jar already includes it (see the previous section), and it is therefore available in the boot classpath.
The API consists of a single class,
org.eclipse.jetty.npn.NextProtoNego, and applications need to
register instances of SSLSocket or SSLEngine with a ClientProvider or
ServerProvider (depending on whether the application is a client or server
application). Refer to NextProtoNego Javadocs and to the examples below
for further details about client and server provider methods.
The NPN implementation calls
so that the client application can decide:
whether to support NPN.
whether the server supports NPN.
to select one of the protocols the server supports.
The example for SSLEngine is identical, and you just need to replace the SSLSocket instance with an SSLEngine instance.
The NPN implementation calls
protocolSelected(String), so that the
server application can
know whether the client supports NPN.
provide the list of protocols the server supports.
know which protocol the client chooses.
It is common that the NextProtoNego.ServerProvider and the NextProtoNego.ClientProvider are implemented as (anonymous) inner classes, and that their methods' implementations require references to the the sslSocket (or sslEngine), either directly or indirectly.
Since the NextProtoNego class holds [sslSocket/sslEngine, provider] pairs in a WeakHashMap, if the value (that is, the provider implementation) holds a strong (even indirect) reference to the key, then the WeakHashMap entries are never removed, leading to a memory leak.
For example, in Jetty the implementation of NextProtoNego.ServerProvider requires a reference to an org.eclipse.jetty.io.nio.SslConnection that in turn holds a reference to the sslEngine. Therefore the NextProtoNego.ServerProvider implementation does not use the SslConnection directly, but instead via an AtomicReference that is cleared upon connection close.
Be aware that declaring the SslConnection as a final local variable and referencing it from within the anonymous NextProtoNego.ServerProvider class generates a hidden field in the anonymous inner class, causing the memory leak, so you must avoid doing so.
You can write and run unit tests that use the NPN 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 NPN implementation in this way:
NextProtoNego.debug = true;
Since the NextProtoNego 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 NPN 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 NextProtoNego class is released under same license as the classes of the Jetty project.
The NPN implementation, relying on modifications of OpenJDK classes, updates every time there are updates to the modified OpenJDK classes.
Table 15.1. NPN vs. OpenJDK versions
|NPN version||OpenJDK version|
|1.0.0.v20120402||1.7.0 - 1.7.0u2 - 1.7.0u3|
|1.1.0.v20120525||1.7.0u4 - 1.7.0u5|
|1.1.1.v20121030||1.7.0u6 - 1.7.0u7|
|1.1.3.v20130313||1.7.0u9 - 1.7.0u10 - 1.7.0u11|
|1.1.5.v20130313||1.7.0u15 - 1.7.0u17 - 1.7.0u21 - 1.7.0u25|
|1.1.6.v20130911||1.7.0u40 - 1.7.0u45 - 1.7.0u51|
This section is for Jetty developers that need to update the NPN implementation with the OpenJDK versions.
Clone the OpenJDK repository with the following command:
$ hg clone http://hg.openjdk.java.net/jdk7u/jdk7u jdk7u $ cd jdk7u $ ./get_source.sh
To update the source to a specific tag, use the following command:
$ ./make/scripts/hgforest.sh update <tag-name>
The list of OpenJDK tags can be obtained from this page.
Then you need to compare and incorporate the OpenJDK source changes into the modified OpenJDK classes at the NPN GitHub Repository.