diff --git a/examples/embedded/pom.xml b/examples/embedded/pom.xml
index adc1b4d984c..0aefbe860a1 100644
--- a/examples/embedded/pom.xml
+++ b/examples/embedded/pom.xml
@@ -15,13 +15,6 @@
${project.groupId}.embedded
-
-
- com.google.guava
- guava
- 18.0
-
-
org.eclipse.jetty
jetty-util-ajax
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java
index d75498b0bac..d926cdaeab0 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/Http2Server.java
@@ -122,7 +122,6 @@ public class Http2Server
ALPN.debug=false;
server.start();
- //server.dumpStdErr();
server.join();
}
diff --git a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java
index 794d116f106..49016135da9 100644
--- a/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java
+++ b/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java
@@ -20,6 +20,8 @@ package org.eclipse.jetty.embedded;
import java.io.File;
import java.io.FileNotFoundException;
+import java.security.Provider;
+import java.security.Security;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.Connector;
@@ -37,7 +39,7 @@ import org.eclipse.jetty.util.ssl.SslContextFactory;
public class ManyConnectors
{
public static void main( String[] args ) throws Exception
- {
+ {
// Since this example shows off SSL configuration, we need a keystore
// with the appropriate key. These lookup of jetty.home is purely a hack
// to get access to a keystore that we use in many unit tests and should
@@ -84,6 +86,9 @@ public class ManyConnectors
// to know about. Much more configuration is available the ssl context,
// including things like choosing the particular certificate out of a
// keystore to be used.
+
+ Security.addProvider((Provider)ClassLoader.getSystemClassLoader().loadClass("org.conscrypt.OpenSSLProvider").newInstance());
+
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(keystoreFile.getAbsolutePath());
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
@@ -126,6 +131,7 @@ public class ManyConnectors
// Start the server
server.start();
+
server.join();
}
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
index 2ec5516e77d..d813a2455af 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationParser.java
@@ -68,10 +68,30 @@ public class AnnotationParser
{
private static final Logger LOG = Log.getLogger(AnnotationParser.class);
+ private static final int JVM_MAJOR_VER;
+
protected Set _parsedClassNames = ConcurrentHashMap.newKeySet();
protected static int ASM_OPCODE_VERSION = Opcodes.ASM5; //compatibility of api
-
+
+ static
+ {
+ // Determine JVM spec version
+ // Using guidance from http://openjdk.java.net/jeps/223
+ String jvmSpecVer = System.getProperty("java.vm.specification.version");
+
+ if (jvmSpecVer.indexOf('.') >= 0)
+ {
+ // Old spec version (Java 1.8 and older)
+ String parts[] = jvmSpecVer.split("\\.");
+ JVM_MAJOR_VER = Integer.parseInt(parts[1]);
+ }
+ else
+ {
+ // Newer spec version (Java 9+)
+ JVM_MAJOR_VER = Integer.parseInt(jvmSpecVer);
+ }
+ }
/**
* Convert internal name to simple name
@@ -1017,10 +1037,61 @@ public class AnnotationParser
if (path == null || path.length()==0)
return false;
- //skip any classfiles that are in a hidden directory
+ if (path.startsWith("META-INF/versions/"))
+ {
+ // Handle JEP 238 - Multi-Release Jars
+ if (JVM_MAJOR_VER < 9)
+ {
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("JEP-238 Multi-Release JAR not supported on Java " +
+ System.getProperty("java.version") + ": " + path);
+ }
+ return false;
+ }
+
+ // Safety check for ASM bytecode support level.
+ // When ASM 6.0 is integrated, the below will start to work.
+ if (ASM_OPCODE_VERSION <= Opcodes.ASM5)
+ {
+ // Cannot scan Java 9 classes with ASM version 5
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Unable to scan newer Java bytecode (Java 9?) with ASM 5 (skipping): " + path);
+ }
+ return false;
+ }
+
+ int idxStart = "META-INF/versions/".length();
+ int idxEnd = path.indexOf('/', idxStart + 1);
+ try
+ {
+ int pathVersion = Integer.parseInt(path.substring(idxStart, idxEnd));
+ if (pathVersion < JVM_MAJOR_VER)
+ {
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("JEP-238 Multi-Release JAR version " + pathVersion +
+ " not supported on Java " + System.getProperty("java.version") +
+ ": " + path);
+ }
+ return false;
+ }
+ }
+ catch (NumberFormatException e)
+ {
+ if (LOG.isDebugEnabled())
+ {
+ LOG.debug("Not a valid JEP-238 Multi-Release path: " + path);
+ }
+ return false;
+ }
+ }
+
+ // skip any classfiles that are in a hidden directory
if (path.startsWith(".") || path.contains("/."))
{
- if (LOG.isDebugEnabled()) LOG.debug("Contains hidden dirs: {}"+path);
+ if (LOG.isDebugEnabled()) LOG.debug("Contains hidden dirs: " + path);
return false;
}
diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java
index 10c91074302..7f7cc18cd6c 100644
--- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java
+++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/DeclareRolesAnnotationHandler.java
@@ -18,11 +18,15 @@
package org.eclipse.jetty.annotations;
+
import javax.annotation.security.DeclareRoles;
import javax.servlet.Servlet;
import org.eclipse.jetty.annotations.AnnotationIntrospector.AbstractIntrospectableAnnotationHandler;
+import org.eclipse.jetty.security.ConstraintAware;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.webapp.WebAppContext;
/**
@@ -30,6 +34,7 @@ import org.eclipse.jetty.webapp.WebAppContext;
*/
public class DeclareRolesAnnotationHandler extends AbstractIntrospectableAnnotationHandler
{
+ private static final Logger LOG = Log.getLogger(DeclareRolesAnnotationHandler.class);
protected WebAppContext _context;
@@ -48,6 +53,12 @@ public class DeclareRolesAnnotationHandler extends AbstractIntrospectableAnnotat
if (!Servlet.class.isAssignableFrom(clazz))
return; //only applicable on javax.servlet.Servlet derivatives
+ if (!(_context.getSecurityHandler() instanceof ConstraintAware))
+ {
+ LOG.warn("SecurityHandler not ConstraintAware, skipping security annotation processing");
+ return;
+ }
+
DeclareRoles declareRoles = (DeclareRoles) clazz.getAnnotation(DeclareRoles.class);
if (declareRoles == null)
return;
diff --git a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java
index 8ab3cfe5f9a..954d2f3d97f 100644
--- a/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java
+++ b/jetty-annotations/src/test/java/org/eclipse/jetty/annotations/TestAnnotationParser.java
@@ -163,6 +163,26 @@ public class TestAnnotationParser
// only the valid classes inside bad-classes.jar should be parsed. If any invalid classes are parsed and exception would be thrown here
}
+ @Test
+ public void testModuleInfoClassInJar() throws Exception
+ {
+ File badClassesJar = MavenTestingUtils.getTestResourceFile("jdk9/slf4j-api-1.8.0-alpha2.jar");
+ AnnotationParser parser = new AnnotationParser();
+ Set emptySet = Collections.emptySet();
+ parser.parse(emptySet, badClassesJar.toURI());
+ // Should throw no exceptions, and happily skip the module-info.class files
+ }
+
+ @Test
+ public void testJep238MultiReleaseInJar() throws Exception
+ {
+ File badClassesJar = MavenTestingUtils.getTestResourceFile("jdk9/log4j-api-2.9.0.jar");
+ AnnotationParser parser = new AnnotationParser();
+ Set emptySet = Collections.emptySet();
+ parser.parse(emptySet, badClassesJar.toURI());
+ // Should throw no exceptions, and skip the META-INF/versions/9/* files
+ }
+
@Test
public void testBasedirExclusion() throws Exception
{
diff --git a/jetty-annotations/src/test/resources/jdk9/log4j-api-2.9.0.jar b/jetty-annotations/src/test/resources/jdk9/log4j-api-2.9.0.jar
new file mode 100644
index 00000000000..ab98d40e9a2
Binary files /dev/null and b/jetty-annotations/src/test/resources/jdk9/log4j-api-2.9.0.jar differ
diff --git a/jetty-annotations/src/test/resources/jdk9/slf4j-api-1.8.0-alpha2.jar b/jetty-annotations/src/test/resources/jdk9/slf4j-api-1.8.0-alpha2.jar
new file mode 100644
index 00000000000..7a2a9b2d8e4
Binary files /dev/null and b/jetty-annotations/src/test/resources/jdk9/slf4j-api-1.8.0-alpha2.jar differ
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java
index cb2fa71af84..1dca5d058f6 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpResponseAbortTest.java
@@ -29,9 +29,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.client.api.Response;
-import org.eclipse.jetty.client.api.Result;
-import org.eclipse.jetty.http.HttpField;
+import org.eclipse.jetty.client.util.DeferredContentProvider;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
@@ -53,22 +51,11 @@ public class HttpResponseAbortTest extends AbstractHttpClientServerTest
final CountDownLatch latch = new CountDownLatch(1);
client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
- .onResponseBegin(new Response.BeginListener()
+ .onResponseBegin(response -> response.abort(new Exception()))
+ .send(result ->
{
- @Override
- public void onBegin(Response response)
- {
- response.abort(new Exception());
- }
- })
- .send(new Response.CompleteListener()
- {
- @Override
- public void onComplete(Result result)
- {
- Assert.assertTrue(result.isFailed());
- latch.countDown();
- }
+ Assert.assertTrue(result.isFailed());
+ latch.countDown();
});
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
@@ -81,23 +68,15 @@ public class HttpResponseAbortTest extends AbstractHttpClientServerTest
final CountDownLatch latch = new CountDownLatch(1);
client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
- .onResponseHeader(new Response.HeaderListener()
+ .onResponseHeader((response, field) ->
{
- @Override
- public boolean onHeader(Response response, HttpField field)
- {
- response.abort(new Exception());
- return true;
- }
+ response.abort(new Exception());
+ return true;
})
- .send(new Response.CompleteListener()
+ .send(result ->
{
- @Override
- public void onComplete(Result result)
- {
- Assert.assertTrue(result.isFailed());
- latch.countDown();
- }
+ Assert.assertTrue(result.isFailed());
+ latch.countDown();
});
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
@@ -110,23 +89,11 @@ public class HttpResponseAbortTest extends AbstractHttpClientServerTest
final CountDownLatch latch = new CountDownLatch(1);
client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
- .onResponseHeaders(new Response.HeadersListener()
+ .onResponseHeaders(response -> response.abort(new Exception()))
+ .send(result ->
{
- @Override
- public void onHeaders(Response response)
- {
- response.abort(new Exception());
- }
- })
- .send(new Response.CompleteListener()
- {
-
- @Override
- public void onComplete(Result result)
- {
- Assert.assertTrue(result.isFailed());
- latch.countDown();
- }
+ Assert.assertTrue(result.isFailed());
+ latch.countDown();
});
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
@@ -158,22 +125,11 @@ public class HttpResponseAbortTest extends AbstractHttpClientServerTest
final CountDownLatch latch = new CountDownLatch(1);
client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
- .onResponseContent(new Response.ContentListener()
+ .onResponseContent((response, content) -> response.abort(new Exception()))
+ .send(result ->
{
- @Override
- public void onContent(Response response, ByteBuffer content)
- {
- response.abort(new Exception());
- }
- })
- .send(new Response.CompleteListener()
- {
- @Override
- public void onComplete(Result result)
- {
- Assert.assertTrue(result.isFailed());
- latch.countDown();
- }
+ Assert.assertTrue(result.isFailed());
+ latch.countDown();
});
Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}
@@ -202,53 +158,31 @@ public class HttpResponseAbortTest extends AbstractHttpClientServerTest
}
});
- final CountDownLatch abortLatch = new CountDownLatch(1);
+ final DeferredContentProvider contentProvider = new DeferredContentProvider(ByteBuffer.allocate(1));
final AtomicInteger completes = new AtomicInteger();
final CountDownLatch completeLatch = new CountDownLatch(1);
client.newRequest("localhost", connector.getLocalPort())
.scheme(scheme)
- .onRequestSuccess(new org.eclipse.jetty.client.api.Request.SuccessListener()
+ .content(contentProvider)
+ .onResponseContent((response, content) ->
{
- @Override
- public void onSuccess(org.eclipse.jetty.client.api.Request request)
+ try
{
- try
- {
- abortLatch.await(5, TimeUnit.SECONDS);
- }
- catch (InterruptedException x)
- {
- x.printStackTrace();
- }
+ response.abort(new Exception());
+ contentProvider.close();
+ // Delay to let the request side to finish its processing.
+ Thread.sleep(1000);
+ }
+ catch (InterruptedException x)
+ {
+ x.printStackTrace();
}
})
- .onResponseContent(new Response.ContentListener()
+ .send(result ->
{
- @Override
- public void onContent(Response response, ByteBuffer content)
- {
- try
- {
- response.abort(new Exception());
- abortLatch.countDown();
- // Delay to let the request side to finish its processing.
- Thread.sleep(1000);
- }
- catch (InterruptedException x)
- {
- x.printStackTrace();
- }
- }
- })
- .send(new Response.CompleteListener()
- {
- @Override
- public void onComplete(Result result)
- {
- completes.incrementAndGet();
- Assert.assertTrue(result.isFailed());
- completeLatch.countDown();
- }
+ completes.incrementAndGet();
+ Assert.assertTrue(result.isFailed());
+ completeLatch.countDown();
});
Assert.assertTrue(completeLatch.await(5, TimeUnit.SECONDS));
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/chapter.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/chapter.adoc
index 6f36fb4d379..92a8cbde8d3 100644
--- a/jetty-documentation/src/main/asciidoc/administration/sessions/chapter.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/chapter.adoc
@@ -25,6 +25,8 @@ Jetty also offers more niche session managers that leverage backends such as Mon
include::session-hierarchy.adoc[]
include::sessions-details.adoc[]
+include::session-configuration-housekeeper.adoc[]
+include::session-configuration-sessioncache.adoc[]
include::session-configuration-memory.adoc[]
include::session-configuration-file-system.adoc[]
include::session-configuration-jdbc.adoc[]
@@ -32,6 +34,8 @@ include::session-configuration-mongodb.adoc[]
include::session-configuration-infinispan.adoc[]
include::session-configuration-hazelcast.adoc[]
include::session-configuration-gcloud.adoc[]
+include::session-configuration-memcachedsessiondatastore.adoc[]
+include::sessions-usecases.adoc[]
//include::setting-session-characteristics.adoc[]
//include::using-persistent-sessions.adoc[]
//include::session-clustering-jdbc.adoc[]
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-file-system.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-file-system.adoc
index db7d3cf7fed..5f2ae862691 100644
--- a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-file-system.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-file-system.adoc
@@ -16,7 +16,9 @@
[[configuring-sessions-file-system]]
-=== Non-Clustered Session Management: File System
+=== Persistent Sessions: File System
+
+Note: Persisting sessions to the local file system should *not* be used in a clustered environment.
==== Enabling File System Sessions
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-gcloud.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-gcloud.adoc
index a1b95614edd..d0dc99d0d8c 100644
--- a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-gcloud.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-gcloud.adoc
@@ -15,7 +15,8 @@
// ========================================================================
[[configuring-sessions-gcloud]]
-=== Clustered Session Management: Google Cloud DataStore
+
+=== Persistent Sessions: Google Cloud DataStore
==== Preparation
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc
index a424404e149..e6e3239e73d 100644
--- a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc
@@ -16,7 +16,7 @@
[[configuring-sessions-hazelcast]]
-=== Clustered Session Management: Hazelcast
+=== Persistent Sessions: Hazelcast
==== Enabling Hazelcast Sessions
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-housekeeper.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-housekeeper.adoc
new file mode 100644
index 00000000000..587cf65cc2f
--- /dev/null
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-housekeeper.adoc
@@ -0,0 +1,54 @@
+// ========================================================================
+// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
+// ========================================================================
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+[[session-configuration-housekeeper]]
+=== The SessionIdManager and the Housekeeper
+
+==== Default Settings
+By default, Jetty will instantiate a single instance of the `DefaultSessionIdManager` and `HouseKeeper` at startup with default settings.
+
+The default settings are:
+
+DefaultSessionIdManager: worker name::
+This uniquely identifies the jetty server instance within a cluster.
+It is set from the value of the `JETTY_WORKER_INSTANCE` environment variable, or `node0` if the environment value is not set.
+If you have more than one Jetty instance, it is *crucial* that you explicitly configure the worker name on each Jetty instance (see link:#session-idmanager-housekeeper-config[below] for how to configure).
+
+HouseKeeper: scavenge interval::
+This is the period in seconds between runs of the session scavenger, and by default is set to the equivalent of 10 minutes.
+As a rule of thumb, you should ensure that the scavenge interval is shorter than the `maxInactiveInterval` of your sessions to ensure that they are promptly scavenged.
+See below for instructions on how to configure this.
+
+[[session-idmanager-housekeeper-config]]
+==== Configuration
+To change the default values, use the link:#startup-modules[module system] to link:#startup-modules[enable] the `sessions` module.
+
+This will enable the `$jetty.home/etc/sessions/id-manager.xml` file and generate a `$jetty.base/start.d/sessions.ini` file.
+
+The `id-manager.xml` file instantiates a single `DefaultSessionIdManager` and `HouseKeeper` and configures them using the properties from the `sessions.ini` file.
+
+Edit the ini file to change the properties to easily customize the `DefaultSessionIdManager` and `HouseKeeper`:
+
+jetty.sessionIdManager.workerName::
+By default it is `node1`.
+This uniquely identifies the Jetty server instance within a cluster.
+If you have more than one Jetty instance, it is crucial that you configure the worker name differently on each jetty instance.
+
+
+jetty.sessionScavengeInterval.seconds::
+This is the period in seconds between runs of the session scavenger.
+By default it will run every 600 secs (ie 10 mins).
+As a rule of thumb, you should ensure that the scavenge interval is shorter than the maxInactiveInterval of your sessions to ensure that they are promptly scavenged.
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc
index c4cad1f7669..0bb6af9fe6c 100644
--- a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc
@@ -16,7 +16,7 @@
[[configuring-sessions-infinispan]]
-=== Clustered Session Management: Inifinspan
+=== Persistent Sessions: Inifinspan
==== Enabling Infinispan Sessions
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-jdbc.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-jdbc.adoc
index 4902b880d33..4d095ba88dc 100644
--- a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-jdbc.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-jdbc.adoc
@@ -16,7 +16,7 @@
[[configuring-sessions-jdbc]]
-=== Clustered Session Management: JDBC
+=== Persistent Sessions: JDBC
==== Enabling JDBC Sessions
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-memcachedsessiondatastore.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-memcachedsessiondatastore.adoc
new file mode 100644
index 00000000000..9ccfd52553a
--- /dev/null
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-memcachedsessiondatastore.adoc
@@ -0,0 +1,62 @@
+// ========================================================================
+// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
+// ========================================================================
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+[[session-configuration-memcachedsessiondatastore]]
+
+=== Persistent Sessions: The L2 Session Data Cache
+
+If your chosen persistence technology is slow, it can be helpful to locally cache the session data.
+The `CachingSessionDataStore` is a special type of `SessionDataStore` that locally caches session data, which makes reads faster. It writes-through to your chosen type of `SessionDataStore` when session data changes.
+
+==== MemcachedSessionDataMap
+
+The `MemcachedSessionDataMap` uses `memcached` to perform caching.
+
+To enable it with the Jetty distribution, enable the `session-store-cache` link:#startup-modules[module], along with your chosen `session-store-xxxx` module, and optionally the `session-cache-hash` or `session-cache-null` modules.
+
+After enabling, the `$jetty.base/start.d/session-store-cache.ini` file will be generated:
+
+[source, screen, subs="{sub-order}"]
+----
+--module=session-store-cache
+
+
+## Session Data Cache type: xmemcached
+session-data-cache=xmemcached
+#jetty.session.memcached.host=localhost
+#jetty.session.memcached.port=11211
+#jetty.session.memcached.expirySec=
+#jetty.session.memcached.heartbeats=true
+----
+
+
+The configuration properties are:
+
+jetty.session.memcached.host::
+Default value is `localhost`.
+This is the host on which the memcached server resides.
+
+jetty.session.memcached.port::
+Default value is `11211`.
+This is the port on which the memcached server is listening.
+
+jetty.session.memcached.expirySec::
+Default value `0`.
+This is the length of time in seconds that an item can remain in the memcached cache, where 0 indicates indefinitely.
+
+jetty.session.memcached.heartbeats::
+Default value `true`.
+Whether or not the memcached system should generate heartbeats.
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-memory.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-memory.adoc
index 3f72e4bdac9..3fb65192ec8 100644
--- a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-memory.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-memory.adoc
@@ -16,21 +16,16 @@
[[configuring-sessions-memory]]
-=== Non-Clustered Session Management: Memory
+=== Non-Persistent Sessions
-Non-clustered, in-memory-only is the default style of Session Management.
-In previous versions of Jetty this was referred to as "hash" sessions, as they were stored in a `HashMap` in memory.
-When using the Jetty distribution, if you do not configure any session module, this will be enabled by default.
+Non-clustered, non-persistent, in-memory-only is the default style of session management.
+In previous versions of Jetty this was referred to as "hash" sessions, as they were stored in a `HashMap` in memory.
-Specifically, Jetty will hook up:
+This is delivered by a combination of the `DefaultSessionCache` (to keep sessions in memory) and a `NullSessionDataStore` (to avoid session persistence).
-A `DefaultSessionIdManager`::
-* Produces unique session ids and supports cross-context dispatch re-use of session ids
-A `HouseKeeper`::
-* Scavenges for expired sessions every 10 mins
-A `DefaultSessionCache` per context::
-* Keeps session objects in memory
-A `NullSessionDataStore` per context::
-* No persistence of sessions
+If you do nothing, Jetty will instantiate one of each of these objects for each context at startup time using hard-coded defaults.
-If you wish to change any of the default configuration, enable the `session-cache-hash` module.
+To explicitly set up non-persisted sessions using modules, use both the `session-cache-hash` and the `session-store-null` modules.
+
+Enabling the modules allows you to configure behavior - see link:#session-configuration-sessioncache[the L1 Session Cache] for detailed information on configuration options for the `DefaultSessionCache`.
+The `NullSessionDataStore` has no customizable options.
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-mongodb.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-mongodb.adoc
index 770b90456b1..c038acb96e7 100644
--- a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-mongodb.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-mongodb.adoc
@@ -16,7 +16,7 @@
[[configuring-sessions-mongo]]
-=== Clustered Session Management: MongoDB
+=== Persistent Sessions: MongoDB
==== Enabling MongoDB Sessions
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-sessioncache.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-sessioncache.adoc
new file mode 100644
index 00000000000..69b59acb044
--- /dev/null
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-sessioncache.adoc
@@ -0,0 +1,73 @@
+// ========================================================================
+// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
+// ========================================================================
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+[[session-configuration-sessioncache]]
+=== The L1 Session Cache
+
+==== The DefaultSessionCache
+
+In the absence of any explicit configuration, Jetty will instantiate an instance of the `DefaultSessionCache` per context.
+If you wish to change any of the default values, you need to enable the `session-cache-hash` link:#startup-modules[module].
+
+Once the `session-cache-hash` module has been enabled, you can view a list of all the configurable values by opening `start.d/session-cache-hash.ini`:
+
+[source, screen, subs="{sub-order}"]
+----
+--module=session-cache-hash
+
+#jetty.session.evictionPolicy=-1
+#jetty.session.saveOnInactiveEvict=false
+#jetty.session.saveOnCreate=false
+#jetty.session.removeUnloadableSessions=false
+----
+
+jetty.session.evictionPolicy::
+Integer.
+Controls whether session objects that are held in memory are subject to eviction from the memory cache.
+Evicting sessions can reduce the memory footprint of the cache.
+Eviction is usually used in conjunction with a `SessionDataStore` that persists sessions.
+Values are:
+* -1 : sessions are never evicted from the cache
+* 0 : sessions are evicted from the cache as soon as the last active request for it finishes
+* >= 1 : any positive number is the time in seconds after which a session that is in the cache but has not experienced any activity will be evicted
+
+____
+[NOTE]
+If you are not using a `SessionDataStore` that persists sessions, be aware that evicted sessions will be lost.
+____
+
+jetty.session.saveOnInactiveEvict::
+Boolean, default `false`.
+Controls whether a session will be saved to the `SessionDataStore` just prior to its eviction.
+
+jetty.session.saveOnCreate::
+Boolean, default `false`.
+Controls whether a session that is newly created will be immediately saved to the `SessionDataStore` or lazily saved as the last request for the session exits.
+
+jetty.session.removeUnloadableSessions::
+Boolean, default `false`.
+Controls whether a session that cannot be restored - for example because it is corrupted - from the `SessionDataStore` is deleted by the `SessionDataStore`.
+
+For more general information on the uses of these configuration properties, see link:#sessions-details[Session Components].
+
+
+==== The NullSessionCache
+
+The `NullSessionCache` is a trivial implementation of the `SessionCache` that does not cache any session information.
+You may need to use it if your clustering setup does not have a sticky load balancer, or if you want absolutely minimal support for sessions.
+If you use this in conjunction with the `NullSessionDataStore`, then sessions will neither be retained in memory nor persisted.
+
+To enable the `NullSessionCache`, enable the `sesssion-cache-null` link:#startup-modules[module].
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-hierarchy.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-hierarchy.adoc
index 7552dc01864..d5539736b82 100644
--- a/jetty-documentation/src/main/asciidoc/administration/sessions/session-hierarchy.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-hierarchy.adoc
@@ -49,8 +49,11 @@ image::images/SessionsHierarchy.png[]
==== Configuring Sessions in the Jetty Distribution
-Jetty provides support for several different Session Management technologies.
-Both link:#configuring-sessions-file-system[local file storage] and in-memory session management can be implemented for standard implementations.
-For implementations using clustered technologies, link:#configuring-sessions-jdbc[JDBC], link:#configuring-sessions-mongo[MongoDB], link:#configuring-sessions-infinispan[Inifinispan] and link:#configuring-sessions-gcloud[Google Cloud Datastore] are all supported.
-Setting up these technologies is as easy as enabling it's link:#startup-modules[module] and editing it's associated ini file with any usernames, passwords or changes you need to make for your instance.
-The following sections will cover how exactly to enable the required modules as well as an overview of what options are available for customization.
+Configuring session management involves selecting a link:#startup-modules[module] for the desired type of link:#session-configuration-sessioncache[session caching] behavior, and a module for the type of session persistence.
+
+Jetty provides two different session caches: the `DefaultSessionCache` which holds sessions in memory, and the `NullSessionCache` which does not.
+There is more information on both of these types of session caching and the circumstances which would lead you to select one or the other in the link:#sessions-details[Session Components] section, and more information on the configuration options of each in link:#session-configuration-sessioncache[the L1 Session Cache] section.
+
+For session persistence, Jetty provides a number of different implementations from which to choose including link:#configuring-sessions-memory[non-persistence], link:#configuring-sessions-file-system[local file storage], clustered technologies such as link:#configuring-sessions-jdbc[JDBC], link:#configuring-sessions-mongo[MongoDB], link:#configuring-sessions-infinispan[Inifinispan], link:#configuring-sessions-gcloud[Google Cloud Datastore], and link:#configuring-sessions-hazelcast[Hazelcast].
+
+Depending on your persistence technology, to enhance performance, you may want to use an L2 cache for session data, in which case Jetty provides the link:#session-configuration-memcachedsessiondatastore[memcached L2 session data cache].
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/sessions-details.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/sessions-details.adoc
index 20cb4a3eb5f..dac104a6f26 100644
--- a/jetty-documentation/src/main/asciidoc/administration/sessions/sessions-details.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/sessions-details.adoc
@@ -15,40 +15,43 @@
// ========================================================================
[[sessions-details]]
-=== Session Configuration and Use Cases
+=== Session Components
-==== Configuration
+==== SessionIdManager
-===== SessionIdManager
-
-There is a maximum of 1 `SessionIdManager` per jetty Server instance.
+There is a maximum of one (1) `SessionIdManager` per Jetty Server instance.
Its purpose is to generate fresh, unique session ids and to coordinate the re-use of session ids amongst co-operating contexts.
Unlike in previous versions of Jetty, the `SessionIdManager` is agnostic with respect to the type of clustering technology chosen.
Jetty provides a default implementation - the `DefaultSessionIdManager` - which should meet the needs of most users.
-If you do not explicitly enable one of the session modules, or otherwise configure a `SessionIdManager`, the `DefaultSessionIdManager` will be used.
+If you do not explicitly enable one of the session modules or otherwise configure a `SessionIdManager`, the `DefaultSessionIdManager` will be used.
If the `DefaultSessionIdManager` does not meet your needs, you can extend the `org.eclipse.jetty.server.session.AbstractSessionIdManager` or do a fresh implementation of the `org.eclipse.jetty.server.session.SessionIdManager` interface.
-===== HouseKeeper
+See link:#session-configuration-housekeeper[Configuring the SessionIdManager and HouseKeeper] for details on configuration.
-There is a maximum of 1 `HouseKeeper` per `SessionIdManager`.
+==== HouseKeeper
+
+There is a maximum of one (1) `HouseKeeper` per `SessionIdManager`.
Its purpose is to periodically poll the `SessionHandlers` to clean out expired sessions.
By default the `HouseKeeper` will poll the `SessionHandlers` every 10 mins to find and delete expired sessions, although this interval is configurable.
+See link:#session-configuration-housekeeper[Configuring the SessionIdManager and HouseKeeper] for details on configuration.
-===== SessionCache
-There is 1 `SessionCache` per context.
+==== SessionCache
+
+There is one (1) `SessionCache` *per context.*
Its purpose is to provide an L1 cache of Session objects.
Having a working set of Session objects in memory allows multiple simultaneous requests for the same session to share the same Session object.
-Jetty provides 2 `SessionCache` implementations: the `DefaultSessionCache` and the `NullSessionCache`.
-The `DefaultSessionCache` retains Session objects in memory in a cache and has a number of configuration options to control cache behavior.
+Jetty provides two (2) `SessionCache` implementations: the `DefaultSessionCache` and the `NullSessionCache`.
+The `DefaultSessionCache` retains Session objects in memory in a cache and has a number of link:#session-configuration-sessioncache[configuration options] to control cache behavior.
It is the default that is used if no other `SessionCache` has been configured.
It is suitable for non-clustered and clustered deployments with a sticky load balancer, as well as clustered deployments with a non-sticky load balancer, with some caveats.
+
The `NullSessionCache` does not actually cache any objects: each request uses a fresh Session object.
It is suitable for clustered deployments without a sticky load balancer and non-clustered deployments when purely minimal support for sessions is needed.
@@ -58,16 +61,19 @@ They can also be configured to do an immediate, eager write of a freshly created
This can be useful if you are likely to experience multiple, near simultaneous requests referencing the same session, e.g. with HTTP/2 and you don't have a sticky load balancer.
Alternatively, if the eager write is not done, application paths which create and then invalidate a session within a single request never incur the cost of writing to persistent storage.
-Additionally, if the `EVICT_ON_INACTIVITY` eviction policy is in use, you can configure the `DefaultSessionCache` to force a write of the Session to the SessionDataStore just before the Session is evicted.
+Additionally, if the `EVICT_ON_INACTIVITY` eviction policy is in use, you can link:#session-configuration-sessioncache[configure] the `DefaultSessionCache` to force a write of the Session to the `SessionDataStore` just before the Session is evicted.
-===== SessionDataStore
+See link:#session-configuration-sessioncache[the L1 Session Cache] for more information.
-There is 1 `SessionDataStore` per context. Its purpose is to handle all persistence related operations on sessions.
+==== SessionDataStore
+
+There is one (1) `SessionDataStore` per context.
+Its purpose is to handle all persistence related operations on sessions.
The common characteristics for all `SessionDataStores` are whether or not they support passivation, and the length of the grace period.
Supporting passivation means that session data is serialized.
-Some persistence mechanisms serialize, such as JDBC, GCloud Datastore etc, whereas others may store an object in shared memory eg Infinispan when configured with a local cache.
+Some persistence mechanisms serialize, such as JDBC, GCloud Datastore etc, whereas others may store an object in shared memory, e.g. Infinispan, when configured with a local cache.
Whether or not a clustering technology entails passivation controls whether or not the session passivation/activation listeners will be called.
@@ -79,56 +85,17 @@ When `SessionDataStores` search their persistent store to find sessions that hav
* The second finds sessions in the store that have expired which were last live on the current node
* The third finds sessions that expired a "while" ago, irrespective of on which node they were last used: the definition of "a while" is based on the grace period.
+Jetty instantiates the trivial `NullSessionDataStore` - which does not persist sessions - as the default.
-===== CachingSessionDataStore
+The distribution provides a number of alternative `SessionDataStore` implementations such as link:#configuring-sessions-file-system[FileSessionDataStore], link:#configuring-sessions-gcloud[GCloudSessionDataStore], link:#configuring-sessions-jdbc[JDBCSessionDataStore], link:#configuring-sessions-mongodb[MongoSessionDataStore], link:#configuring-sessions-infinispan[InfinispanSessionDataStore], link:#configuring-sessions-hazelcast[HazelcastSessionDataStore].
-The `CachingSessionDataStore` is a special type of `SessionDataStore` that inserts an L2 cache of SessionData - the `SessionDataMap` - in front of a delegate `SessionDataStore`.
+
+==== CachingSessionDataStore
+
+The `CachingSessionDataStore` is a special type of `SessionDataStore` that inserts an L2 cache of Session data - the `SessionDataMap` - in front of a delegate `SessionDataStore`.
The `SessionDataMap` is preferentially consulted before the actual SessionDataStore on reads.
This can improve the performance of slow stores.
Jetty provides one implementation of the this L2 cache based on `Memcached`, the `MemcachedSessionDataMap`.
-
-==== Use Cases
-
-===== Clustering with a Sticky Load Balancer
-
-Preferably, your cluster will utilize a sticky load balancer.
-This will route requests for the same session to the same Jetty instance.
-In this case, the `DefaultSessionCache` can be used to keep in-use Session objects in memory.
-You can fine-tune the cache by controlling how long Session objects remain in memory with the eviction policy settings.
-
-If you have a large number of Sessions or very large Session objects, then you might want to manage your memory allocation by controlling the amount of time Session objects spend in the cache.
-The `EVICT_ON_SESSION_EXIT` eviction policy will remove a Session object from the cache as soon as the last simultaneous request referencing it exits.
-Alternatively, the `EVICT_ON_INACTIVITY` policy will remove a Session object from the cache after a configurable amount of time has passed without a request referencing it.
-
-If your Sessions are very long lived and infrequently referenced, you might use the `EVICT_ON_INACTIVITY_POLICY` to control the size of the cache.
-
-If your Sessions are small, or relatively few or stable in number or they are read-mostly, then you might select the `NEVER_EVICT` policy.
-With this policy, Session objects will remain in the cache until they either expire or are explicitly invalidated.
-
-If you have a high likelihood of simultaneous requests for the same session object, then the `EVICT_ON_SESSION_EXIT` policy will ensure the Session object stays in the cache as long as it is needed.
-
-
-===== Clustering without a Sticky Load Balancer
-
-Without a sticky load balancer requests for the same session may arrive on any node in the cluster.
-This means it is likely that the copy of the Session object in any `SessionCache` is likely to be out-of-date, as the Session was probably last accessed on a different node.
-In this case, your `choices` are to use either the `NullSessionCache` or to de-tuned the `DefaultSessionCache`.
-If you use the NullSessionCache all Session object caching is avoided.
-This means that every time a request references a session it must be brought in from persistent storage.
-It also means that there can be no sharing of Session objects for multiple requests for the same session: each will have their own Session object.
-Furthermore, the outcome of session writes are indeterminate because the Servlet Specification does not mandate ACID transactions for sessions.
-
-If you use the `DefaultSessionCache`, there is a risk that the caches on some nodes will contain out-of-date session information as simultaneous requests for the same session are scattered over the cluster.
-To mitigate this somewhat you can use the `EVICT_ON_SESSION_EXIT` eviction policy: this will ensure that the Session is removed from the cache as soon as the last simultaneous request for it exits.
-Again, due to the lack of session transactionality, the ordering outcome of write operations cannot be guaranteed.
-As the Session is cached while at least one request is accessing it, it is possible for multiple simultaneous requests to share the same Session object.
-
-
-===== Handling corrupted or unloadable session data
-
-For various reasons it might not be possible for the SessionDataStore to re-read a stored session.
-One scenario is that the session stores a serialized object in it's attributes, and after a redeployment there in an incompatible class change.
-Using the setter `SessionCache.setRemoveUnloadableSessions(true)` will allow the `SessionDataStore` to delete the unreadable session from persistent storage.
-This can be useful from preventing the scavenger from continually generating errors on the same expired, but un-restorable, session.
+See link:#session-configuration-memcachedsessiondatastore[the L2 SessionData Cache]for additional information.
diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/sessions-usecases.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/sessions-usecases.adoc
new file mode 100644
index 00000000000..4556b72d15d
--- /dev/null
+++ b/jetty-documentation/src/main/asciidoc/administration/sessions/sessions-usecases.adoc
@@ -0,0 +1,60 @@
+// ========================================================================
+// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
+// ========================================================================
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+//
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+//
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+//
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+[[sessions-usecases]]
+=== Use Cases
+
+===== Clustering with a Sticky Load Balancer
+
+Preferably, your cluster will utilize a sticky load balancer.
+This will route requests for the same Session to the same Jetty instance.
+In this case, the `DefaultSessionCache` can be used to keep in-use Session objects in memory.
+You can fine-tune the cache by controlling how long Session objects remain in memory with the eviction policy settings.
+
+If you have a large number of Sessions or very large Session objects, then you may want to manage your memory allocation by controlling the amount of time Session objects spend in the cache.
+The `EVICT_ON_SESSION_EXIT` eviction policy will remove a Session object from the cache as soon as the last simultaneous request referencing it exits.
+Alternatively, the `EVICT_ON_INACTIVITY` policy will remove a Session object from the cache after a configurable amount of time has passed without a request referencing it.
+
+If your Sessions are very long lived and infrequently referenced, you might use the `EVICT_ON_INACTIVITY_POLICY` to control the size of the cache.
+
+If your Sessions are small, or relatively few or stable in number or they are read-mostly, then you might select the `NEVER_EVICT` policy.
+With this policy, Session objects will remain in the cache until they either expire or are explicitly invalidated.
+
+If you have a high likelihood of simultaneous requests for the same session object, then the `EVICT_ON_SESSION_EXIT` policy will ensure the Session object stays in the cache as long as it is needed.
+
+
+===== Clustering Without a Sticky Load Balancer
+
+Without a sticky load balancer requests for the same session may arrive on any node in the cluster.
+This means it is likely that the copy of the Session object in any `SessionCache` is likely to be out-of-date, as the Session was probably last accessed on a different node.
+In this case, your `choices` are to use either the `NullSessionCache` or to de-tune the `DefaultSessionCache`.
+If you use the NullSessionCache all Session object caching is avoided.
+This means that every time a request references a session it must be brought in from persistent storage.
+It also means that there can be no sharing of Session objects for multiple requests for the same session: each will have their own Session object.
+Furthermore, the outcome of session writes are indeterminate because the Servlet Specification does not mandate ACID transactions for sessions.
+
+If you use the `DefaultSessionCache`, there is a risk that the caches on some nodes will contain out-of-date Session information as simultaneous requests for the same session are scattered over the cluster.
+To mitigate this somewhat you can use the `EVICT_ON_SESSION_EXIT` eviction policy: this will ensure that the Session is removed from the cache as soon as the last simultaneous request for it exits.
+Again, due to the lack of Session transactionality, the ordering outcome of write operations cannot be guaranteed.
+As the Session is cached while at least one request is accessing it, it is possible for multiple simultaneous requests to share the same Session object.
+
+
+===== Handling corrupted or unloadable session data
+
+For various reasons it might not be possible for the `SessionDataStore` to re-read a stored session.
+One scenario is that the session stores a serialized object in it's attributes, and after a redeployment there in an incompatible class change.
+Using the setter `SessionCache.setRemoveUnloadableSessions(true)` will allow the `SessionDataStore` to delete the unreadable session from persistent storage.
+This can be useful from preventing the scavenger from continually generating errors on the same expired, but un-restorable, session.
diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc
index d236b24db46..b1d726d36a4 100644
--- a/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/startup/screen-empty-base-listconfig.adoc
@@ -16,7 +16,7 @@
[source, screen, subs="{sub-order}"]
....
-[mybase]$ java -jar /opt/jetty-distribution/start.jar --list-config
+[mybase]$ java -jar $JETTY_HOME/start.jar --list-config
Java Environment:
-----------------
@@ -28,7 +28,7 @@ Java Environment:
java.runtime.name = Java(TM) SE Runtime Environment
java.runtime.version = 1.8.0_92-b14
java.io.tmpdir = /var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/
- user.dir = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
+ user.dir = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
user.language = en
user.country = US
@@ -36,14 +36,14 @@ Jetty Environment:
-----------------
jetty.version = {VERSION}
jetty.tag.version = master
- jetty.home = /Users/staff/installs/repository/jetty-distribution-9.4.0
- jetty.base = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
+ jetty.home = /Users/staff/installs/repository/jetty-distribution-{VERSION}
+ jetty.base = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
Config Search Order:
--------------------
- ${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
- ${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-9.4.0
+ ${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
+ ${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-{VERSION}
JVM Arguments:
diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc
index 42852f088e6..fcd6b25d1a3 100644
--- a/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy-listconfig.adoc
@@ -16,7 +16,7 @@
[source, screen, subs="{sub-order}"]
....
-[mybase]$ java -jar ../start.jar --list-config
+[mybase]$ java -jar $JETTY_HOME/start.jar --list-config
Java Environment:
-----------------
@@ -28,7 +28,7 @@ Java Environment:
java.runtime.name = Java(TM) SE Runtime Environment
java.runtime.version = 1.8.0_92-b14
java.io.tmpdir = /var/folders/h6/yb_lbnnn11g0y1jjlvqg631h0000gn/T/
- user.dir = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
+ user.dir = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
user.language = en
user.country = US
@@ -36,14 +36,14 @@ Jetty Environment:
-----------------
jetty.version = {VERSION}
jetty.tag.version = master
- jetty.home = /Users/staff/installs/repository/jetty-distribution-9.4.0
- jetty.base = /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
+ jetty.home = /Users/staff/installs/repository/jetty-distribution-{VERSION}
+ jetty.base = /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
Config Search Order:
--------------------
- ${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-9.4.0/mybase
- ${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-9.4.0
+ ${jetty.base} -> /Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase
+ ${jetty.home} -> /Users/staff/installs/repository/jetty-distribution-{VERSION}
JVM Arguments:
@@ -81,7 +81,8 @@ Note: order presented here is how they would appear on the classpath.
Jetty Active XMLs:
------------------
- ${jetty.home}/etc/jetty.xml
- ${jetty.home}/etc/jetty-deploy.xml
- ${jetty.home}/etc/jetty-http.xml
+${jetty.home}/etc/jetty.xml
+${jetty.home}/etc/jetty-webapp.xml
+${jetty.home}/etc/jetty-deploy.xml
+${jetty.home}/etc/jetty-http.xml
....
diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy.adoc
index 4fab86e5e05..cabdb76adb8 100644
--- a/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/startup/screen-http-webapp-deploy.adoc
@@ -16,11 +16,13 @@
[source, screen, subs="{sub-order}"]
....
-[mybase]$ java -jar ../start.jar --add-to-start=http,webapp,deploy
-INFO : webapp initialised in ${jetty.base}/start.d/webapp.ini
-INFO : server initialised (transitively) in ${jetty.base}/start.d/server.ini
-INFO : http initialised in ${jetty.base}/start.d/http.ini
-INFO : deploy initialised in ${jetty.base}/start.d/deploy.ini
-MKDIR: ${jetty.base}/webapps
-INFO : Base directory was modified
+[mybase]$ java -jar $JETTY_HOME/start.jar --add-to-start=http,webapp,deploy
+INFO : webapp initialized in ${jetty.base}/start.ini
+INFO : server transitively enabled, ini template available with --add-to-start=server
+INFO : security transitively enabled
+INFO : servlet transitively enabled
+INFO : http initialized in ${jetty.base}/start.ini
+INFO : deploy initialized in ${jetty.base}/start.ini
+MKDIR : ${jetty.base}/webapps
+INFO : Base directory was modified
....
diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/screen-list-logging-modules.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/screen-list-logging-modules.adoc
index 6f4e9181826..f88ac6c408a 100644
--- a/jetty-documentation/src/main/asciidoc/administration/startup/screen-list-logging-modules.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/startup/screen-list-logging-modules.adoc
@@ -16,7 +16,7 @@
[source, screen, subs="{sub-order}"]
....
-[mybase]$ java -jar ../start.jar --list-modules=logging,-internal
+[mybase]$ java -jar $JETTY_HOME/start.jar --list-modules=logging,-internal
Available Modules:
==================
diff --git a/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc b/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc
index 6e308896d0d..874bbf65b80 100644
--- a/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc
+++ b/jetty-documentation/src/main/asciidoc/administration/startup/startup-modules.adoc
@@ -18,7 +18,8 @@
=== Managing Startup Modules
The standard Jetty Distribution ships with several modules defined in `${jetty.home}/modules/`.
-These modules allow flexibility for implementations and make configuration a much more plug-and-play set up.
+Modules interact with Jetty XML files to configure options and parameters for the server and are the primary configuration method for Jetty distributions.
+Modules allow flexibility for implementations and their plug-and-play nature makes adding or removing server functionality virtually painless.
[[enabling-modules]]
==== Enabling Modules
@@ -28,27 +29,27 @@ The default distribution has a co-mingled `${jetty.home}` and `${jetty.base}` wh
It is highly encouraged that you learn about the differences in link:#startup-base-and-home[Jetty Base vs Jetty Home] and take full advantage of this setup.
____
-Jetty ships with many modules defined in `${jetty.home}/modules`.
Enabling a module is a simple process: simply add the `--add-to-start` syntax on the command line.
Doing this will enable the module and any dependent modules.
-An example of this, with a new, empty, base directory.
-We can see from this output, that the directory is new.
+An example of this with a new, empty, base directory:
+
+If we try to start the Jetty server with no configuration or modules enabled, it will promptly exit:
include::screen-empty-base.adoc[]
-Lets see what the configuration looks like so far:
+By using the `--list-config` parameter to our startup command, we can see that there are no modules enabled and no Jetty XML files are active:
include::screen-empty-base-listconfig.adoc[]
-Lets try adding some basic support for webapps, with automatic deploy (hot deploy), and a single basic HTTP/1.1 connector.
+Let's try adding some basic support for webapps, with automatic deploy (hot deploy), and a single basic HTTP/1.1 connector.
include::screen-http-webapp-deploy.adoc[]
-This created the webapps directory in our `mybase` directory and appended the `start.ini` file with the ini template arguments from the associated module files.
-Additionally, where needed, Jetty enabled any module dependencies and added their module ini template properties.
+This creates the webapps directory in our `mybase` directory and appended the `start.ini` file with the ini template arguments from the associated module files.
+Additionally, where needed, Jetty enabled any module dependencies.
-Lets see what it looks like configuration wise.
+Now that we have added some modules to our server, let's run `--list-config` again to review our new configuration.
include::screen-http-webapp-deploy-listconfig.adoc[]
diff --git a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc
index 5f9719ae1f7..b4b114da1ff 100644
--- a/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc
+++ b/jetty-documentation/src/main/asciidoc/configuring/connectors/configuring-connectors.adoc
@@ -24,13 +24,274 @@ Configuring a connector is a combination of configuring the following:
* Services the connector uses (for example: executors, schedulers).
* Connection factories that instantiate and configure the protocol for an accepted connection.
-Jetty primarily uses a single connector type called link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[ServerConnector].
+Typically connectors require very little configuration aside from setting the listening port, and enabling `X-Forwarded-For` customization when applicable.
+Additional settings, including construction your own constructor Jetty XML files, are for expert configuration only.
+
+==== Enabling Connectors
+
+Out of the box, Jetty provides several link:#startup-modules[modules] for enabling different types of connectors, from HTTP to HTTPS, HTTP/2, and others.
+If you startup Jetty with the `--list-modules=connector` command, you can see a list of all available connector modules:
+
+[source, screen, subs="{sub-order}"]
+....
+[mybase]$ java -jar $JETTY_HOME/start.jar --list-modules=connector
+
+Available Modules:
+==================
+tags: [connector]
+
+Modules for tag 'connector':
+----------------------------
+
+ Module: http
+ : Enables a HTTP connector on the server.
+ : By default HTTP/1 is support, but HTTP2C can
+ : be added to the connector with the http2c module.
+ Tags: connector, http
+ Depend: server
+ XML: etc/jetty-http.xml
+ Enabled: ${jetty.base}/start.ini
+
+ Module: http-forwarded
+ : Adds a forwarded request customizer to the HTTP Connector
+ : to process forwarded-for style headers from a proxy.
+ Tags: connector
+ Depend: http
+ XML: etc/jetty-http-forwarded.xml
+
+ Module: http2
+ : Enables HTTP2 protocol support on the TLS(SSL) Connector,
+ : using the ALPN extension to select which protocol to use.
+ Tags: connector, http2, http, ssl
+ Depend: ssl, alpn
+ LIB: lib/http2/*.jar
+ XML: etc/jetty-http2.xml
+
+ Module: http2c
+ : Enables the HTTP2C protocol on the HTTP Connector
+ : The connector will accept both HTTP/1 and HTTP/2 connections.
+ Tags: connector, http2, http
+ Depend: http
+ LIB: lib/http2/*.jar
+ XML: etc/jetty-http2c.xml
+
+ Module: https
+ : Adds HTTPS protocol support to the TLS(SSL) Connector
+ Tags: connector, https, http, ssl
+ Depend: ssl
+ Optional: http-forwarded, http2
+ XML: etc/jetty-https.xml
+
+ Module: proxy-protocol-ssl
+ : Enables the Proxy Protocol on the TLS(SSL) Connector.
+ : http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
+ : This allows a Proxy operating in TCP mode to transport
+ : details of the proxied connection to the server.
+ : Both V1 and V2 versions of the protocol are supported.
+ Tags: connector, ssl
+ Depend: ssl
+ XML: etc/jetty-proxy-protocol-ssl.xml
+
+ Module: ssl
+ : Enables a TLS(SSL) Connector on the server.
+ : This may be used for HTTPS and/or HTTP2 by enabling
+ : the associated support modules.
+ Tags: connector, ssl
+ Depend: server
+ XML: etc/jetty-ssl.xml
+ XML: etc/jetty-ssl-context.xml
+
+ Module: unixsocket
+ : Enables a Unix Domain Socket Connector that can receive
+ : requests from a local proxy and/or SSL offloader (eg haproxy) in either
+ : HTTP or TCP mode. Unix Domain Sockets are more efficient than
+ : localhost TCP/IP connections as they reduce data copies, avoid
+ : needless fragmentation and have better dispatch behaviours.
+ : When enabled with corresponding support modules, the connector can
+ : accept HTTP, HTTPS or HTTP2C traffic.
+ Tags: connector
+ Depend: server
+ LIB: lib/jetty-unixsocket-${jetty.version}.jar
+ LIB: lib/jnr/*.jar
+ XML: etc/jetty-unixsocket.xml
+
+ Module: unixsocket-forwarded
+ : Adds a forwarded request customizer to the HTTP configuration used
+ : by the Unix Domain Socket connector, for use when behind a proxy operating
+ : in HTTP mode that adds forwarded-for style HTTP headers. Typically this
+ : is an alternate to the Proxy Protocol used mostly for TCP mode.
+ Tags: connector
+ Depend: unixsocket-http
+ XML: etc/jetty-unixsocket-forwarded.xml
+
+ Module: unixsocket-http
+ : Adds a HTTP protocol support to the Unix Domain Socket connector.
+ : It should be used when a proxy is forwarding either HTTP or decrypted
+ : HTTPS traffic to the connector and may be used with the
+ : unix-socket-http2c modules to upgrade to HTTP/2.
+ Tags: connector, http
+ Depend: unixsocket
+ XML: etc/jetty-unixsocket-http.xml
+
+ Module: unixsocket-http2c
+ : Adds a HTTP2C connetion factory to the Unix Domain Socket Connector
+ : It can be used when either the proxy forwards direct
+ : HTTP/2C (unecrypted) or decrypted HTTP/2 traffic.
+ Tags: connector, http2
+ Depend: unixsocket-http
+ LIB: lib/http2/*.jar
+ XML: etc/jetty-unixsocket-http2c.xml
+
+ Module: unixsocket-proxy-protocol
+ : Enables the proxy protocol on the Unix Domain Socket Connector
+ : http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt
+ : This allows information about the proxied connection to be
+ : efficiently forwarded as the connection is accepted.
+ : Both V1 and V2 versions of the protocol are supported and any
+ : SSL properties may be interpreted by the unixsocket-secure
+ : module to indicate secure HTTPS traffic. Typically this
+ : is an alternate to the forwarded module.
+ Tags: connector
+ Depend: unixsocket
+ XML: etc/jetty-unixsocket-proxy-protocol.xml
+
+ Module: unixsocket-secure
+ : Enable a secure request customizer on the HTTP Configuration
+ : used by the Unix Domain Socket Connector.
+ : This looks for a secure scheme transported either by the
+ : unixsocket-forwarded, unixsocket-proxy-protocol or in a
+ : HTTP2 request.
+ Tags: connector
+ Depend: unixsocket-http
+ XML: etc/jetty-unixsocket-secure.xml
+...
+....
+
+To enable a connector, simply activate the associated module.
+Below is an example of activating both the `http` and `https` modules in a fresh link:#startup-base-and-home[Jetty base] using the link:#start-vs-startd[start.d directory]:
+
+[source, screen, subs="{sub-order}"]
+....
+[mybase] java -jar $JETTY_HOME/start.jar --create-startd
+MKDIR : ${jetty.base}/start.d
+INFO : Base directory was modified
+
+[mybase] java -jar $JETTY_HOME/start.jar --add-to-start=http,https
+INFO : server transitively enabled, ini template available with --add-to-start=server
+INFO : http initialized in ${jetty.base}/start.d/http.ini
+INFO : https initialized in ${jetty.base}/start.d/https.ini
+INFO : ssl transitively enabled, ini template available with --add-to-start=ssl
+MKDIR : ${jetty.base}/etc
+COPY : ${jetty.home}/modules/ssl/keystore to ${jetty.base}/etc/keystore
+INFO : Base directory was modified
+[mybase] tree
+.
+├── etc
+│  └── keystore
+└── start.d
+ ├── http.ini
+ └── https.ini
+....
+
+When the `http` and `https` modules were activated, so too were any modules they were dependent on, in this case `server` and `ssl`, as well as any dependencies for those modules, such as the `etc` and `ketystore` directories for `ssl`.
+
+At this point the server has been configured with connectors for both HTTP and HTTPS and can be started:
+
+[source, screen, subs="{sub-order}"]
+....
+[mybase] java -jar $JETTY_HOME/start.jar
+2017-08-31 10:19:58.855:INFO::main: Logging initialized @372ms to org.eclipse.jetty.util.log.StdErrLog
+2017-08-31 10:19:59.076:INFO:oejs.Server:main: jetty-9.4.6.v20170531
+2017-08-31 10:19:59.125:INFO:oejs.AbstractConnector:main: Started ServerConnector@421e98e0{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
+2017-08-31 10:19:59.150:INFO:oejus.SslContextFactory:main: x509=X509@5315b42e(jetty,h=[jetty.eclipse.org],w=[]) for SslContextFactory@2ef9b8bc(file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore,file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore)
+2017-08-31 10:19:59.151:INFO:oejus.SslContextFactory:main: x509=X509@5d624da6(mykey,h=[],w=[]) for SslContextFactory@2ef9b8bc(file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore,file:///Users/staff/installs/repository/jetty-distribution-{VERSION}/mybase/etc/keystore)
+2017-08-31 10:19:59.273:INFO:oejs.AbstractConnector:main: Started ServerConnector@2b98378d{SSL,[ssl, http/1.1]}{0.0.0.0:8443}
+2017-08-31 10:19:59.274:INFO:oejs.Server:main: Started @791ms
+....
+
+When modules are enabled, they are loaded with several default options.
+These can be changed by editing the associated module ini file in the `start.d` directory (or the associated lines in `server.ini` if your implementation does not use `start.d`).
+For example, if we examine the `http.ini` file in our `start.d` directory created above, we will see the following settings:
+
+[source, screen, subs="{sub-order}"]
+....
+# ---------------------------------------
+# Module: http
+# Enables a HTTP connector on the server.
+# By default HTTP/1 is support, but HTTP2C can
+# be added to the connector with the http2c module.
+# ---------------------------------------
+--module=http
+
+### HTTP Connector Configuration
+
+## Connector host/address to bind to
+# jetty.http.host=0.0.0.0
+
+## Connector port to listen on
+# jetty.http.port=8080
+
+## Connector idle timeout in milliseconds
+# jetty.http.idleTimeout=30000
+
+## Connector socket linger time in seconds (-1 to disable)
+# jetty.http.soLingerTime=-1
+
+## Number of acceptors (-1 picks default based on number of cores)
+# jetty.http.acceptors=-1
+
+## Number of selectors (-1 picks default based on number of cores)
+# jetty.http.selectors=-1
+
+## ServerSocketChannel backlog (0 picks platform default)
+# jetty.http.acceptorQueueSize=0
+
+## Thread priority delta to give to acceptor threads
+# jetty.http.acceptorPriorityDelta=0
+
+## HTTP Compliance: RFC7230, RFC2616, LEGACY
+# jetty.http.compliance=RFC7230
+....
+
+To make a change to these settings, uncomment the line (by removing the #) and change the property to the desired value.
+For example, if you wanted to change the HTTP port to 5231, you would edit the line as follows:
+
+[source, screen, subs="{sub-order}"]
+....
+...
+## Connector port to listen on
+jetty.http.port=5231
+...
+....
+
+Now when the server is started, HTTP connections will enter on port 5231:
+
+[source, screen, subs="{sub-order}"]
+....
+[mybase] java -jar ../start.jar
+2017-08-31 10:31:32.955:INFO::main: Logging initialized @366ms to org.eclipse.jetty.util.log.StdErrLog
+2017-08-31 10:31:33.109:INFO:oejs.Server:main: jetty-9.4.6.v20170531
+2017-08-31 10:31:33.146:INFO:oejs.AbstractConnector:main: Started ServerConnector@2ef9b8bc{HTTP/1.1,[http/1.1]}{0.0.0.0:5231}
+...
+2017-08-31 10:31:33.263:INFO:oejs.Server:main: Started @675ms
+....
+
+Every module has their own set of configuration options, and reviewing them all is recommended.
+For additional information on the module system, please refer to our documentation on link:#startup-modules[Startup Modules].
____
[NOTE]
+Editing these module files is the recommended way to edit the configuration of your server.
+Making changes to the associated Jetty XML file for connectors is *not* recommended, and is for advanced users only.
+If you do wish to edit Jetty XML, please see our section on managing link:#[Jetty Home and Jetty Base] to ensure your Jetty Home remains a standard of truth for your implementation.
+____
+
+==== Advanced Configuration
+
+Jetty primarily uses a single connector type called link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[ServerConnector].
+
Prior to Jetty 9, the type of the connector specified both the protocol and the implementation used; for example, selector-based non blocking I/O vs blocking I/O, or SSL connector vs non-SSL connector.
Jetty 9 has a single selector-based non-blocking I/O connector, and a collection of link:{JDURL}/org/eclipse/jetty/server/ConnectionFactory.html[`ConnectionFactories`] now configure the protocol on the connector.
-____
The standard Jetty distribution comes with the following Jetty XML files that create and configure connectors; you should examine them as you read this section:
@@ -48,15 +309,6 @@ link:{GITBROWSEURL}/jetty-http2/http2-server/src/main/config/etc/jetty-http2.xml
link:{GITBROWSEURL}/jetty-alpn/jetty-alpn-server/src/main/config/etc/jetty-alpn.xml[`jetty-alpn.xml`]::
Adds an link:{JDURL}/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.html[`ALPNServerConnectionFactory`] to the link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] configured by `jetty-ssl.xml` which allows the one SSL connector to support multiple protocols with the ALPN extension used to select the protocol to be used for each connection.
-Typically connectors require very little configuration aside from setting the listening port (see link:#jetty-connectors-network-settings[Network Settings]), and enabling `X-Forwarded-For` customization when applicable. (see link:#jetty-connectors-http-configuration[HTTP Configuration]).
-Additional settings are for expert configuration only.
-
-____
-[NOTE]
-All the connectors discussed in this chapter can be enabled in the Jetty Distribution by enabling them via the module system.
-Please refer to our chapter on link:#startup-modules[Managing Startup Modules] for more information.
-____
-
==== Constructing a ServerConnector
The services a link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] instance uses are set by constructor injection and once instantiated cannot be changed.
@@ -79,9 +331,9 @@ You can see the other arguments that can be passed when constructing a `ServerCo
Typically the defaults are sufficient for almost all deployments.
[[jetty-connectors-network-settings]]
-==== Network Settings.
+==== Network Settings
-You configure connector network settings by calling setters on the connector before it is started.
+You can configure connector network settings by calling setters on the connector before it is started.
For example, you can set the port with the Jetty XML:
[source, xml, subs="{sub-order}"]
@@ -107,7 +359,7 @@ Thus typically the port is set within Jetty XML, but uses the `Property` element
----
-The network settings that you can set on the link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] include:
+The network settings available for configuration on the link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] include:
.Connector Configuration
[width="100%",cols="22%,78%",options="header",]
@@ -238,13 +490,13 @@ These headers can be interpreted by an instance of link:{JDURL}/org/eclipse/jett
===== Proxy Protocol
-The http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt[Proxy Protocol] is a de facto standard created by HAProxy and used by environments such as Amazon Elastic Cloud.
+The http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt[Proxy Protocol] is the _de facto_ standard created by HAProxy and used by environments such as Amazon Elastic Cloud.
This mechanism is independent of any protocol, so it can be used for HTTP2, TLS etc.
The information about the client connection is sent as a small data frame on each newly established connection.
In Jetty, this protocol can be handled by the link:{JDURL}/org/eclipse/jetty/server/ProxyConnectionFactory.html[`ProxyConnectionFactory`] which parses the data frame and then instantiates the next `ConnectionFactory` on the connection with an end point that has been customized with the data obtained about the original client connection.
The connection factory can be added to any link:{JDURL}/org/eclipse/jetty/server/ServerConnector.html[`ServerConnector`] and should be the first link:{JDURL}/org/eclipse/jetty/server/ConnectionFactory.html[`ConnectionFactory`].
-An example of adding the factory to a HTTP connector is:
+An example of adding the factory to a HTTP connector is shown below:
[source, xml, subs="{sub-order}"]
----
diff --git a/jetty-documentation/src/main/asciidoc/configuring/security/serving-aliased-files.adoc b/jetty-documentation/src/main/asciidoc/configuring/security/serving-aliased-files.adoc
index 35030473996..3fb6e507d7c 100644
--- a/jetty-documentation/src/main/asciidoc/configuring/security/serving-aliased-files.adoc
+++ b/jetty-documentation/src/main/asciidoc/configuring/security/serving-aliased-files.adoc
@@ -60,8 +60,8 @@ Unfortunately this approach denies all aliases, including symbolic links, which
==== Serving Aliases and Symbolic Links
Not all aliases are bad nor should be seen as attempts to subvert security constraints.
-Specifically symbolic links can be very useful when assembling complex web applications, yet by default Jetty will not serve them.
-Thus Jetty contexts support an extensible `AliasCheck` mechanism to allow aliases resources to be inspected an conditionally served.
+Specifically, symbolic links can be very useful when assembling complex web applications.
+As such, Jetty contexts support an extensible `AliasCheck` mechanism to allow aliases resources to be inspected and conditionally served.
In this way, "good" aliases can be detected and served.
Jetty provides several utility implementations of the `AliasCheck` interface as nested classes with `ContextHandler`:
@@ -70,6 +70,11 @@ ApproveAliases::
AllowSymLinkAliasChecker::
Approve Aliases using the java-7 `Files.readSymbolicLink(path)` and `Path.toRealPath(...)` APIs to check that aliases are valid symbolic links.
+____
+[NOTE]
+By default, Jetty serves aliased files for implementations running on UNIX as Contexts are created with both the {JDURL}/org/eclipse/jetty/server/handler/AllowSymLinkAliasChecker.html[`AllowSymLinkAliasChecker`] and {JDURL}/org/eclipse/jetty/server/handler/ContextHandler.ApproveNonExistentDirectoryAliases.html[`ApproveNonExistentDirectoryAliases`] alias checkers.
+____
+
An application is free to implement its own Alias checking.
Alias Checkers can be installed in a context via the following XML used in a context deployer file or `WEB-INF/jetty-web.xml`:
diff --git a/jetty-documentation/src/main/asciidoc/reference/architecture/jetty-classloading.adoc b/jetty-documentation/src/main/asciidoc/reference/architecture/jetty-classloading.adoc
index 5fcec472e60..8e66e7cc8a0 100644
--- a/jetty-documentation/src/main/asciidoc/reference/architecture/jetty-classloading.adoc
+++ b/jetty-documentation/src/main/asciidoc/reference/architecture/jetty-classloading.adoc
@@ -86,7 +86,7 @@ The default system classes are:
.Default System Classes
[width="100%",cols="8%,92%",options="header",]
|=======================================================================
-|System Classes
+|System Classes | Note
|java. |Java SE classes (per servlet spec v2.5 / SRV.9.7.2).
|javax. |Java SE classes (per servlet spec v2.5 / SRV.9.7.2).
|org.xml. |Needed by javax.xml.
@@ -98,7 +98,7 @@ The default system classes are:
|org.eclipse.jetty.servlet.DefaultServlet |Webapp can see and not change default servlet.
|=======================================================================
-Absolute classname can be passed, names ending with . are treated as packages names, and names starting with - are treated as negative matches and must be listed before any enclosing packages.
+Absolute classname can be passed, names ending with `.` are treated as packages names, and names starting with `-` are treated as negative matches and must be listed before any enclosing packages.
[[setting-server-classes]]
===== Setting Server Classes
diff --git a/jetty-documentation/src/main/docbkx-stylesheet/html/docbook.xsl b/jetty-documentation/src/main/docbkx-stylesheet/html/docbook.xsl
index eeadaa81667..44ebe4d4a1c 100644
--- a/jetty-documentation/src/main/docbkx-stylesheet/html/docbook.xsl
+++ b/jetty-documentation/src/main/docbkx-stylesheet/html/docbook.xsl
@@ -129,13 +129,13 @@ xmlns:date="http://exslt.org/dates-and-times"
- |