Merge branch 'jetty-10.0.x' into jetty-10.0.x-5264-demo-modules
This commit is contained in:
commit
eedcac314b
|
@ -39,12 +39,13 @@ pipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage( "Build / Test - JDK14" ) {
|
|
||||||
|
stage("Build / Test - JDK15") {
|
||||||
agent { node { label 'linux' } }
|
agent { node { label 'linux' } }
|
||||||
steps {
|
steps {
|
||||||
container( 'jetty-build' ) {
|
container( 'jetty-build' ) {
|
||||||
timeout( time: 120, unit: 'MINUTES' ) {
|
timeout( time: 120, unit: 'MINUTES' ) {
|
||||||
mavenBuild( "jdk14", "-T3 clean install", "maven3", true )
|
mavenBuild( "jdk15", "-T3 clean install", "maven3", true )
|
||||||
warnings consoleParsers: [[parserName: 'Maven'], [parserName: 'Java']]
|
warnings consoleParsers: [[parserName: 'Maven'], [parserName: 'Java']]
|
||||||
junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml'
|
junit testResults: '**/target/surefire-reports/*.xml,**/target/invoker-reports/TEST*.xml'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd">
|
|
||||||
|
|
||||||
<Configure id="OtherServer" class="org.eclipse.jetty.server.Server">
|
|
||||||
<Set name="handler">
|
|
||||||
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerList">
|
|
||||||
<Set name="handlers">
|
|
||||||
<Array type="org.eclipse.jetty.server.Handler">
|
|
||||||
<Item>
|
|
||||||
<New id="OtherContexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
|
|
||||||
</Item>
|
|
||||||
<Item>
|
|
||||||
<New class="org.eclipse.jetty.server.handler.DefaultHandler"/>
|
|
||||||
</Item>
|
|
||||||
</Array>
|
|
||||||
</Set>
|
|
||||||
</New>
|
|
||||||
</Set>
|
|
||||||
|
|
||||||
<Call name="addConnector">
|
|
||||||
<Arg>
|
|
||||||
<New class="org.eclipse.jetty.server.ServerConnector">
|
|
||||||
<Arg name="server"><Ref refid="OtherServer" /></Arg>
|
|
||||||
<Set name="port">8888</Set>
|
|
||||||
</New>
|
|
||||||
</Arg>
|
|
||||||
</Call>
|
|
||||||
|
|
||||||
<Call name="addBean">
|
|
||||||
<Arg>
|
|
||||||
<New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
|
|
||||||
<Set name="contexts">
|
|
||||||
<Ref refid="OtherContexts" />
|
|
||||||
</Set>
|
|
||||||
|
|
||||||
<Call id="webappprovider" name="addAppProvider">
|
|
||||||
<Arg>
|
|
||||||
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
|
|
||||||
<Set name="monitoredDirName"><Property name="jetty.base" default="." />/other-webapps</Set>
|
|
||||||
<Set name="defaultsDescriptor"><Property name="jetty.home" default="." />/etc/webdefault.xml</Set>
|
|
||||||
<Set name="extractWars">true</Set>
|
|
||||||
<Set name="configurationManager">
|
|
||||||
<New class="org.eclipse.jetty.deploy.PropertiesConfigurationManager"/>
|
|
||||||
</Set>
|
|
||||||
</New>
|
|
||||||
</Arg>
|
|
||||||
</Call>
|
|
||||||
</New>
|
|
||||||
</Arg>
|
|
||||||
</Call>
|
|
||||||
</Configure>
|
|
|
@ -49,14 +49,12 @@
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ant</groupId>
|
<groupId>org.apache.ant</groupId>
|
||||||
<artifactId>ant</artifactId>
|
<artifactId>ant</artifactId>
|
||||||
<version>1.6.5</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>ant</groupId>
|
<groupId>org.apache.ant</groupId>
|
||||||
<artifactId>ant-launcher</artifactId>
|
<artifactId>ant-launcher</artifactId>
|
||||||
<version>1.6.5</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
|
|
@ -1126,18 +1126,12 @@ public class HttpClient extends ContainerLifeCycle
|
||||||
{
|
{
|
||||||
if (port > 0)
|
if (port > 0)
|
||||||
return port;
|
return port;
|
||||||
else if (isSchemeSecure(scheme))
|
return HttpScheme.getDefaultPort(scheme);
|
||||||
return 443;
|
|
||||||
else
|
|
||||||
return 80;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDefaultPort(String scheme, int port)
|
public boolean isDefaultPort(String scheme, int port)
|
||||||
{
|
{
|
||||||
if (isSchemeSecure(scheme))
|
return HttpScheme.getDefaultPort(scheme) == port;
|
||||||
return port == 443;
|
|
||||||
else
|
|
||||||
return port == 80;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSchemeSecure(String scheme)
|
public static boolean isSchemeSecure(String scheme)
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
# DO NOT EDIT - See: https://www.eclipse.org/jetty/documentation/current/startup-modules.html
|
|
||||||
|
|
||||||
[description]
|
[description]
|
||||||
Enables webapplication deployment from the webapps directory.
|
Enables web application deployment from the $JETTY_BASE/webapps/ directory.
|
||||||
|
|
||||||
[depend]
|
[depend]
|
||||||
webapp
|
webapp
|
||||||
|
|
|
@ -101,9 +101,7 @@
|
||||||
<!-- handler by context path and virtual host, and the -->
|
<!-- handler by context path and virtual host, and the -->
|
||||||
<!-- DefaultHandler, which handles any requests not handled by -->
|
<!-- DefaultHandler, which handles any requests not handled by -->
|
||||||
<!-- the context handlers. -->
|
<!-- the context handlers. -->
|
||||||
<!-- Other handlers may be added to the "Handlers" collection, -->
|
<!-- Other handlers may be added to the "Handlers" collection. -->
|
||||||
<!-- for example the jetty-requestlog.xml file adds the -->
|
|
||||||
<!-- RequestLogHandler after the default handler -->
|
|
||||||
<!-- =========================================================== -->
|
<!-- =========================================================== -->
|
||||||
<Set name="handler">
|
<Set name="handler">
|
||||||
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerList">
|
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerList">
|
||||||
|
|
|
@ -311,7 +311,7 @@
|
||||||
<argument>jetty.home=${home-directory}</argument>
|
<argument>jetty.home=${home-directory}</argument>
|
||||||
<argument>jetty.base=${base-directory}</argument>
|
<argument>jetty.base=${base-directory}</argument>
|
||||||
<argument>--create-startd</argument>
|
<argument>--create-startd</argument>
|
||||||
<argument>--add-to-start=server,requestlog,deploy,websocket,ext,resources,client,annotations,jndi,servlets,jsp,jstl,http,https,demo</argument>
|
<argument>--add-module=server,requestlog,deploy,websocket,ext,resources,client,annotations,jndi,servlets,jsp,jstl,http,https,demo</argument>
|
||||||
</arguments>
|
</arguments>
|
||||||
</configuration>
|
</configuration>
|
||||||
<goals>
|
<goals>
|
||||||
|
|
|
@ -11,23 +11,6 @@
|
||||||
<name>Jetty :: Documentation</name>
|
<name>Jetty :: Documentation</name>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<properties>
|
|
||||||
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
|
|
||||||
<html.common.directory>${project.build.directory}/html/common</html.common.directory>
|
|
||||||
<html.image.directory>${project.build.directory}/html/common/images</html.image.directory>
|
|
||||||
<javadoc.version>${project.version}</javadoc.version>
|
|
||||||
<asciidoctor.maven.plugin.version>1.5.7.1</asciidoctor.maven.plugin.version>
|
|
||||||
<asciidoctorj.pdf.version>1.5.0-alpha.16</asciidoctorj.pdf.version>
|
|
||||||
<asciidoctorj.epub.version>1.5.0-alpha.8.1</asciidoctorj.epub.version>
|
|
||||||
<asciidoctorj.version>1.5.8.1</asciidoctorj.version>
|
|
||||||
<jruby.version>1.7.27</jruby.version>
|
|
||||||
<web.resources.version>1.2</web.resources.version>
|
|
||||||
<web.resources.directory>${project.build.directory}/web-resources</web.resources.directory>
|
|
||||||
<!-- old properties -->
|
|
||||||
<html.directory>${project.build.directory}/current</html.directory>
|
|
||||||
<javadoc.version>${project.version}</javadoc.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||||
|
@ -99,73 +82,32 @@
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty.memcached</groupId>
|
||||||
|
<artifactId>jetty-memcached-sessions</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-dependency-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>unpack-jetty-web-resouces</id>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>unpack</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<artifactItems>
|
|
||||||
<artifactItem>
|
|
||||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
|
||||||
<artifactId>jetty-web-resources</artifactId>
|
|
||||||
<version>${web.resources.version}</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<overWrite>true</overWrite>
|
|
||||||
<outputDirectory>${web.resources.directory}</outputDirectory>
|
|
||||||
</artifactItem>
|
|
||||||
</artifactItems>
|
|
||||||
<excludes>META-INF/**</excludes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>copy-base-html-assets</id>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-resources</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>${web.resources.directory}/html</directory>
|
|
||||||
<includes>
|
|
||||||
<include>**</include>
|
|
||||||
</includes>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
<outputDirectory>${html.common.directory}</outputDirectory>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.asciidoctor</groupId>
|
<groupId>org.asciidoctor</groupId>
|
||||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||||
<version>${asciidoctor.maven.plugin.version}</version>
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.asciidoctor</groupId>
|
<groupId>org.asciidoctor</groupId>
|
||||||
<artifactId>asciidoctorj-diagram</artifactId>
|
<artifactId>asciidoctorj-diagram</artifactId>
|
||||||
<version>2.0.1</version>
|
<version>2.0.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<configuration>
|
<configuration>
|
||||||
|
<backend>html5</backend>
|
||||||
|
<requires>
|
||||||
|
<require>asciidoctor-diagram</require>
|
||||||
|
</requires>
|
||||||
<attributes>
|
<attributes>
|
||||||
<JDURL>http://www.eclipse.org/jetty/javadoc/${javadoc.version}</JDURL>
|
<JDURL>http://www.eclipse.org/jetty/javadoc/${project.version}</JDURL>
|
||||||
<JXURL>http://download.eclipse.org/jetty/stable-9/xref</JXURL>
|
<JXURL>http://download.eclipse.org/jetty/stable-9/xref</JXURL>
|
||||||
<SRCDIR>${basedir}/..</SRCDIR>
|
<SRCDIR>${basedir}/..</SRCDIR>
|
||||||
<GITBROWSEURL>https://github.com/eclipse/jetty.project/tree/master</GITBROWSEURL>
|
<GITBROWSEURL>https://github.com/eclipse/jetty.project/tree/master</GITBROWSEURL>
|
||||||
|
@ -187,8 +129,6 @@
|
||||||
<goal>process-asciidoc</goal>
|
<goal>process-asciidoc</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<backend>html5</backend>
|
|
||||||
<templateDir>${web.resources.directory}/asciidoc/slim-template</templateDir>
|
|
||||||
<sourceDirectory>src/main/asciidoc/operations-guide</sourceDirectory>
|
<sourceDirectory>src/main/asciidoc/operations-guide</sourceDirectory>
|
||||||
<sourceDocumentName>index.adoc</sourceDocumentName>
|
<sourceDocumentName>index.adoc</sourceDocumentName>
|
||||||
<outputDirectory>${project.build.directory}/html/operations-guide</outputDirectory>
|
<outputDirectory>${project.build.directory}/html/operations-guide</outputDirectory>
|
||||||
|
@ -201,12 +141,9 @@
|
||||||
<goal>process-asciidoc</goal>
|
<goal>process-asciidoc</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<backend>html5</backend>
|
|
||||||
<templateDir>${web.resources.directory}/asciidoc/slim-template</templateDir>
|
|
||||||
<sourceDirectory>${basedir}/src/main/asciidoc/contribution-guide</sourceDirectory>
|
<sourceDirectory>${basedir}/src/main/asciidoc/contribution-guide</sourceDirectory>
|
||||||
<sourceDocumentName>index.adoc</sourceDocumentName>
|
<sourceDocumentName>index.adoc</sourceDocumentName>
|
||||||
<outputDirectory>${project.build.directory}/html/contribution-guide</outputDirectory>
|
<outputDirectory>${project.build.directory}/html/contribution-guide</outputDirectory>
|
||||||
<sourceHighlighter>coderay</sourceHighlighter>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
<execution>
|
<execution>
|
||||||
|
@ -216,15 +153,9 @@
|
||||||
<goal>process-asciidoc</goal>
|
<goal>process-asciidoc</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<backend>html5</backend>
|
|
||||||
<templateDir>${web.resources.directory}/asciidoc/slim-template</templateDir>
|
|
||||||
<sourceDirectory>${basedir}/src/main/asciidoc/programming-guide</sourceDirectory>
|
<sourceDirectory>${basedir}/src/main/asciidoc/programming-guide</sourceDirectory>
|
||||||
<sourceDocumentName>index.adoc</sourceDocumentName>
|
<sourceDocumentName>index.adoc</sourceDocumentName>
|
||||||
<outputDirectory>${project.build.directory}/html/programming-guide</outputDirectory>
|
<outputDirectory>${project.build.directory}/html/programming-guide</outputDirectory>
|
||||||
<sourceHighlighter>coderay</sourceHighlighter>
|
|
||||||
<requires>
|
|
||||||
<require>asciidoctor-diagram</require>
|
|
||||||
</requires>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
|
@ -249,113 +180,4 @@
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>alt-formats</id>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.asciidoctor</groupId>
|
|
||||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
|
||||||
<version>${asciidoctor.maven.plugin.version}</version>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.asciidoctor</groupId>
|
|
||||||
<artifactId>asciidoctorj-pdf</artifactId>
|
|
||||||
<version>${asciidoctorj.pdf.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.asciidoctor</groupId>
|
|
||||||
<artifactId>asciidoctorj-epub3</artifactId>
|
|
||||||
<version>${asciidoctorj.epub.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jruby</groupId>
|
|
||||||
<artifactId>jruby-complete</artifactId>
|
|
||||||
<version>${jruby.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.asciidoctor</groupId>
|
|
||||||
<artifactId>asciidoctorj</artifactId>
|
|
||||||
<version>${asciidoctorj.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<configuration>
|
|
||||||
<imagesdir />
|
|
||||||
<backend>docbook</backend>
|
|
||||||
<attributes>
|
|
||||||
<revnumber>${project.version}</revnumber>
|
|
||||||
<JDURL>http://www.eclipse.org/jetty/javadoc/${javadoc.version}</JDURL>
|
|
||||||
<JXURL>http://download.eclipse.org/jetty/stable-9/xref</JXURL>
|
|
||||||
<SRCDIR>${basedir}/..</SRCDIR>
|
|
||||||
<GITBROWSEURL>https://github.com/eclipse/jetty.project/tree/master</GITBROWSEURL>
|
|
||||||
<MVNCENTRAL>http://central.maven.org/maven2</MVNCENTRAL>
|
|
||||||
<VERSION>${project.version}</VERSION>
|
|
||||||
</attributes>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>contribution-guide-pdf</id>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>process-asciidoc</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<backend>pdf</backend>
|
|
||||||
<sourceHighlighter>coderay</sourceHighlighter>
|
|
||||||
<attributes>
|
|
||||||
<icons>font</icons>
|
|
||||||
<pagenums />
|
|
||||||
<toc />
|
|
||||||
<idprefix />
|
|
||||||
<idseparator>-</idseparator>
|
|
||||||
</attributes>
|
|
||||||
<sourceDirectory>${basedir}/src/main/asciidoc/contribution-guide</sourceDirectory>
|
|
||||||
<sourceDocumentName>index.adoc</sourceDocumentName>
|
|
||||||
<outputFile>${project.build.directory}/pdf/contribution-guide/contribution-guide.pdf</outputFile>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>quickstart-distribution-guide-pdf</id>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>process-asciidoc</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<backend>pdf</backend>
|
|
||||||
<sourceHighlighter>coderay</sourceHighlighter>
|
|
||||||
<attributes>
|
|
||||||
<icons>font</icons>
|
|
||||||
<pagenums />
|
|
||||||
<toc />
|
|
||||||
<idprefix />
|
|
||||||
<idseparator>-</idseparator>
|
|
||||||
</attributes>
|
|
||||||
<sourceDirectory>${basedir}/src/main/asciidoc/quickstart-distribution-guide</sourceDirectory>
|
|
||||||
<sourceDocumentName>index.adoc</sourceDocumentName>
|
|
||||||
<outputFile>${project.build.directory}/pdf/quickstart-distribution-guide/quickstart-distribution-guide.pdf</outputFile>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>contribution-guide-epub</id>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>process-asciidoc</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<backend>epub3</backend>
|
|
||||||
<sourceHighlighter>coderay</sourceHighlighter>
|
|
||||||
<sourceDirectory>${basedir}/src/main/asciidoc/contribution-guide</sourceDirectory>
|
|
||||||
<sourceDocumentName>index.adoc</sourceDocumentName>
|
|
||||||
<outputFile>${project.build.directory}/epub/contribution-guide/contribution-guide.epub</outputFile>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
:author: Jetty Developers
|
||||||
|
:email: jetty-dev@eclipse.org
|
||||||
|
:revnumber: {version}
|
||||||
|
:revdate: {localdate}
|
||||||
|
|
||||||
|
:toc: left
|
||||||
|
:toclevels: 4
|
||||||
|
|
||||||
|
:idseparator: -
|
||||||
|
:sectlinks:
|
||||||
|
:sectanchors:
|
||||||
|
|
||||||
|
// Use fonts for admonitions.
|
||||||
|
:icons: font
|
||||||
|
|
||||||
|
// HTML specific directives
|
||||||
|
ifdef::backend-html5[]
|
||||||
|
:safe-mode-unsafe:
|
||||||
|
:linkcss:
|
||||||
|
endif::[]
|
||||||
|
|
||||||
|
// TODO: remove this attribute once all documentation has been ported.
|
||||||
|
:sub-order: attributes+
|
|
@ -17,45 +17,11 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
:doctitle: Eclipse Jetty: Contribution Guide
|
:doctitle: Eclipse Jetty: Contribution Guide
|
||||||
:author: Jetty Developers
|
|
||||||
:email: jetty-dev@eclipse.org
|
|
||||||
:revnumber: 1.0
|
|
||||||
:revdate: {TIMESTAMP}
|
|
||||||
:toc: left
|
|
||||||
:toc-title: Contribution Guide
|
:toc-title: Contribution Guide
|
||||||
:toc-style:
|
|
||||||
|
|
||||||
:header-style: eclipse-thin
|
|
||||||
:breadcrumb-style: eclipse-thin
|
|
||||||
:footer-style: default
|
|
||||||
:breadcrumb: Home:../index.html | Contribution Guide:./index.html
|
:breadcrumb: Home:../index.html | Contribution Guide:./index.html
|
||||||
|
:idprefix: cg-
|
||||||
|
|
||||||
// docinfo lets you pull in shared content and/or influence via render type
|
include::../config.adoc[]
|
||||||
//:docinfodir: {DOCINFODIR}/documentation
|
|
||||||
//:docinfo1:
|
|
||||||
|
|
||||||
// html specific directives
|
|
||||||
ifdef::backend-html5[]
|
|
||||||
:safe-mode-unsafe:
|
|
||||||
:stylesdir: ../common/css
|
|
||||||
:stylesheet: jetty.css
|
|
||||||
:linkcss:
|
|
||||||
:scriptsdir: ../common/js
|
|
||||||
endif::[]
|
|
||||||
|
|
||||||
// options for special blocks, code snippets, screen, etc
|
|
||||||
:sub-order: attributes+
|
|
||||||
|
|
||||||
// uncomment to allow include::https:// style content inclusion
|
|
||||||
//:allow-uri-read: true
|
|
||||||
|
|
||||||
// use fonts for admonitions
|
|
||||||
:icons: font
|
|
||||||
|
|
||||||
// suppress automatic id generation
|
|
||||||
:sectids!:
|
|
||||||
|
|
||||||
|
|
||||||
include::1-introduction.adoc[]
|
include::1-introduction.adoc[]
|
||||||
include::2-community.adoc[]
|
include::2-community.adoc[]
|
||||||
include::3-source.adoc[]
|
include::3-source.adoc[]
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// Asciidoctor IDE configuration file.
|
||||||
|
// See https://github.com/asciidoctor/asciidoctor-intellij-plugin/wiki/Support-project-specific-configurations
|
||||||
|
:JETTY_HOME: ../../../../../../jetty-home/target/jetty-home
|
|
@ -0,0 +1,81 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-begin-arch]]
|
||||||
|
==== Eclipse Jetty Architecture Overview
|
||||||
|
|
||||||
|
There are two main concepts on which the Eclipse Jetty standalone server is based:
|
||||||
|
|
||||||
|
* the xref:og-begin-arch-modules[Jetty _module_ system], that provides the Jetty features
|
||||||
|
* the xref:og-begin-arch-jetty-base[`$JETTY_BASE` directory], that provides a place where you configure the modules, and therefore the features, you need for your web applications
|
||||||
|
|
||||||
|
After installing Jetty, you want to setup a xref:og-begin-arch-jetty-base[`$JETTY_BASE` directory] where you configure xref:og-begin-arch-modules[Jetty modules].
|
||||||
|
|
||||||
|
[[og-begin-arch-modules]]
|
||||||
|
===== Eclipse Jetty Architecture: Modules
|
||||||
|
|
||||||
|
The Jetty standalone server is made of xref:pg-arch-bean[components] that are assembled together, configured and started to provide different features.
|
||||||
|
|
||||||
|
A Jetty _module_ is made of one or more components that work together to provide typically one feature, although they may provide more than one feature.
|
||||||
|
|
||||||
|
A Jetty module is nothing more than Jetty components assembled together like you would do using Java APIs, just done in a declarative way using configuration files rather than using Java APIs.
|
||||||
|
What you can do in Java code to assemble Jetty components, it can be done using Jetty modules.
|
||||||
|
|
||||||
|
A Jetty module may be dependent on other Jetty modules: for example, the `http` Jetty module depends on the `server` Jetty module, that in turn depends on the `threadpool` and `logging` Jetty modules.
|
||||||
|
|
||||||
|
Every feature in a Jetty server is enabled by enabling correspondent Jetty modules.
|
||||||
|
|
||||||
|
For example, if you enable only the `http` Jetty module, then your Jetty standalone server will only be able to listen to a network port for clear-text HTTP requests.
|
||||||
|
It will not be able to process secure HTTP (i.e. `https`) requests, it will not be able to process WebSocket, or HTTP/2 or any other protocol because the correspondent modules have not been enabled.
|
||||||
|
|
||||||
|
You can even start a Jetty server _without_ listening on a network port -- for example because you have enabled a custom module you wrote that provides the features you need.
|
||||||
|
|
||||||
|
This allows the Jetty standalone server to be as small as necessary: modules that are not enabled are not loaded, don't waste memory, and you don't risk that client use a module that you did not know was even there.
|
||||||
|
|
||||||
|
For more detailed information about the Jetty module system, see xref:og-modules[this section].
|
||||||
|
|
||||||
|
[[og-begin-arch-jetty-base]]
|
||||||
|
===== Eclipse Jetty Architecture: `$JETTY_BASE`
|
||||||
|
|
||||||
|
After installing Jetty in `$JETTY_HOME`, you want to create another directory that will be referred to as `$JETTY_BASE`, likely in a different location in the file system from `$JETTY_HOME`.
|
||||||
|
|
||||||
|
The `$JETTY_BASE` directory is where you configure which Jetty modules you want to use and what configuration they have, and it is the base directory where you deploy your web applications.
|
||||||
|
You do not deploy your web applications in `$JETTY_HOME`, you deploy them in `$JETTY_BASE`.
|
||||||
|
|
||||||
|
You can have just one `$JETTY_HOME` but multiple `$JETTY_HOME` directories, each with its own configuration.
|
||||||
|
|
||||||
|
This separation between `$JETTY_HOME` and `$JETTY_BASE` allows to upgrade Jetty without affecting your web applications.
|
||||||
|
`$JETTY_HOME` contains the Jetty runtime and libraries and the default configuration, while a `$JETTY_BASE` contains your web applications and any override of the default configuration.
|
||||||
|
|
||||||
|
For example, with the `$JETTY_HOME` installation the default value for the network port for clear-text HTTP is `8080`.
|
||||||
|
However, you want that port to be `6060`, for example because you are behind a load balancer that is configured to forward to the backend on port `6060`.
|
||||||
|
|
||||||
|
If you had changed the default configuration in `$JETTY_HOME`, when you upgrade Jetty, say from version `10.0.0` to version `10.0.1`, your change will be lost.
|
||||||
|
You would have to remember all the changes you made to the default configuration, upgrade Jetty (which would overwrite the configuration files with the default values), and made again all the changes, which results in a maintenance nightmare.
|
||||||
|
|
||||||
|
Instead, you want to configure the clear-text HTTP port in your `$JETTY_BASE`.
|
||||||
|
When you upgrade Jetty, you will upgrade only files in `$JETTY_HOME`, and all the configuration in `$JETTY_BASE` will remain unchanged.
|
||||||
|
|
||||||
|
Installing the Jetty runtime and libraries in `$JETTY_HOME` also allows you to leverage file system permissions: `$JETTY_HOME` may be owned by an administrator user (so that only administrators can upgrade it), while `$JETTY_BASE` directories may be owned by a less privileged user.
|
||||||
|
|
||||||
|
[IMPORTANT]
|
||||||
|
====
|
||||||
|
Install Jetty and never modify the files under `$JETTY_HOME`, unless you are upgrading Jetty itself.
|
||||||
|
|
||||||
|
Do all the rest in `$JETTY_BASE`.
|
||||||
|
====
|
|
@ -0,0 +1,28 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-begin]]
|
||||||
|
=== Introduction to Eclipse Jetty
|
||||||
|
|
||||||
|
This section will get you started with Eclipse Jetty.
|
||||||
|
|
||||||
|
include::download.adoc[]
|
||||||
|
include::install.adoc[]
|
||||||
|
include::architecture.adoc[]
|
||||||
|
include::start.adoc[]
|
||||||
|
include::deploy.adoc[]
|
|
@ -0,0 +1,120 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-begin-deploy]]
|
||||||
|
==== Deploying Web Applications to Eclipse Jetty
|
||||||
|
|
||||||
|
For the purpose of deploying web applications to Jetty, there are two types of resources that can be deployed:
|
||||||
|
|
||||||
|
* Standard Web Application Archives, in the form of `+*.war+` files or `+*.war+` directories, defined by the Servlet specification.
|
||||||
|
Their deployment is described in xref:og-begin-deploy-war[this section].
|
||||||
|
* Jetty context XML files, that allow you to customize the deployment of standard web applications, and also allow you use Jetty components, and possibly custom components written by you, to assemble your web applications.
|
||||||
|
Their deployment is described in xref:og-deploy[this section].
|
||||||
|
|
||||||
|
[[og-begin-deploy-war]]
|
||||||
|
===== Deploying Standard +*.war+ Web Applications
|
||||||
|
|
||||||
|
A standard Servlet web application is packaged in either a `+*.war+` file or in a directory with the structure of a `+*.war+` file.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
Recall that the structure of a `+*.war+` file is as follows:
|
||||||
|
|
||||||
|
[source,subs=verbatim]
|
||||||
|
----
|
||||||
|
mywebapp.war
|
||||||
|
├── index.html <1>
|
||||||
|
└── WEB-INF <2>
|
||||||
|
├── classes/ <3>
|
||||||
|
├── lib/ <4>
|
||||||
|
└── web.xml <5>
|
||||||
|
----
|
||||||
|
<1> Publicly accessible resources such as `+*.html+`, `+*.jsp+`, `+*.css+`, `+*.js+` files, etc. are placed in `+*.war+` or in sub-directories of the `+*.war+`.
|
||||||
|
<2> `WEB-INF` is a special directory used to store anything related to the web application that must not be publicly accessible, but may be accessed by other resources.
|
||||||
|
<3> `WEB-INF/classes` stores the web application compiled `+*.class+` files
|
||||||
|
<4> `WEB-INF/classes` stores the web application `+*.jar+` files
|
||||||
|
<5> `WEB-INF/web.xml` is the web application deployment descriptor defines the components and the configuration of your web application.
|
||||||
|
====
|
||||||
|
|
||||||
|
To deploy a standard web application, you need to enable the `deploy` module (see the `deploy` module complete definition xref:og-module-deploy[here]).
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar --add-module=deploy
|
||||||
|
----
|
||||||
|
----
|
||||||
|
INFO : webapp transitively enabled, ini template available with --add-module=webapp
|
||||||
|
INFO : security transitively enabled
|
||||||
|
INFO : servlet transitively enabled
|
||||||
|
INFO : deploy initialized in ${jetty.base}/start.d/deploy.ini
|
||||||
|
INFO : mkdir ${jetty.base}/webapps
|
||||||
|
INFO : Base directory was modified
|
||||||
|
----
|
||||||
|
|
||||||
|
The `deploy` module creates the `$JETTY_BASE/webapps` directory, the directory where `+*.war+` files or `+*.war+` directories should be copied so that Jetty can deploy them.
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
The `deploy` module only provides the feature of deploying web applications.
|
||||||
|
|
||||||
|
Whether these web applications are served via clear-text HTTP/1.1, or secure HTTP/1.1, or secure HTTP/2 (or even all of these protocols) depends on whether the correspondent Jetty modules have been enabled.
|
||||||
|
Refer to the xref:og-protocols[section about protocols] for further information.
|
||||||
|
====
|
||||||
|
|
||||||
|
Now you need to copy a web application to the `$JETTY_BASE/webapps` directory:
|
||||||
|
|
||||||
|
----
|
||||||
|
curl https://repo1.maven.org/maven2/org/eclipse/jetty/test-jetty-webapp/10.0.0/test-jetty-webapp-10.0.0.war --output $JETTY_BASE/webapps/test.war
|
||||||
|
----
|
||||||
|
// TODO: this webapp requires the login module, need something simpler.
|
||||||
|
// TODO: replace this with a module, so the download is done by the module.
|
||||||
|
|
||||||
|
The `$JETTY_BASE` directory is now:
|
||||||
|
|
||||||
|
----
|
||||||
|
$JETTY_BASE
|
||||||
|
├── resources
|
||||||
|
│ └── jetty-logging.properties
|
||||||
|
├── start.d
|
||||||
|
│ ├── deploy.ini
|
||||||
|
│ └── http.ini
|
||||||
|
└── webapps
|
||||||
|
└── test.war
|
||||||
|
----
|
||||||
|
|
||||||
|
Now start Jetty:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar
|
||||||
|
----
|
||||||
|
----
|
||||||
|
2020-09-16 09:53:38.182:INFO :oejs.Server:main: jetty-10.0.0-SNAPSHOT; built: 2020-09-16T07:47:47.334Z; git: d45455b32d96f516d39e03b53e91502a34b04f37; jvm 15+36-1562
|
||||||
|
2020-09-16 09:53:38.205:INFO :oejdp.ScanningAppProvider:main: Deployment monitor [file:///tmp/jetty.base/webapps/] at interval 1
|
||||||
|
2020-09-16 09:53:38.293:WARN :oejshC.test:main: The async-rest webapp is deployed. DO NOT USE IN PRODUCTION!
|
||||||
|
2020-09-16 09:53:38.298:INFO :oejw.StandardDescriptorProcessor:main: NO JSP Support for /test, did not find org.eclipse.jetty.jsp.JettyJspServlet
|
||||||
|
2020-09-16 09:53:38.306:INFO :oejss.DefaultSessionIdManager:main: DefaultSessionIdManager workerName=node0
|
||||||
|
2020-09-16 09:53:38.306:INFO :oejss.DefaultSessionIdManager:main: No SessionScavenger set, using defaults
|
||||||
|
2020-09-16 09:53:38.307:INFO :oejss.HouseKeeper:main: node0 Scavenging every 660000ms
|
||||||
|
2020-09-16 09:53:38.331:INFO :oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@45b4c3a9{Async REST Webservice Example,/test,[file:///tmp/jetty-0_0_0_0-8080-test_war-_test-any-15202033063643714058.dir/webapp/, jar:file:///tmp/jetty-0_0_0_0-8080-test_war-_test-any-15202033063643714058.dir/webapp/WEB-INF/lib/example-async-rest-jar-10.0.0-SNAPSHOT.jar!/META-INF/resources],AVAILABLE}{/tmp/jetty.base/webapps/test.war}
|
||||||
|
2020-09-16 09:53:38.338:INFO :oejs.AbstractConnector:main: Started ServerConnector@543295b0{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
|
||||||
|
2020-09-16 09:53:38.347:INFO :oejs.Server:main: Started Server@5ffead27{STARTING}[10.0.0-SNAPSHOT,sto=5000] @593ms
|
||||||
|
----
|
||||||
|
// TODO: highlight the line that says that it deployed a context
|
||||||
|
|
||||||
|
Now you can access the web application by pointing your browser to `+http://localhost:8080/test+`.
|
||||||
|
|
||||||
|
If you want to customize the deployment of your web application, for example by specifying a `contextPath` different from the file/directory name, or by specifying JNDI entries, or by specifying virtual hosts, etc. read xref:og-deploy[this section].
|
|
@ -0,0 +1,25 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-begin-download]]
|
||||||
|
==== Downloading Eclipse Jetty
|
||||||
|
|
||||||
|
The Eclipse Jetty distribution is available for download from link:https://www.eclipse.org/jetty/download.html[]
|
||||||
|
|
||||||
|
The Eclipse Jetty distribution is available in both `zip` and `gzip` formats; download the one most appropriate for your system, typically `zip` for Windows and `gzip` for other operative systems.
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-begin-install]]
|
||||||
|
==== Installing Eclipse Jetty
|
||||||
|
|
||||||
|
After the download, unpacking the Eclipse Jetty distribution will extract the files into a directory called `jetty-distribution-VERSION`, where `VERSION` is the version that you downloaded, for example `10.0.0`, so that the directory is called `jetty-distribution-10.0.0`.
|
||||||
|
|
||||||
|
Unpack the Eclipse Jetty distribution compressed file in a convenient location, for example under `/opt`.
|
||||||
|
|
||||||
|
NOTE: For Windows users, you should unpack Jetty to a path that does not contain spaces.
|
||||||
|
|
||||||
|
The rest of the instructions in this documentation will refer to this location as `$JETTY_HOME`, or `${jetty.home}`.
|
||||||
|
|
||||||
|
IMPORTANT: It is important that *only* stable release versions are used in production environments.
|
||||||
|
Versions that have been deprecated or are released as Milestones (M), Alpha, Beta or Release Candidates (RC) are *not* suitable for production as they may contain security flaws or incomplete/non-functioning feature sets.
|
||||||
|
|
||||||
|
If you are new to Jetty, read the xref:og-begin-arch[Jetty architecture short section] to become familiar with the terms used in this document.
|
||||||
|
Otherwise, you can jump to the xref:og-begin-start[start Jetty section].
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-begin-start]]
|
||||||
|
==== Starting Eclipse Jetty
|
||||||
|
|
||||||
|
// TODO: Consider: old_docs/startup/*.adoc
|
||||||
|
|
||||||
|
// So far, what below is the content of old_docs/startup/startup-modules.adoc
|
||||||
|
|
||||||
|
Eclipse Jetty as a standalone server has no graphical user interface, so configuring and running the server is done from the command line.
|
||||||
|
|
||||||
|
Recall from the xref:og-begin-arch[Eclipse Jetty standalone server architecture section] that Jetty is based on xref:og-modules[modules], that provides features, and on xref:og-begin-arch-jetty-base[`$JETTY_BASE`], the place where you configure which module (and therefore which feature) you want to enable, and where you configure module parameters.
|
||||||
|
|
||||||
|
Jetty is started by executing `$JETTY_HOME/start.jar`, but first we need to create a `$JETTY_BASE`:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ JETTY_BASE=/path/to/jetty.base
|
||||||
|
$ cd $JETTY_BASE
|
||||||
|
$ java -jar $JETTY_HOME/start.jar
|
||||||
|
----
|
||||||
|
----
|
||||||
|
ERROR : Nothing to start, exiting ...
|
||||||
|
|
||||||
|
Usage: java -jar $JETTY_HOME/start.jar [options] [properties] [configs]
|
||||||
|
java -jar $JETTY_HOME/start.jar --help # for more information
|
||||||
|
----
|
||||||
|
|
||||||
|
The error is normal, since the `$JETTY_BASE` you just created is empty and therefore there is no configuration to use to assemble the Jetty server.
|
||||||
|
|
||||||
|
However, it shows that `start.jar` takes parameters, whose details can be found in xref:og-start-jar[this section].
|
||||||
|
|
||||||
|
You can explore what modules are available out of the box via:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar --list-modules=*
|
||||||
|
----
|
||||||
|
// TODO: add output of the --list-modules command?
|
||||||
|
|
||||||
|
Try to enable the `http` module (see also xref:og-protocols-http[this section] for additional information):
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar --add-module=http
|
||||||
|
----
|
||||||
|
----
|
||||||
|
INFO : mkdir ${jetty.base}/start.d
|
||||||
|
INFO : server transitively enabled, ini template available with --add-module=server
|
||||||
|
INFO : logging-jetty transitively enabled
|
||||||
|
INFO : http initialized in ${jetty.base}/start.d/http.ini
|
||||||
|
INFO : resources transitively enabled
|
||||||
|
INFO : threadpool transitively enabled, ini template available with --add-module=threadpool
|
||||||
|
INFO : logging/slf4j dynamic dependency of logging-jetty
|
||||||
|
INFO : bytebufferpool transitively enabled, ini template available with --add-module=bytebufferpool
|
||||||
|
INFO : mkdir ${jetty.base}/resources
|
||||||
|
INFO : copy ${jetty.home}/modules/logging/jetty/resources/jetty-logging.properties to ${jetty.base}/resources/jetty-logging.properties
|
||||||
|
INFO : Base directory was modified
|
||||||
|
----
|
||||||
|
|
||||||
|
Now you can start Jetty:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar
|
||||||
|
----
|
||||||
|
[source,subs=quotes]
|
||||||
|
----
|
||||||
|
2020-09-11 15:35:17.451:INFO :oejs.Server:main: jetty-10.0.0-SNAPSHOT; built: 2020-09-10T11:01:33.608Z; git: b10a14ebf9b200da388f4f9a2036bd8117ee0b11; jvm 11.0.8+10
|
||||||
|
2020-09-11 15:35:17.485:INFO :oejs.AbstractConnector:main: Started ServerConnector@2d52216b{HTTP/1.1, #(http/1.1)}{0.0.0.0:8080}#
|
||||||
|
2020-09-11 15:35:17.496:INFO :oejs.Server:main: Started Server@44821a96{STARTING}[10.0.0-SNAPSHOT,sto=5000] @553ms
|
||||||
|
----
|
||||||
|
|
||||||
|
Note how Jetty is listening on port `8080` for clear-text HTTP/1.1 connections.
|
||||||
|
|
||||||
|
After having enabled the `http` module, the `$JETTY_BASE` directory looks like this:
|
||||||
|
|
||||||
|
[source,subs=verbatim]
|
||||||
|
----
|
||||||
|
JETTY_BASE
|
||||||
|
├── resources
|
||||||
|
│ └── jetty-logging.properties <1>
|
||||||
|
└── start.d <2>
|
||||||
|
└── http.ini <3>
|
||||||
|
----
|
||||||
|
|
||||||
|
<1> The `resources/jetty-logging.properties` file has been created because the `http` modules depends on the `server` module, which in turn depends on the `logging` module; the `logging` module created this file that can be configured to control the server logging level.
|
||||||
|
<2> The `start.d/` directory contains the configuration files for the modules.
|
||||||
|
<3> The `start.d/http.ini` file is the `http` module configuration file, where you can specify values for the `http` module properties.
|
||||||
|
|
||||||
|
In the `http.ini` file you can find the following content (among other content):
|
||||||
|
|
||||||
|
.http.ini
|
||||||
|
[source,subs=verbatim]
|
||||||
|
----
|
||||||
|
--module=http <1>
|
||||||
|
# jetty.http.port=8080 <2>
|
||||||
|
...
|
||||||
|
----
|
||||||
|
|
||||||
|
<1> This line enables the `http` module and should not be modified.
|
||||||
|
<2> This line is commented out and specifies the default value for the module property `jetty.http.port`, which is the network port that listens for clear-text HTTP connections.
|
||||||
|
|
||||||
|
You can change the module property `jetty.http.port` value directly from the command line:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar jetty.http.port=9999
|
||||||
|
----
|
||||||
|
|
||||||
|
To make this change persistent, you can edit the `http.ini` file, uncomment the module property `jetty.http.port` and change its value to `9999`:
|
||||||
|
|
||||||
|
.http.ini
|
||||||
|
----
|
||||||
|
--module=http
|
||||||
|
jetty.http.port=9999
|
||||||
|
...
|
||||||
|
----
|
||||||
|
|
||||||
|
If you restart Jetty, the new value will be used:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar
|
||||||
|
----
|
||||||
|
[source,subs=quotes]
|
||||||
|
----
|
||||||
|
2020-09-11 15:35:17.451:INFO :oejs.Server:main: jetty-10.0.0-SNAPSHOT; built: 2020-09-10T11:01:33.608Z; git: b10a14ebf9b200da388f4f9a2036bd8117ee0b11; jvm 11.0.8+10
|
||||||
|
2020-09-11 15:35:17.485:INFO :oejs.AbstractConnector:main: Started ServerConnector@2d52216b{HTTP/1.1, #(http/1.1)}{0.0.0.0:9999}#
|
||||||
|
2020-09-11 15:35:17.496:INFO :oejs.Server:main: Started Server@44821a96{STARTING}[10.0.0-SNAPSHOT,sto=5000] @553ms
|
||||||
|
----
|
||||||
|
|
||||||
|
Note how Jetty is now listening on port `9999` for clear-text HTTP/1.1 connections.
|
||||||
|
|
||||||
|
NOTE: If you want to enable support for different protocols such as secure HTTP/1.1 or HTTP/2, or configured Jetty behind a load balancer, read xref:og-protocols[this section].
|
||||||
|
|
||||||
|
The Jetty server is now up and running, but it has no web applications deployed, so it just replies with `404 Not Found` to every request.
|
||||||
|
It is time to xref:og-begin-deploy[deploy your web applications] to Jetty.
|
||||||
|
|
||||||
|
For more detailed information about the Jetty start system, you can read the xref:og-start-details[Jetty start system] section.
|
|
@ -0,0 +1,23 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-contexts]]
|
||||||
|
=== Configuring Jetty Context XML Files
|
||||||
|
|
||||||
|
TODO
|
||||||
|
// TODO: add here from old_docs/contexts and old_docs/extras
|
|
@ -0,0 +1,44 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-deploy]]
|
||||||
|
=== Customizing Web Application Deployment
|
||||||
|
|
||||||
|
Most of the times you want to be able to customize the deployment of your web applications, for example by changing the `contextPath`, or by adding JNDI entries, or by configuring virtual hosts, etc.
|
||||||
|
|
||||||
|
The customization is performed by the xref:og-module-deploy[`deploy` module] by processing xref:og-deploy-jetty[Jetty context XML files].
|
||||||
|
|
||||||
|
The `deploy` module contains the `DeploymentManager` component that scans the `$JETTY_BASE/webapps` directory for changes, following the deployment rules described in xref:og-deploy-rules[this section].
|
||||||
|
|
||||||
|
include::deploy-hot-static.adoc[]
|
||||||
|
include::deploy-rules.adoc[]
|
||||||
|
include::deploy-jetty.adoc[]
|
||||||
|
include::deploy-jndi.adoc[]
|
||||||
|
include::deploy-virtual-hosts.adoc[]
|
||||||
|
include::deploy-extract-war.adoc[]
|
||||||
|
include::deploy-override-webxml.adoc[]
|
||||||
|
|
||||||
|
// TODO: move this section to its own file
|
||||||
|
// TODO: configuring from the Jetty context XML file happens before web.xml
|
||||||
|
// What about jetty-web.xml? Can this be specified externally, e.g. WebAppContext.setJettyWebXml() ?
|
||||||
|
[[og-deploy-init-params]]
|
||||||
|
==== Configuring ``init-param``s
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
// TODO: see old_docs/deploying
|
|
@ -0,0 +1,39 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-deploy-extract-war]]
|
||||||
|
==== Configuring `+*.war+` File Extraction
|
||||||
|
|
||||||
|
By default, `+*.war+` files are uncompressed and its content extracted in a temporary directory.
|
||||||
|
// TODO: reference the `work` module and how it works, perhaps in a section about the `deploy` module?
|
||||||
|
The web application resources are served by Jetty from the files extracted in the temporary directory, not from the files within the `+*.war+` file, for performance reasons.
|
||||||
|
|
||||||
|
If you do not want Jetty to extract the `+*.war+` files, you can disable this feature, for example:
|
||||||
|
|
||||||
|
.mywebapp.xml
|
||||||
|
[source,xml,highlight=8]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||||
|
|
||||||
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
|
<Set name="contextPath">/mywebapp</Set>
|
||||||
|
<Set name="war">/opt/webapps/mywebapp.war</Set>
|
||||||
|
<Set name="extractWAR">false</Set>
|
||||||
|
</Configure>
|
||||||
|
----
|
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-deploy-hot-static]]
|
||||||
|
==== Hot vs Static Deployment
|
||||||
|
|
||||||
|
The `DeploymentManager` scans the `$JETTY_BASE/webapps` directory for changes every `N` seconds, where `N` is configured via the `jetty.deploy.scanInterval` property.
|
||||||
|
|
||||||
|
By default, the scan interval is `1` second, which means that _hot_ deployment is enabled: if a file is added/changed/removed from the `$JETTY_BASE/webapps` directory, the `DeploymentManager` will notice the change and respectively deploy/redeploy/undeploy the web application.
|
||||||
|
|
||||||
|
Setting the scan interval to `0` means that _static_ deployment is enabled, and the `DeploymentManager` will not scan the `$JETTY_BASE/webapps` directory for changes.
|
||||||
|
This means that to deploy/redeploy/undeploy a web application you will need to stop and restart Jetty.
|
||||||
|
|
||||||
|
The following command line disables _hot_ deployment by specifying the `jetty.deploy.scanInterval` property on the command line, and therefore only for this particular run:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar jetty.deploy.scanInterval=0
|
||||||
|
----
|
||||||
|
|
||||||
|
To make _static_ deployment persistent, you need to edit the `deploy` module configuration file, `$JETTY_BASE/start.d/deploy.ini`, uncomment the module property `jetty.deploy.scanInterval` and change its value to `0`:
|
||||||
|
|
||||||
|
.deploy.ini
|
||||||
|
[source,subs=quotes]
|
||||||
|
----
|
||||||
|
--module=deploy
|
||||||
|
#jetty.deploy.scanInterval=0#
|
||||||
|
...
|
||||||
|
----
|
|
@ -0,0 +1,80 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-deploy-jetty]]
|
||||||
|
==== Deploying Jetty Context XML Files
|
||||||
|
|
||||||
|
A Jetty context XML file is a xref:og-xml[Jetty XML file] that allows you to customize the deployment of web applications.
|
||||||
|
|
||||||
|
NOTE: Recall that the `DeploymentManager` component of the Jetty `deploy` module xref:og-deploy-rules[gives priority] to Jetty context XML files over `+*.war+` files or directories.
|
||||||
|
|
||||||
|
To deploy a web application using a Jetty context XML file, simply place the file in the `$JETTY_BASE/webapps` directory.
|
||||||
|
|
||||||
|
A simple Jetty context XML file, for example named `wiki.xml` is the following:
|
||||||
|
|
||||||
|
.wiki.xml
|
||||||
|
[source,xml,subs=verbatim]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||||
|
|
||||||
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext"> <1>
|
||||||
|
<Set name="contextPath">/wiki</Set> <2>
|
||||||
|
<Set name="war">/opt/myapps/myapp.war</Set> <3>
|
||||||
|
</Configure>
|
||||||
|
----
|
||||||
|
<1> Configures a link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[`WebAppContext`], which is the Jetty component that represents a standard Servlet web application.
|
||||||
|
<2> Specifies the web application `contextPath`, which may be different from the `+*.war+` file name.
|
||||||
|
<3> Specifies the file system path of the `+*.war+` file.
|
||||||
|
|
||||||
|
The `$JETTY_BASE` directory would look like this:
|
||||||
|
|
||||||
|
----
|
||||||
|
$JETTY_BASE
|
||||||
|
├── resources
|
||||||
|
│ └── jetty-logging.properties
|
||||||
|
├── start.d
|
||||||
|
│ ├── deploy.ini
|
||||||
|
│ └── http.ini
|
||||||
|
└── webapps
|
||||||
|
└── wiki.xml
|
||||||
|
----
|
||||||
|
|
||||||
|
TIP: The `+*.war+` file may be placed anywhere in the file system and does not need to be placed in the `$JETTY_BASE/webapps` directory.
|
||||||
|
|
||||||
|
IMPORTANT: If you place both the Jetty context XML file _and_ the `+*.war+` file in the `$JETTY_BASE/webapps` directory, remember that they must have the same file name, for example `wiki.xml` and `wiki.war`, so that the `DeploymentManager` deploys the web application only once using the Jetty context XML file (and not the `+*.war+` file).
|
||||||
|
|
||||||
|
You can use the features of xref:og-xml[Jetty XML files] to avoid to hard-code file system paths or other configurations in your Jetty context XML files, for example by using system properties:
|
||||||
|
|
||||||
|
.wiki.xml
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||||
|
|
||||||
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
|
<Set name="contextPath">/wiki</Set>
|
||||||
|
<Set name="war"><SystemProperty name="myapps.dir"/>/myapp.war</Set>
|
||||||
|
</Configure>
|
||||||
|
----
|
||||||
|
|
||||||
|
Note how the `+*.war+` file path is now obtained by resolving the system property `myapps.dir` that you can specify on the command line when you start Jetty:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar -Dmyapps.dir=/opt/myapps
|
||||||
|
----
|
|
@ -0,0 +1,56 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-deploy-jndi]]
|
||||||
|
==== Configuring JNDI Entries
|
||||||
|
|
||||||
|
A web application may _reference_ a JNDI entry, such as a JDBC `DataSource` from the web application `web.xml` file.
|
||||||
|
The JNDI entry must be _defined_ in the Jetty context XML file, for example:
|
||||||
|
|
||||||
|
.mywebapp.xml
|
||||||
|
[source,xml,subs=normal]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||||
|
|
||||||
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
|
<Set name="contextPath">/mywebapp</Set>
|
||||||
|
<Set name="war">/opt/webapps/mywebapp.war</Set>
|
||||||
|
# <New class="org.eclipse.jetty.plus.jndi.Resource">
|
||||||
|
<Arg />
|
||||||
|
<Arg>jdbc/myds</Arg>
|
||||||
|
<Arg>
|
||||||
|
<New class="com.mysql.cj.jdbc.MysqlConnectionPoolDataSource">
|
||||||
|
<Set name="url">jdbc:mysql://localhost:3306/databasename</Set>
|
||||||
|
<Set name="user">user</Set>
|
||||||
|
<Set name="password">password</Set>
|
||||||
|
</New>
|
||||||
|
</Arg>
|
||||||
|
</New>#
|
||||||
|
</Configure>
|
||||||
|
----
|
||||||
|
|
||||||
|
[IMPORTANT]
|
||||||
|
====
|
||||||
|
Class `com.mysql.cj.jdbc.MysqlConnectionPoolDataSource` is present in the MySQL JDBC driver file, `mysql-connector-java-<version>.jar`, which must be available to the web application.
|
||||||
|
|
||||||
|
File `mysql-connector-java-<version>.jar` must be either present in `WEB-INF/lib`, or in the Jetty server class-path.
|
||||||
|
====
|
||||||
|
// TODO: add a link to reference the section about how
|
||||||
|
// to add a JDBC driver jar to the server classpath.
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-deploy-jetty-override-web-xml]]
|
||||||
|
==== Overriding `web.xml`
|
||||||
|
|
||||||
|
You can configure an additional `web.xml` that complements the `web.xml` file that is present in the web application `+*.war+` file.
|
||||||
|
This additional `web.xml` is processed _after_ the `+*.war+` file `web.xml`.
|
||||||
|
This allows you to add host specific configuration or server specific configuration without having to extract the web application `web.xml`, modify it, and repackage it in the `+*.war+` file.
|
||||||
|
|
||||||
|
.mywebapp.xml
|
||||||
|
[source,xml,highlight=8]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||||
|
|
||||||
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
|
<Set name="contextPath">/mywebapp</Set>
|
||||||
|
<Set name="war">/opt/webapps/mywebapp.war</Set>
|
||||||
|
<Set name="overrideDescriptor">/opt/webapps/mywebapp-web.xml</Set>
|
||||||
|
</Configure>
|
||||||
|
----
|
||||||
|
|
||||||
|
The format of the additional `web.xml` is exactly the same as a standard `web.xml` file, for example:
|
||||||
|
|
||||||
|
.mywebapp-web.xml
|
||||||
|
[source,xml,linenums,highlight=10-11]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
|
||||||
|
version="4.0">
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>my-servlet</servlet-name>
|
||||||
|
<init-param>
|
||||||
|
<param-name>host</param-name>
|
||||||
|
<param-value>192.168.0.13</param-value>
|
||||||
|
</init-param>
|
||||||
|
</servlet>
|
||||||
|
</web-app>
|
||||||
|
----
|
||||||
|
|
||||||
|
In the example above, you configured the `my-servlet` Servlet (defined in the web application `web.xml`), adding a host specific `init-param` with the IP address of the host.
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-deploy-rules]]
|
||||||
|
==== Deployment Rules
|
||||||
|
|
||||||
|
_Adding_ a `+*.war+` file, a `+*.war+` directory, a Jetty context XML file or a normal directory to `$JETTY_BASE/webapps` causes the `DeploymentManager` to deploy the new web application.
|
||||||
|
|
||||||
|
_Updating_ a `+*.war+` file or a Jetty context XML file causes the `DeploymentManager` to redeploy the web application, which means that the Jetty context component representing the web application is stopped, then reconfigured, and then restarted.
|
||||||
|
|
||||||
|
_Removing_ a `+*.war+` file, a `+*.war+` directory, a Jetty context XML file or a normal directory from `$JETTY_BASE/webapps` causes the `DeploymentManager` to undeploy the web application, which means that the Jetty context component representing the web application is stopped and removed from the Jetty server.
|
||||||
|
|
||||||
|
When a file or directory is added to `$JETTY_BASE/webapps`, the `DeploymentManager` derives the web application `contextPath` from the file or directory name, with the following rules:
|
||||||
|
|
||||||
|
* If the directory name is, for example, `mywebapp/`, it is deployed as a standard web application if it contains a `WEB-INF/` subdirectory, otherwise it is deployed as a web application of static content.
|
||||||
|
The `contextPath` would be `/mywebapp` (that is, the web application is reachable at `+http://localhost:8080/mywebapp/+`).
|
||||||
|
* If the directory name is `ROOT`, case insensitive, the `contextPath` is `/` (that is, the web application is reachable at `+http://localhost:8080/+`).
|
||||||
|
* If the directory name ends with `.d`, for example `config.d/`, it is ignored, although it may be referenced to configure other web applications (for example to store common files).
|
||||||
|
* If the `+*.war+` file name is, for example, `mywebapp.war`, it is deployed as a standard web application with the context path `/mywebapp` (that is, the web application is reachable at `+http://localhost:8080/mywebapp/+`).
|
||||||
|
* If the file name is `ROOT.war`, case insensitive, the `contextPath` is `/` (that is, the web application is reachable at `+http://localhost:8080/+`).
|
||||||
|
* If both the `mywebapp.war` file and the `mywebapp/` directory exist, only the file is deployed.
|
||||||
|
This allows the directory with the same name to be the `+*.war+` file unpack location and avoid that the web application is deployed twice.
|
||||||
|
* A xref:og-deploy-jetty[Jetty context XML file] named `mywebapp.xml` is deployed as a web application by processing the directives contained in the XML file itself, which must set the `contextPath`.
|
||||||
|
* If both `mywebapp.xml` and `mywebapp.war` exist, only the XML file is deployed.
|
||||||
|
This allows the XML file to reference the `+*.war+` file and avoid that the web application is deployed twice.
|
||||||
|
|
||||||
|
// TODO: add section about the work directory from
|
||||||
|
// old_docs/contexts/temporary-directories.adoc
|
|
@ -0,0 +1,191 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-deploy-virtual-hosts]]
|
||||||
|
==== Configuring Virtual Hosts
|
||||||
|
|
||||||
|
A _virtual host_ is an internet domain name, registered in the Domain Name Server (DNS), for an IP address such that multiple virtual hosts will resolve to the same IP address of a single server instance.
|
||||||
|
|
||||||
|
If you have multiple web applications deployed on the same Jetty server, by using virtual hosts you will be able to target a specific web application.
|
||||||
|
|
||||||
|
For example, you may have a web application for your business and a web application for your hobbies , both deployed in the same Jetty server.
|
||||||
|
By using virtual hosts, you will be able to have the first web application available at `+http://domain.biz/+`, and the second web application available at `+http://hobby.net/+`.
|
||||||
|
|
||||||
|
Another typical case is when you want to use different subdomains for different web application, for example a project website is at `+http://project.org/+` and the project documentation is at `+http://docs.project.org+`.
|
||||||
|
|
||||||
|
Virtual hosts can be used with any context that is a subclass of link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html[ContextHandler].
|
||||||
|
|
||||||
|
[[og-deploy-virtual-hosts-names]]
|
||||||
|
===== Virtual Host Names
|
||||||
|
|
||||||
|
Jetty supports the following variants to be specified as virtual host names:
|
||||||
|
|
||||||
|
`www.hostname.com`::
|
||||||
|
A fully qualified domain name. It is important to list all variants as a site may receive traffic for both `www.hostname.com` and `hostname.com`.
|
||||||
|
|
||||||
|
`*.hostname.com`::
|
||||||
|
A wildcard domain name which will match only one level of arbitrary subdomains.
|
||||||
|
*.foo.com will match www.foo.com and m.foo.com, but not www.other.foo.com.
|
||||||
|
|
||||||
|
`10.0.0.2`::
|
||||||
|
An IP address may be set as a virtual host to indicate that a web application should handle requests received on the network interface with that IP address for protocols that do not indicate a host name such as HTTP/0.9 or HTTP/1.0.
|
||||||
|
|
||||||
|
`@ConnectorName`::
|
||||||
|
A Jetty `ServerConnector` name to indicate that a web application should handle requests received on the `ServerConnector` with that name, and therefore received on a specific IP port.
|
||||||
|
A `ServerConnector` name can be set via link:{JDURL}/org/eclipse/jetty/server/AbstractConnector.html#setName(java.lang.String)[].
|
||||||
|
|
||||||
|
`www.√integral.com`::
|
||||||
|
Non-ASCII and https://en.wikipedia.org/wiki/Internationalized_domain_name[IDN] domain names can be set as virtual hosts using https://en.wikipedia.org/wiki/Punycode[Puny Code] equivalents that may be obtained from a https://www.punycoder.com/[Punycode/IDN converters].
|
||||||
|
For example if the non-ASCII domain name `www.√integral.com` is given to a browser, then the browser will make a request that uses the domain name `www.xn--integral-7g7d.com`, which is the name that should be added as the virtual host name.
|
||||||
|
|
||||||
|
[[og-deploy-virtual-hosts-config]]
|
||||||
|
===== Virtual Hosts Configuration
|
||||||
|
|
||||||
|
If you have a web application `mywebapp.war` you can configure its virtual hosts in this way:
|
||||||
|
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||||
|
|
||||||
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
|
<Set name="contextPath">/mywebapp</Set>
|
||||||
|
<Set name="war">/opt/webapps/mywebapp.war</Set>
|
||||||
|
<Set name="virtualHosts">
|
||||||
|
<Array type="java.lang.String">
|
||||||
|
<Item>mywebapp.com</Item>
|
||||||
|
<Item>www.mywebapp.com</Item>
|
||||||
|
<Item>mywebapp.net</Item>
|
||||||
|
<Item>www.mywebapp.net</Item>
|
||||||
|
</Array>
|
||||||
|
</Set>
|
||||||
|
</Configure>
|
||||||
|
----
|
||||||
|
|
||||||
|
Your web application will be available at:
|
||||||
|
|
||||||
|
* `+http://mywebapp.com/mywebapp+`
|
||||||
|
* `+http://www.mywebapp.com/mywebapp+`
|
||||||
|
* `+http://mywebapp.net/mywebapp+`
|
||||||
|
* `+http://www.mywebapp.net/mywebapp+`
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
You configured the `contextPath` of your web application to `/mywebapp`.
|
||||||
|
|
||||||
|
As such, a request to `+http://mywebapp.com/other+` will not match your web application because the `contextPath` does not match.
|
||||||
|
|
||||||
|
Likewise, a request to `+http://other.com/mywebapp+` will not match your web application because the virtual host does not match.
|
||||||
|
====
|
||||||
|
|
||||||
|
[[og-deploy-virtual-hosts-same-context]]
|
||||||
|
===== Same Context Path, Different Virtual Hosts
|
||||||
|
|
||||||
|
If you want to deploy different web applications to the same context path, typically the root context path `/`, you must use virtual hosts to differentiate among web applications.
|
||||||
|
|
||||||
|
You have `domain.war` that you want to deploy at `+http://domain.biz/+` and `hobby.war` that you want to deploy at `+http://hobby.net+`.
|
||||||
|
|
||||||
|
To achieve this, you simply use the same context path of `/` for each of your webapps, while specifying different virtual hosts for each of your webapps:
|
||||||
|
|
||||||
|
.domain.xml
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||||
|
|
||||||
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
|
<Set name="contextPath">/</Set>
|
||||||
|
<Set name="war">/opt/webapps/domain.war</Set>
|
||||||
|
<Set name="virtualHosts">
|
||||||
|
<Array type="java.lang.String">
|
||||||
|
<Item>domain.biz</Item>
|
||||||
|
</Array>
|
||||||
|
</Set>
|
||||||
|
</Configure>
|
||||||
|
----
|
||||||
|
|
||||||
|
.hobby.xml
|
||||||
|
[source,xml]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||||
|
|
||||||
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
|
<Set name="contextPath">/</Set>
|
||||||
|
<Set name="war">/opt/webapps/hobby.war</Set>
|
||||||
|
<Set name="virtualHosts">
|
||||||
|
<Array type="java.lang.String">
|
||||||
|
<Item>hobby.net</Item>
|
||||||
|
</Array>
|
||||||
|
</Set>
|
||||||
|
</Configure>
|
||||||
|
----
|
||||||
|
|
||||||
|
[[og-deploy-virtual-hosts-port]]
|
||||||
|
===== Different Port, Different Web Application
|
||||||
|
|
||||||
|
Sometimes it is required to serve different web applications from different IP ports, and therefore from different ``ServerConnector``s.
|
||||||
|
|
||||||
|
For example, you want requests to `+http://localhost:8080/+` to be served by one web application, but requests to `+http://localhost:9090/+` to be served by another web application.
|
||||||
|
|
||||||
|
This configuration may be useful when Jetty sits behind a load balancer.
|
||||||
|
|
||||||
|
In this case, you want to xref:og-protocols[configure multiple connectors], each with a different name, and then reference the connector name in the web application virtual host configuration:
|
||||||
|
|
||||||
|
.domain.xml
|
||||||
|
[source,xml,highlight=10]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||||
|
|
||||||
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
|
<Set name="contextPath">/</Set>
|
||||||
|
<Set name="war">/opt/webapps/domain.war</Set>
|
||||||
|
<Set name="virtualHosts">
|
||||||
|
<Array type="java.lang.String">
|
||||||
|
<Item>@port8080</Item>
|
||||||
|
</Array>
|
||||||
|
</Set>
|
||||||
|
</Configure>
|
||||||
|
----
|
||||||
|
|
||||||
|
.hobby.xml
|
||||||
|
[source,xml,highlight=10]
|
||||||
|
----
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||||
|
|
||||||
|
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
|
<Set name="contextPath">/</Set>
|
||||||
|
<Set name="war">/opt/webapps/hobby.war</Set>
|
||||||
|
<Set name="virtualHosts">
|
||||||
|
<Array type="java.lang.String">
|
||||||
|
<Item>@port9090</Item>
|
||||||
|
</Array>
|
||||||
|
</Set>
|
||||||
|
</Configure>
|
||||||
|
----
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
====
|
||||||
|
Web application `domain.war` has a virtual host of `@port8080`, where `port8080` is the name of a Jetty connector.
|
||||||
|
|
||||||
|
Likewise, web application `hobby.war` has a virtual host of `@port9090`, where `port9090` is the name of another Jetty connector.
|
||||||
|
|
||||||
|
See xref:og-protocols[this section] for further information about how to configure connectors.
|
||||||
|
====
|
|
@ -17,48 +17,20 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
:doctitle: Eclipse Jetty: Operations Guide
|
:doctitle: Eclipse Jetty: Operations Guide
|
||||||
:author: Jetty Developers
|
|
||||||
:email: jetty-dev@eclipse.org
|
|
||||||
:revnumber: {version}
|
|
||||||
:revdate: {TIMESTAMP}
|
|
||||||
:toc: left
|
|
||||||
:toc-title: Operations Guide
|
:toc-title: Operations Guide
|
||||||
:toc-style:
|
|
||||||
|
|
||||||
:header-style: eclipse-thin
|
|
||||||
:breadcrumb-style: eclipse-thin
|
|
||||||
:footer-style: default
|
|
||||||
|
|
||||||
:breadcrumb: Home:../index.html | Operations Guide:./index.html
|
:breadcrumb: Home:../index.html | Operations Guide:./index.html
|
||||||
|
:idprefix: og-
|
||||||
|
|
||||||
// docinfo lets you pull in shared content and/or influence via render type
|
include::../config.adoc[]
|
||||||
//:docinfodir: {DOCINFODIR}/documentation
|
include::.asciidoctorconfig[]
|
||||||
//:docinfo1:
|
|
||||||
|
|
||||||
// html specific directives
|
|
||||||
ifdef::backend-html5[]
|
|
||||||
:safe-mode-unsafe:
|
|
||||||
:stylesdir: ../common/css
|
|
||||||
:stylesheet: jetty.css
|
|
||||||
:linkcss:
|
|
||||||
:scriptsdir: ../common/js
|
|
||||||
endif::[]
|
|
||||||
|
|
||||||
// options for special blocks, code snippets, screen, etc
|
|
||||||
:sub-order: attributes+
|
|
||||||
|
|
||||||
// uncomment to allow include::https:// style content inclusion
|
|
||||||
//:allow-uri-read: true
|
|
||||||
|
|
||||||
// use fonts for admonitions
|
|
||||||
:icons: font
|
|
||||||
|
|
||||||
// suppress automatic id generation
|
|
||||||
:sectids!:
|
|
||||||
|
|
||||||
// download and install
|
|
||||||
include::introduction.adoc[]
|
include::introduction.adoc[]
|
||||||
// TODO: jetty.home vs jetty.base
|
include::begin/chapter.adoc[]
|
||||||
|
|
||||||
|
include::start/chapter.adoc[]
|
||||||
|
include::deploy/chapter.adoc[]
|
||||||
|
include::protocols/chapter.adoc[]
|
||||||
|
include::modules/chapter.adoc[]
|
||||||
|
include::sessions/chapter.adoc[]
|
||||||
|
|
||||||
// TODO: how jetty standalone work what start.jar does, command line options, modules, etc.
|
// TODO: how jetty standalone work what start.jar does, command line options, modules, etc.
|
||||||
// TODO: this is mostly in old_docs/startup.
|
// TODO: this is mostly in old_docs/startup.
|
||||||
|
|
|
@ -16,33 +16,33 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[og-guide]]
|
[[og-intro]]
|
||||||
== Eclipse Jetty Operations Guide
|
== Eclipse Jetty Operations Guide
|
||||||
|
|
||||||
The Eclipse Jetty Operations Guide targets sysops, devops, and developers who want to install Eclipse Jetty as a standalone server to deploy web applications.
|
The Eclipse Jetty Operations Guide targets sysops, devops, and developers who want to install Eclipse Jetty as a standalone server to deploy web applications.
|
||||||
|
|
||||||
[[og-download]]
|
=== Introduction
|
||||||
=== Downloading Eclipse Jetty
|
|
||||||
|
|
||||||
The Eclipse Jetty distribution is available for download from link:https://www.eclipse.org/jetty/download.html[]
|
If you are new to Eclipse Jetty, read xref:og-begin[here] to download, install, start and deploy web applications to Jetty.
|
||||||
|
|
||||||
The Eclipse Jetty distribution is available in both `zip` and `gzip` formats; download the one most appropriate for your system, typically `zip` for Windows and `gzip` for other operative systems.
|
=== Eclipse Jetty Features
|
||||||
|
|
||||||
[[og-install]]
|
If you know Eclipse Jetty already, jump to a feature:
|
||||||
=== Installing Eclipse Jetty
|
|
||||||
|
|
||||||
After the download, unpacking the Eclipse Jetty distribution will extract the files into a directory called `jetty-distribution-VERSION`, where `VERSION` is the version that you downloaded, for example `10.0.0`, so that the directory is called `jetty-distribution-10.0.0`.
|
* xref:og-sessions[HTTP Session Caching and Clustering]
|
||||||
|
|
||||||
Unpack the Eclipse Jetty distribution compressed file in a convenient location, for example under `/opt`.
|
TODO
|
||||||
|
|
||||||
The rest of the instructions in this documentation will refer to this location as `$JETTY_HOME`.
|
* Jetty Overview
|
||||||
|
* Jetty Modules
|
||||||
|
* Rewrite Modules
|
||||||
|
|
||||||
IMPORTANT: It is important that *only* stable release versions are used in production environments.
|
=== Eclipse Jetty How-Tos
|
||||||
Versions that have been deprecated or are released as Milestones (M), Alpha, Beta or Release Candidates (RC) are *not* suitable for production as they may contain security flaws or incomplete/non-functioning feature sets.
|
|
||||||
|
|
||||||
[[og-running]]
|
* xref:og-protocols-http[Configure Clear-Text HTTP/1.1]
|
||||||
=== Running Eclipse Jetty
|
* xref:og-protocols-https[Configure Secure HTTP/1.1 (https)]
|
||||||
|
|
||||||
Eclipse Jetty as a standalone server has no graphical user interface, so configuring and running the server is done from the command line.
|
TODO
|
||||||
|
|
||||||
TODO: section about general architecture - modules etc.
|
* Jetty Behind a Load Balancer
|
||||||
|
** Forward Header Customizer
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
include::modules.adoc[]
|
||||||
|
include::module-bytebufferpool.adoc[]
|
||||||
|
include::module-deploy.adoc[]
|
||||||
|
include::module-http.adoc[]
|
||||||
|
include::module-server.adoc[]
|
||||||
|
include::module-threadpool.adoc[]
|
|
@ -0,0 +1,34 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-module-bytebufferpool]]
|
||||||
|
==== Module `bytebufferpool`
|
||||||
|
|
||||||
|
The `bytebufferpool` module allows you to configure the server-wide `ByteBuffer` pool.
|
||||||
|
|
||||||
|
// TODO: expand
|
||||||
|
|
||||||
|
The module file is `$JETTY_HOME/modules/bytebufferpool.mod`:
|
||||||
|
|
||||||
|
----
|
||||||
|
include::{JETTY_HOME}/modules/bytebufferpool.mod[]
|
||||||
|
----
|
||||||
|
|
||||||
|
Among the configurable properties, the most relevant are:
|
||||||
|
|
||||||
|
TODO
|
|
@ -0,0 +1,36 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-module-deploy]]
|
||||||
|
==== Module `deploy`
|
||||||
|
|
||||||
|
The `deploy` module provides the deployment feature through a `DeploymentManager` component that watches a directory for changes (see xref:og-deploy[how to deploy web applications] for more information).
|
||||||
|
|
||||||
|
Files or directories added in this monitored directory cause the `DeploymentManager` to deploy them as web applications; updating files already existing in this monitored directory cause the `DeploymentManager` to re-deploy the correspondent web application; removing files in this monitored directory cause the `DeploymentManager` to undeploy the correspondent web application (see also xref:og-deploy-rules[here] for more information).
|
||||||
|
|
||||||
|
The module file is `$JETTY_HOME/modules/deploy.mod`:
|
||||||
|
|
||||||
|
----
|
||||||
|
include::{JETTY_HOME}/modules/deploy.mod[]
|
||||||
|
----
|
||||||
|
|
||||||
|
Among the configurable properties, the most relevant are:
|
||||||
|
|
||||||
|
* `jetty.deploy.monitoredDir`, to change the name of the monitored directory.
|
||||||
|
* `jetty.deploy.scanInterval`, to change the scan period, that is how frequently the `DeploymentManager` wakes up to scan the monitored directory for changes.
|
||||||
|
Setting `jetty.deploy.scanInterval=0` disabled _hot_ deployment so that only static deployment will be possible (see also xref:og-deploy-hot-static[here] for more information).
|
|
@ -0,0 +1,64 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-module-http]]
|
||||||
|
==== Module `http`
|
||||||
|
|
||||||
|
The `http` module provides support for the clear-text HTTP/1.1 protocol and depends on the xref:og-module-server[`server` module].
|
||||||
|
|
||||||
|
The module file is `$JETTY_HOME/modules/http.mod`:
|
||||||
|
|
||||||
|
----
|
||||||
|
include::{JETTY_HOME}/modules/http.mod[]
|
||||||
|
----
|
||||||
|
|
||||||
|
Among the configurable properties, the most relevant are:
|
||||||
|
|
||||||
|
* `jetty.http.port`, default `8080`, is the network port that Jetty listens to for clear-text HTTP/1.1 connections.
|
||||||
|
* `jetty.http.idleTimeout`, default `30` seconds, is the amount of time a connection can be idle (i.e. no bytes received and no bytes sent) until the server decides to close it to save resources.
|
||||||
|
* `jetty.http.acceptors`, default -1 (i.e. an accept heuristic decides the value based on the number of cores), is the number of threads that compete to accept connections.
|
||||||
|
* `jetty.http.selectors`, default -1 (i.e. a select heuristic decides the value based on the number of cores), is the number of NIO selectors (with an associated thread) that manage connections.
|
||||||
|
|
||||||
|
[[og-module-http-acceptors]]
|
||||||
|
===== Configuration of Acceptors
|
||||||
|
|
||||||
|
Accepting connections is a blocking operation, so a thread is blocked in the `accept()` call until a connection is accepted, and other threads are blocked on the lock acquired just before the `accept()` call.
|
||||||
|
|
||||||
|
When the accepting thread accepts a connection, it performs a little processing of the just accepted connection, before forwarding it to other components.
|
||||||
|
|
||||||
|
During this little processing other connections may be established; if there is only one accepting thread, the newly established connections are waiting for the accepting thread to finish the processing of the previously accepted connection and call again `accept()`.
|
||||||
|
|
||||||
|
Servers that manage a very high number of connections that may (naturally) come and go, or that handle inefficient protocols that open and close connections very frequently (such as HTTP/1.0) may benefit of an increased number of acceptor threads.
|
||||||
|
|
||||||
|
// TODO: expand on acceptors=0 and non-blocking accepts
|
||||||
|
|
||||||
|
[[og-module-http-selectors]]
|
||||||
|
===== Configuration of Selectors
|
||||||
|
|
||||||
|
Performing a NIO `select()` call is a blocking operation, where the selecting thread is blocked in the `select()` call until at least one connection is ready to be processed for an I/O operation.
|
||||||
|
There are 4 I/O operations: ready to be accepted, ready to be connected, ready to be read and ready to be written.
|
||||||
|
|
||||||
|
A single NIO selector can manage thousands of connections, with the assumption that not many of them will be ready at the same time.
|
||||||
|
|
||||||
|
For a single NIO selector, the ratio between the average number of selected connections over the total number of connections for every `select()` call depends heavily on the protocol but also on the application.
|
||||||
|
|
||||||
|
Multiplexed protocols such as HTTP/2 tend to be busier than duplex protocols such as HTTP/1.1, leading to a higher ratio.
|
||||||
|
|
||||||
|
REST applications that exchange many little JSON messages tend to be busier than file server applications, leading to a higher ratio.
|
||||||
|
|
||||||
|
The higher the ratio, the higher the number of selectors you want to have, compatibly with the number of cores -- there is no point in having 64 selector threads on a single core hardware.
|
|
@ -0,0 +1,28 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-module-https]]
|
||||||
|
==== Module `https`
|
||||||
|
|
||||||
|
The `https` module provides the HTTP/1.1 protocol to the xref:og-module-ssl[`ssl` module].
|
||||||
|
|
||||||
|
The module file is `$JETTY_HOME/modules/https.mod`:
|
||||||
|
|
||||||
|
----
|
||||||
|
include::{JETTY_HOME}/modules/https.mod[]
|
||||||
|
----
|
|
@ -0,0 +1,36 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-module-server]]
|
||||||
|
==== Module `server`
|
||||||
|
|
||||||
|
The `server` module provides generic server support, and configures generic HTTP properties that apply to all HTTP protocols, the scheduler properties and the server specific properties.
|
||||||
|
|
||||||
|
The `server` module depends on the xref:og-module-threadpool[`threadpool` module], the xref:og-module-bytebufferpool[`bytebufferpool` module] and the xref:og-module-logging[`logging` module].
|
||||||
|
|
||||||
|
The module file is `$JETTY_HOME/modules/server.mod`:
|
||||||
|
|
||||||
|
----
|
||||||
|
include::{JETTY_HOME}/modules/server.mod[]
|
||||||
|
----
|
||||||
|
|
||||||
|
Among the configurable properties, the most relevant are:
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
// TODO: consider extracting the httpConfig and scheduler properties into separate files.
|
|
@ -0,0 +1,32 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-module-ssl]]
|
||||||
|
==== Module `ssl`
|
||||||
|
|
||||||
|
The `ssl` module provides the secure connector, and allows you to configure the keystore properties and the TLS parameters.
|
||||||
|
|
||||||
|
The module file is `$JETTY_HOME/modules/ssl.mod`:
|
||||||
|
|
||||||
|
----
|
||||||
|
include::{JETTY_HOME}/modules/ssl.mod[]
|
||||||
|
----
|
||||||
|
|
||||||
|
Among the configurable properties, the most relevant are:
|
||||||
|
|
||||||
|
TODO
|
|
@ -0,0 +1,31 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-module-test-keystore]]
|
||||||
|
==== Module `test-keystore`
|
||||||
|
|
||||||
|
The `test-keystore` module provides a keystore containing a self-signed certificate for domain `localhost`.
|
||||||
|
|
||||||
|
The module file is `$JETTY_HOME/modules/test-keystore.mod`:
|
||||||
|
|
||||||
|
----
|
||||||
|
include::{JETTY_HOME}/modules/test-keystore.mod[]
|
||||||
|
----
|
||||||
|
|
||||||
|
Note how properties `jetty.sslContext.keyStorePath` and `jetty.sslContext.keyStorePassword` are configured, only if not already set (via the `?=` operator), directly in the module file, rather than in a `+*.ini+` file.
|
||||||
|
This is done to avoid that these properties accidentally overwrite a real keystore configuration.
|
|
@ -0,0 +1,34 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-module-threadpool]]
|
||||||
|
==== Module `threadpool`
|
||||||
|
|
||||||
|
The `threadpool` module allows you to configure the server-wide thread pool.
|
||||||
|
|
||||||
|
// TODO: thread pool per connector should be documented here?
|
||||||
|
|
||||||
|
The module file is `$JETTY_HOME/modules/threadpool.mod`:
|
||||||
|
|
||||||
|
----
|
||||||
|
include::{JETTY_HOME}/modules/threadpool.mod[]
|
||||||
|
----
|
||||||
|
|
||||||
|
Among the configurable properties, the most relevant are:
|
||||||
|
|
||||||
|
TODO
|
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-modules]]
|
||||||
|
==== Jetty Modules
|
||||||
|
|
||||||
|
TODO
|
||||||
|
// Consider:
|
||||||
|
// * old_docs/gettingstarted/configuring/*.adoc
|
||||||
|
// * old_docs/startup/startup-modules.adoc
|
||||||
|
// * old_docs/startup/custom-modules.adoc
|
||||||
|
//
|
|
@ -22,8 +22,6 @@
|
||||||
This chapter discusses various options for configuring Jetty contexts.
|
This chapter discusses various options for configuring Jetty contexts.
|
||||||
|
|
||||||
include::setting-context-path.adoc[]
|
include::setting-context-path.adoc[]
|
||||||
include::configuring-virtual-hosts.adoc[]
|
|
||||||
include::temporary-directories.adoc[]
|
include::temporary-directories.adoc[]
|
||||||
include::serving-webapp-from-particular-port.adoc[]
|
|
||||||
include::custom-error-pages.adoc[]
|
include::custom-error-pages.adoc[]
|
||||||
include::setting-form-size.adoc[]
|
include::setting-form-size.adoc[]
|
||||||
|
|
|
@ -1,216 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under
|
|
||||||
// the terms of the Eclipse Public License 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0
|
|
||||||
//
|
|
||||||
// This Source Code may also be made available under the following
|
|
||||||
// Secondary Licenses when the conditions for such availability set
|
|
||||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
|
||||||
// the Apache License v2.0 which is available at
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
[[configuring-virtual-hosts]]
|
|
||||||
=== Configuring Virtual Hosts
|
|
||||||
|
|
||||||
A virtual host is an alternative name, registered in DNS, for an IP address such that multiple domain names will resolve to the same IP of a shared server instance.
|
|
||||||
If the content to be served to the aliases names is link:#different-virtual-hosts-different-contexts[different], then a virtual host needs to be configured for each deployed link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html[context] to indicate which names a context will respond to.
|
|
||||||
|
|
||||||
Virtual hosts are set on a link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html[context] by calling the link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html#setVirtualHosts-java.lang.String:A-[`setVirtualHosts`] or link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html#addVirtualHosts-java.lang.String:A-[`addVirtualHost`] method which can be done in several ways:
|
|
||||||
|
|
||||||
* Using a link:#deployable-descriptor-file[context XML] file in the webapps directory (see the example in link:{GITBROWSEURL}/tests/test-webapps/test-jetty-webapp/src/main/config/demo-base/webapps/test.xml[test.xml] in the Jetty distribution).
|
|
||||||
* Creating a link:#deployment-architecture[custom deployer] with a binding to configure virtual hosts for all contexts found in the same `webapps` directory.
|
|
||||||
* Calling the link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html#setVirtualHosts-java.lang.String:A-[API] directly on an link:#advanced-embedding[embedded] usage.
|
|
||||||
* Using a `WEB-INF/jetty-web.xml` file (now deprecated).
|
|
||||||
|
|
||||||
[[configuring-a-virtual-host]]
|
|
||||||
==== Virtual Host Names
|
|
||||||
|
|
||||||
Jetty supports the following styles of virtual host name:
|
|
||||||
|
|
||||||
www.hostname.com::
|
|
||||||
A fully qualified host name. It is important to list all variants as a site may receive traffic from both www.hostname.com and just hostname.com
|
|
||||||
*.hostname.com::
|
|
||||||
A wildcard qualified host which will match only one level of arbitrary names.
|
|
||||||
*.foo.com will match www.foo.com and m.foo.com, but not www.other.foo.com
|
|
||||||
10.0.0.2::
|
|
||||||
An IP address may be given as a virtual host name to indicate that a context should handle requests received on that server port that do not have a host name specified (HTTP/0.9 or HTTP/1.0).
|
|
||||||
@ConnectorName::
|
|
||||||
A connector name, which is not strictly a virtual host, but instead will only match requests that are received on connectors that have a matching name set with link:{JDURL}/org/eclipse/jetty/server/AbstractConnector.html#setName(java.lang.String)[Connector.setName(String)].
|
|
||||||
www.√integral.com::
|
|
||||||
Non-ASCII and http://en.wikipedia.org/wiki/Internationalized_domain_name[IDN] domain names can be set as virtual hosts using http://en.wikipedia.org/wiki/Punycode[Puny Code] equivalents that may be obtained from a http://network-tools.com/idn-convert.asp[Punycode/IDN converters].
|
|
||||||
For example if the non-ASCII domain name `www.√integral.com` is given to a browser, then it will make a request that uses the domain name `www.xn--integral-7g7d.com`, which is the name that should be added as the virtual host name.
|
|
||||||
|
|
||||||
==== Example Virtual Host Configuration
|
|
||||||
|
|
||||||
Virtual hosts can be used with any context that is a subclass of link:{JDURL}/org/eclipse/jetty/server/handler/ContextHandler.html[ContextHandler].
|
|
||||||
Lets look at an example where we configure a web application - represented by the link:{JDURL}/org/eclipse/jetty/webapp/WebAppContext.html[WebAppContext] class - with virtual hosts.
|
|
||||||
You supply a list of IP addresses and names at which the web application is reachable, such as the following:
|
|
||||||
|
|
||||||
* `333.444.555.666`
|
|
||||||
* `127.0.0.1`
|
|
||||||
* `www.blah.com`
|
|
||||||
* `www.blah.net`
|
|
||||||
* `www.blah.org`
|
|
||||||
|
|
||||||
Suppose you have a webapp called `blah.war`, that you want all of the above names and addresses to be served at path "`/blah`".
|
|
||||||
Here's how you would configure the virtual hosts with a link:#deployable-descriptor-file[context XML] file:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
|
||||||
----
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd">
|
|
||||||
|
|
||||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
|
||||||
<Set name="contextPath">/blah</Set>
|
|
||||||
<Set name="war"><Property name="jetty.webapps"/>blah.war</Set>
|
|
||||||
<Set name="virtualHosts">
|
|
||||||
<Array type="java.lang.String">
|
|
||||||
<Item>333.444.555.666</Item>
|
|
||||||
<Item>127.0.0.1</Item>
|
|
||||||
<Item>www.blah.com</Item>
|
|
||||||
<Item>www.blah.net</Item>
|
|
||||||
<Item>www.blah.org</Item>
|
|
||||||
</Array>
|
|
||||||
</Set>
|
|
||||||
</Configure>
|
|
||||||
----
|
|
||||||
|
|
||||||
[[different-virtual-hosts-different-contexts]]
|
|
||||||
==== Using Different Sets of Virtual Hosts to Select Different Contexts
|
|
||||||
|
|
||||||
You can configure different contexts to respond on different virtual hosts by supplying a specific list of virtual hosts for each one.
|
|
||||||
|
|
||||||
For example, suppose your imaginary machine has these DNS names:
|
|
||||||
|
|
||||||
* `www.blah.com`
|
|
||||||
* `www.blah.net`
|
|
||||||
* `www.blah.org`
|
|
||||||
* `www.other.com`
|
|
||||||
* `www.other.net`
|
|
||||||
* `www.other.org`
|
|
||||||
|
|
||||||
Suppose also you have 2 webapps, one called `blah.war` that you would like served from the `*.blah.*` names, and one called `other.war` that you want served only from the `*.other.*` names.
|
|
||||||
|
|
||||||
Using the method of preparing link:#deployable-descriptor-file[contextXML] files, one for each webapp yields the following:
|
|
||||||
|
|
||||||
For `blah` webapp:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
|
||||||
----
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd">
|
|
||||||
|
|
||||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
|
||||||
<Set name="contextPath">/blah</Set>
|
|
||||||
<Set name="war"><Property name="jetty.webapps"/>/blah.war</Set>
|
|
||||||
<Set name="virtualHosts">
|
|
||||||
<Array type="java.lang.String">
|
|
||||||
<Item>www.blah.com</Item>
|
|
||||||
<Item>www.blah.net</Item>
|
|
||||||
<Item>www.blah.org</Item>
|
|
||||||
</Array>
|
|
||||||
</Set>
|
|
||||||
</Configure>
|
|
||||||
----
|
|
||||||
|
|
||||||
These URLs now resolve to the blah context (ie `blah.war`):
|
|
||||||
|
|
||||||
* `http://www.blah.com/blah`
|
|
||||||
* `http://www.blah.net/blah`
|
|
||||||
* `http://www.blah.org/blah`
|
|
||||||
|
|
||||||
For `other` webapp:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
|
||||||
----
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd">
|
|
||||||
|
|
||||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
|
||||||
<Set name="contextPath">/other</Set>
|
|
||||||
<Set name="war"><Property name="jetty.webapps"/>/other.war</Set>
|
|
||||||
<Set name="virtualHosts">
|
|
||||||
<Array type="java.lang.String">
|
|
||||||
<Item>www.other.com</Item>
|
|
||||||
<Item>www.other.net</Item>
|
|
||||||
<Item>www.other.org</Item>
|
|
||||||
</Array>
|
|
||||||
</Set>
|
|
||||||
</Configure>
|
|
||||||
----
|
|
||||||
|
|
||||||
These URLs now resolve to the other context (i.e. `other.war`):
|
|
||||||
|
|
||||||
* `http://www.other.com/other`
|
|
||||||
* `http://www.other.net/other`
|
|
||||||
* `http://www.other.org/other`
|
|
||||||
|
|
||||||
[[different-virtual-hosts-different-context-same-path]]
|
|
||||||
==== Using Different Sets of Virtual Hosts to Select Different Contexts at the Same Context Path
|
|
||||||
|
|
||||||
In the previous section we setup 2 different contexts to be served from different virtual hosts at _different_ context paths.
|
|
||||||
However, there is no requirement that the context paths must be distinct: you may use the same context path for multiple contexts, and use virtual hosts to determine which one is served for a given request.
|
|
||||||
|
|
||||||
Consider an example where we have the same set of DNS names as before, and the same webapps `blah.war` and `other.war`. We still want `blah.war` to be served in response to hostnames of `*.blah.*`, and we still want `other.war` to be served in response to `*.other.*` names.
|
|
||||||
However, we would like__all__ of our clients to use the `"/"` context path, no matter which context is being targeted.
|
|
||||||
|
|
||||||
In other words, we want all of the following URLs to map to `blah.war`:
|
|
||||||
|
|
||||||
* `http://www.blah.com/`
|
|
||||||
* `http://www.blah.net/`
|
|
||||||
* `http://www.blah.org/`
|
|
||||||
|
|
||||||
Similarly, we want the following URLs to map to `other.war`:
|
|
||||||
|
|
||||||
* `http://www.other.com/`
|
|
||||||
* `http://www.other.net/`
|
|
||||||
* `http://www.other.org/`
|
|
||||||
|
|
||||||
To achieve this, we simply use the same context path of `/` for each of our webapps, while still applying our different set of virtual host names.
|
|
||||||
|
|
||||||
For foo webapp:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
|
||||||
----
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd">
|
|
||||||
|
|
||||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
|
||||||
<Set name="contextPath">/</Set>
|
|
||||||
<Set name="war"><Property name="jetty.webapps"/>/foo.war</Set>
|
|
||||||
<Set name="virtualHosts">
|
|
||||||
<Array type="java.lang.String">
|
|
||||||
<Item>www.blah.com</Item>
|
|
||||||
<Item>www.blah.net</Item>
|
|
||||||
<Item>www.blah.org</Item>
|
|
||||||
</Array>
|
|
||||||
</Set>
|
|
||||||
</Configure>
|
|
||||||
----
|
|
||||||
|
|
||||||
For bar webapp:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
|
||||||
----
|
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd">
|
|
||||||
|
|
||||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
|
||||||
<Set name="contextPath">/</Set>
|
|
||||||
<Set name="war"><Property name="jetty.webapps"/>/bar.war</Set>
|
|
||||||
<Set name="virtualHosts">
|
|
||||||
<Array type="java.lang.String">
|
|
||||||
<Item>www.other.com</Item>
|
|
||||||
<Item>www.other.net</Item>
|
|
||||||
<Item>www.other.org</Item>
|
|
||||||
</Array>
|
|
||||||
</Set>
|
|
||||||
</Configure>
|
|
||||||
----
|
|
|
@ -1,74 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under
|
|
||||||
// the terms of the Eclipse Public License 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0
|
|
||||||
//
|
|
||||||
// This Source Code may also be made available under the following
|
|
||||||
// Secondary Licenses when the conditions for such availability set
|
|
||||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
|
||||||
// the Apache License v2.0 which is available at
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
[[serving-webapp-from-particular-port]]
|
|
||||||
=== Serving a WebApp from a Particular Port/Connector
|
|
||||||
|
|
||||||
Sometimes it is required to serve different web applications from different ports/connectors.
|
|
||||||
The simplest way to do this is to create multiple `Server` instances.
|
|
||||||
However, if contexts need to share resources (eg data sources, authentication), or if the mapping of ports to web applications is not cleanly divided, then the named connector mechanism can be used.
|
|
||||||
|
|
||||||
[[creating-server-instances]]
|
|
||||||
==== Creating Multiple Server Instances
|
|
||||||
|
|
||||||
Creating multiple server instances is a straight forward process that includes embedding Jetty code by creating multiples instances of the Server class and configuring them as needed.
|
|
||||||
This is also easy to achieve if you are configuring Jetty servers via XML.
|
|
||||||
The `id` field in the Configure element of `jetty.xml` files is used to identify the instance that the configuration applies to, so to run two instances of the Server, you can copy the `jetty.xml`, jetty-http.xml and other jetty configuration files used and change the "Server" id to a new name.
|
|
||||||
This can be done in the same style and layout as the existing `jetty.xml` files or the multiple XML files may be combined to a single file.
|
|
||||||
|
|
||||||
When creating new configurations for alternative server:
|
|
||||||
|
|
||||||
* Change all `id="Server"` to the new server name:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
|
||||||
----
|
|
||||||
<Configure id="OtherServer" class="org.eclipse.jetty.server.Server">
|
|
||||||
----
|
|
||||||
|
|
||||||
* For all connectors for the new server change the `refid` in the server argument:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
|
||||||
----
|
|
||||||
<Arg name="server"><Ref refid="OtherServer" /></Arg>
|
|
||||||
----
|
|
||||||
|
|
||||||
* Make sure that any references to properties like `jetty.http.port` are either renamed or replaced with absolute values.
|
|
||||||
* Make sure that any deployers `AppProviders` refer to a different "webapps" directory so that a different set of applications are deployed.
|
|
||||||
|
|
||||||
[[jetty-otherserver.xml]]
|
|
||||||
===== Example Other Server XML
|
|
||||||
|
|
||||||
The following example creates another server instance and configures it with a connector and deployer:
|
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
|
||||||
----
|
|
||||||
include::{SRCDIR}/examples/embedded/src/main/resources/jetty-otherserver.xml[]
|
|
||||||
----
|
|
||||||
|
|
||||||
To run the other server, add the extra configuration file(s) to the command line:
|
|
||||||
|
|
||||||
[source, screen, subs="{sub-order}"]
|
|
||||||
----
|
|
||||||
java -jar start.jar jetty-otherserver.xml
|
|
||||||
----
|
|
||||||
|
|
||||||
[[alternative]]
|
|
||||||
==== Named Connectors
|
|
||||||
|
|
||||||
It is also possible to use an extension to the virtual host mechanism with named to connectors to make some web applications only accessible by specific connectors.
|
|
||||||
If a connector has a name "MyConnector" set using the `setName` method, then this can be referenced with the special virtual host name "@MyConnector".
|
|
|
@ -1,42 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under
|
|
||||||
// the terms of the Eclipse Public License 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0
|
|
||||||
//
|
|
||||||
// This Source Code may also be made available under the following
|
|
||||||
// Secondary Licenses when the conditions for such availability set
|
|
||||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
|
||||||
// the Apache License v2.0 which is available at
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
[[anatomy-of-a-webapp]]
|
|
||||||
=== Anatomy of a Web Application
|
|
||||||
|
|
||||||
The standard Jetty distribution is capable of deploying standard Servlet Spec Web Applications and Jetty internal ContextHandler deployment descriptors, or even a mix of the two.
|
|
||||||
|
|
||||||
Web Applications are deployable collections of dynamic (servlets, filters, jsps, etc..) and static content, support libraries, and descriptive metadata that are bound to a specific context path on Jetty.
|
|
||||||
|
|
||||||
Ultimately the format and layout are defined by the Servlet Spec, and the official Servlet Spec documentation should be consulted for a more detailed understanding of Web Application layout and structure; however, this will outline basics about how Jetty views these requirements.
|
|
||||||
|
|
||||||
Web Applications can be bundled into a single Web Archive (WAR file) or as a directory tree.
|
|
||||||
|
|
||||||
`/WEB-INF/`::
|
|
||||||
Special Servlet API defined directory used to store anything related to the Web Application that are not part of the public access of the Web Application.
|
|
||||||
If there is content that is accessed by a Web Application internally, but that should also never be accessed directly by a web browser, this is the directory it would placed in.
|
|
||||||
|
|
||||||
`/WEB-INF/web.xml`::
|
|
||||||
*Required* deployment descriptor defining various behavior of the Web Application.
|
|
||||||
|
|
||||||
`/WEB-INF/classes/`::
|
|
||||||
Location for Web Application specific compiled java classes
|
|
||||||
`/WEB-INF/lib/`::
|
|
||||||
Directory for JAR files (libraries)
|
|
||||||
|
|
||||||
The Jetty internal `WebAppClassloader` will load classes from `/WEB-INF/classes/` first, then from jar files found in `/WEB-INF/lib/`.
|
|
|
@ -1,42 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under
|
|
||||||
// the terms of the Eclipse Public License 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0
|
|
||||||
//
|
|
||||||
// This Source Code may also be made available under the following
|
|
||||||
// Secondary Licenses when the conditions for such availability set
|
|
||||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
|
||||||
// the Apache License v2.0 which is available at
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
[[automatic-webapp-deployment]]
|
|
||||||
=== Automatic Web Application Deployment
|
|
||||||
|
|
||||||
The most basic technique for deploying Web Applications is to put a WAR file or Exploded WAR directory into the `${jetty.base}/webapps/` directory and let Jetty's deployment scanner find it and deploy it under a Context path of the same name.
|
|
||||||
|
|
||||||
Only Web Applications that follow the Web Application Layout will be detected by Jetty and deployed this way.
|
|
||||||
|
|
||||||
The Context Path assigned to this automatic deployment is based the filename (or directory name) of the WAR.
|
|
||||||
|
|
||||||
[cols=",",options="header",]
|
|
||||||
|=======================================================================
|
|
||||||
|File or Directory Name |Assigned Context Path
|
|
||||||
|`/webapps/footrope.war` |http://host/footrope/
|
|
||||||
|
|
||||||
|`/webapps/baggywrinkle-1.0.war` |http://host/baggywrinkle-1.0/
|
|
||||||
|
|
||||||
|`/webapps/lazaret-2.1.3-SNAPSHOT.war` |http://host/lazaret-2.1.3-SNAPSHOT/
|
|
||||||
|
|
||||||
|`/webapps/belaying-pins/WEB-INF/web.xml` |http://host/belaying-pins/
|
|
||||||
|
|
||||||
|`/webapps/root.war` _(reserved name)_ |http://host/
|
|
||||||
|
|
||||||
|`/webapps/root/WEB-INF/web.xml` _(reserved name)_ |http://host/
|
|
||||||
|=======================================================================
|
|
|
@ -23,12 +23,9 @@ This chapter discusses various ways to deploy applications with Jetty.
|
||||||
Topics range from deployment bindings to deploying third party products.
|
Topics range from deployment bindings to deploying third party products.
|
||||||
It also includes information about the Deployment Manager and WebApp Provider.
|
It also includes information about the Deployment Manager and WebApp Provider.
|
||||||
|
|
||||||
include::anatomy-of-a-webapp.adoc[]
|
|
||||||
include::automatic-webapp-deployment.adoc[]
|
|
||||||
include::configuring-specific-webapp-deployment.adoc[]
|
include::configuring-specific-webapp-deployment.adoc[]
|
||||||
include::deployment-processing-webapps.adoc[]
|
include::deployment-processing-webapps.adoc[]
|
||||||
include::static-content-deployment.adoc[]
|
include::static-content-deployment.adoc[]
|
||||||
include::hot-deployment.adoc[]
|
|
||||||
include::deployment-architecture.adoc[]
|
include::deployment-architecture.adoc[]
|
||||||
include::quickstart-webapp.adoc[]
|
include::quickstart-webapp.adoc[]
|
||||||
//include::overlay-deployer.adoc[]
|
//include::overlay-deployer.adoc[]
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under
|
|
||||||
// the terms of the Eclipse Public License 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0
|
|
||||||
//
|
|
||||||
// This Source Code may also be made available under the following
|
|
||||||
// Secondary Licenses when the conditions for such availability set
|
|
||||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
|
||||||
// the Apache License v2.0 which is available at
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
[[hot-deployment]]
|
|
||||||
=== Hot Deployment
|
|
||||||
|
|
||||||
Jetty allows for deploying an arbitrary context or web application by monitoring a directory for changes.
|
|
||||||
If a web application or a context descriptor is added to the directory, Jetty's `DeploymentManager` (DM) deploys a new context.
|
|
||||||
If a context descriptor is touched or updated, the DM stops, reconfigures, and redeploys its context.
|
|
||||||
If a context is removed, the DM stops it and removes it from the server.
|
|
||||||
|
|
||||||
This behavior can be controlled by configuring `WebAppProvider` properties.
|
|
||||||
|
|
||||||
monitoredDirName::
|
|
||||||
The directory to scan for possible deployable Web Applications (or Deployment Descriptor XML files).
|
|
||||||
scanInterval::
|
|
||||||
Number of seconds between scans of the provided `monitoredDirName`.
|
|
||||||
A value of `0` disables the continuous hot deployment scan, Web Applications will be deployed on startup only.
|
|
||||||
|
|
||||||
The default location for this configuration is in the `${jetty.home}/etc/jetty-deploy.xml` file.
|
|
||||||
To modify it as part of the Jetty distribution, first enable the `deploy` module.
|
|
||||||
Once it is enabled, you can edit these properties in either the `$JETTY_BASE/start.d/deploy.ini` or `$JETTY_BASE/start.ini` file, depending on link:#start-vs-startd[how your implementation is configured.]
|
|
||||||
|
|
||||||
[source, screen, subs="{sub-order}"]
|
|
||||||
----
|
|
||||||
<?xml version="1.0"?>
|
|
||||||
# ---------------------------------------
|
|
||||||
# Module: deploy
|
|
||||||
# Enables webapplication deployment from the webapps directory.
|
|
||||||
# ---------------------------------------
|
|
||||||
--module=deploy
|
|
||||||
|
|
||||||
# Monitored directory name (relative to $jetty.base)
|
|
||||||
# jetty.deploy.monitoredDir=webapps
|
|
||||||
# - OR -
|
|
||||||
# Monitored directory path (fully qualified)
|
|
||||||
# jetty.deploy.monitoredPath=/var/www/webapps
|
|
||||||
|
|
||||||
# Defaults Descriptor for all deployed webapps
|
|
||||||
# jetty.deploy.defaultsDescriptorPath=${jetty.base}/etc/webdefault.xml
|
|
||||||
|
|
||||||
# Monitored directory scan period (seconds)
|
|
||||||
# jetty.deploy.scanInterval=1
|
|
||||||
|
|
||||||
# Whether to extract *.war files
|
|
||||||
# jetty.deploy.extractWars=true
|
|
||||||
----
|
|
||||||
|
|
||||||
See xref:default-web-app-provider[] for more configuration details.
|
|
||||||
|
|
||||||
See also xref:deployment-architecture[] for detailed conceptual information.
|
|
|
@ -25,4 +25,3 @@ This guide covers the latter, a standalone distribution suitable for deploying w
|
||||||
include::jetty-installing.adoc[]
|
include::jetty-installing.adoc[]
|
||||||
include::jetty-running.adoc[]
|
include::jetty-running.adoc[]
|
||||||
include::jetty-common-configuration.adoc[]
|
include::jetty-common-configuration.adoc[]
|
||||||
include::jetty-deploying.adoc[]
|
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
|
||||||
//
|
|
||||||
// This program and the accompanying materials are made available under
|
|
||||||
// the terms of the Eclipse Public License 2.0 which is available at
|
|
||||||
// https://www.eclipse.org/legal/epl-2.0
|
|
||||||
//
|
|
||||||
// This Source Code may also be made available under the following
|
|
||||||
// Secondary Licenses when the conditions for such availability set
|
|
||||||
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
|
||||||
// the Apache License v2.0 which is available at
|
|
||||||
// https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
|
||||||
// ========================================================================
|
|
||||||
//
|
|
||||||
|
|
||||||
[[quickstart-deploying-webapps]]
|
|
||||||
=== Deploying Web Applications
|
|
||||||
|
|
||||||
Jetty server instances that configure the deploy module will have a web application deployer that link:#hot-deployment[hot deploys] files found in the `webapps` directory.
|
|
||||||
Standard WAR files and Jetty configuration files that are placed in the `webapps` directory are hot deployed to the server with the following conventions:
|
|
||||||
|
|
||||||
* A directory called `example/` is deployed as a standard web application if it contains a `WEB-INF/` subdirectory, otherwise it is deployed as context of static content.
|
|
||||||
The context path is `/example` (that is, `http://localhost:8080/example/`) unless the base name is ROOT (case insensitive), in which case the context path is /.
|
|
||||||
If the directory name ends with ".d" it is ignored (but may be used by explicit configuration).
|
|
||||||
* A file called `example.war` is deployed as a standard web application with the context path `/example` (that is,
|
|
||||||
`http://localhost:8080/example/`).
|
|
||||||
If the base name is `ROOT` (case insensitive), the context path is `/`.
|
|
||||||
If `example.war` and `example/` exist, only the WAR is deployed (which may use the directory as an unpack location).
|
|
||||||
* An XML file like `example.xml` is deployed as a context whose configuration is defined by the XML.
|
|
||||||
The configuration itself must set the context path.
|
|
||||||
If `example.xml` and `example.war` exists, only the XML is deployed (which may use the WAR in its configuration).
|
|
||||||
|
|
||||||
If you have a standard web application, you can hot deploy it into Jetty by copying it into the `webapps` directory.
|
|
||||||
|
|
||||||
==== Jetty Demonstration Web Applications
|
|
||||||
|
|
||||||
The demo-base/webapps directory contains the following deployable and auxiliary files:
|
|
||||||
|
|
||||||
`ROOT/`::
|
|
||||||
A directory of static content that is deployed to the root context / due to it's name.
|
|
||||||
Contains the Jetty demo welcome page.
|
|
||||||
`test.d`::
|
|
||||||
A directory containing additional configuration files used by `test.xml` to inject extra configuration into `test.war`.
|
|
||||||
`test.xml`::
|
|
||||||
A context configuration file that configures and deploys `test.war.`
|
|
||||||
The additional configuration includes the context path as well as setting additional descriptors found in the `test.d` directory.
|
|
||||||
`test.war`::
|
|
||||||
The demonstration web application that is configured and deployed by `test.xml`.
|
|
||||||
`async-rest.war`::
|
|
||||||
A web application demonstration of asynchronous REST to eBay, automatically deployed to /async-rest based on the file name.
|
|
||||||
`test-jaas.war`::
|
|
||||||
A demonstration web application utilizing link:#jaas-support[JAAS] for authentication.
|
|
||||||
`test-jaas.xml`::
|
|
||||||
A context configuration file that configures `test-jaas.war`.
|
|
||||||
Additional configuration includes setting up the link:#configuring-login-service[LoginService] for authentication and authorization.
|
|
||||||
`test-jndi.war`::
|
|
||||||
A demonstration web application showing the use of link:#jndi[JNDI].
|
|
||||||
`test-jndi.xml`::
|
|
||||||
A context configuration file that configures `test-jndi.war`.
|
|
||||||
Additional configuration includes defining objects in the naming space that can be referenced from the webapp.
|
|
||||||
`test-spec.war`::
|
|
||||||
A demonstration web application that shows the use of annotations, fragments, `ServletContainerInitializers` and other Servlet Specification 3.0/3.1 features.
|
|
||||||
`test-spec.xml`::
|
|
||||||
A context configuration file that configures `test-spec.war`.
|
|
||||||
Additional configuration includes setting up some objects in the naming space that can be referenced by annotations.
|
|
||||||
`javadoc-proxy.war`::
|
|
||||||
A demonstration web application that uses a transparent proxy to serve the Jetty source link:{JDURL}/[Javadoc] from the http://www.eclipse.org/jetty[Eclipse Jetty website].
|
|
||||||
`example-moved.xml`::
|
|
||||||
A demonstration context configuration file that shows how to use the link:#moved-context-handler[`MovedContextHandler`] to redirect from one path to another.
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-protocols]]
|
||||||
|
=== Configuring Eclipse Jetty Connectors and Protocols
|
||||||
|
|
||||||
|
Connectors are the network components through which Jetty accepts incoming network connections.
|
||||||
|
|
||||||
|
Each connector listens on a network port and can be configured with `ConnectionFactory` components that _understand_ one or more network protocols.
|
||||||
|
|
||||||
|
Understanding a protocol means that the connector is able to interpret incoming network bytes (for example, the bytes that represent an HTTP/1.1 request) and convert them into more abstract objects (for example an `HttpServletRequest` object) that are then processed by applications.
|
||||||
|
Conversely, an abstract object (for example an `HttpServletResponse`) is converted into the correspondent outgoing network bytes (the bytes that represent an HTTP/1.1 response).
|
||||||
|
|
||||||
|
Like other Jetty components, connectors are enabled and configured by enabling and configuring the correspondent Jetty module.
|
||||||
|
|
||||||
|
IMPORTANT: Recall that you must always issue the commands to enable Jetty modules from within the `$JETTY_BASE` directory, and that the Jetty module configuration files are in the `$JETTY_BASE/start.d/` directory.
|
||||||
|
|
||||||
|
You can obtain the list of connector-related modules in this way:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar --list-modules=connector
|
||||||
|
----
|
||||||
|
|
||||||
|
include::protocols-http.adoc[]
|
||||||
|
include::protocols-https.adoc[]
|
||||||
|
include::protocols-ssl.adoc[]
|
||||||
|
|
||||||
|
// TODO: old_docs/connectors/*.adoc
|
|
@ -0,0 +1,77 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-protocols-http]]
|
||||||
|
==== Configuring Clear-Text HTTP/1.1
|
||||||
|
|
||||||
|
Clear text HTTP/1.1 is enabled with the `http` Jetty module with the following command (issued from within the `$JETTY_BASE` directory):
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar --add-module=http
|
||||||
|
----
|
||||||
|
----
|
||||||
|
INFO : mkdir ${jetty.base}/start.d
|
||||||
|
INFO : server transitively enabled, ini template available with --add-module=server
|
||||||
|
INFO : logging-jetty transitively enabled
|
||||||
|
INFO : http initialized in ${jetty.base}/start.d/http.ini
|
||||||
|
INFO : resources transitively enabled
|
||||||
|
INFO : threadpool transitively enabled, ini template available with --add-module=threadpool
|
||||||
|
INFO : logging/slf4j dynamic dependency of logging-jetty
|
||||||
|
INFO : bytebufferpool transitively enabled, ini template available with --add-module=bytebufferpool
|
||||||
|
INFO : mkdir ${jetty.base}/resources
|
||||||
|
INFO : copy ${jetty.home}/modules/logging/jetty/resources/jetty-logging.properties to ${jetty.base}/resources/jetty-logging.properties
|
||||||
|
INFO : Base directory was modified
|
||||||
|
----
|
||||||
|
|
||||||
|
After having enabled the `http` module, the `$JETTY_BASE` directory looks like this:
|
||||||
|
|
||||||
|
[source,subs=quotes]
|
||||||
|
----
|
||||||
|
JETTY_BASE
|
||||||
|
├── resources
|
||||||
|
│ └── jetty-logging.properties
|
||||||
|
└── start.d
|
||||||
|
└── #http.ini#
|
||||||
|
----
|
||||||
|
|
||||||
|
The `http.ini` file is the file that you want to edit to configure network and protocol parameters -- for more details see xref:og-module-http[this section].
|
||||||
|
|
||||||
|
Note that the `http` Jetty module depends on the `server` Jetty module.
|
||||||
|
|
||||||
|
Some parameters that you may want to configure are in fact common HTTP parameters that are applied not only for clear-text HTTP/1.1, but also for secure HTTP/1.1 or for clear-text HTTP/2 or for encrypted HTTP/2, and these configuration parameters may be present in the `server` module configuration file.
|
||||||
|
|
||||||
|
You can force the creation of the `server.ini` file via:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar --add-module=server
|
||||||
|
----
|
||||||
|
|
||||||
|
Now the `$JETTY_BASE` directory looks like this:
|
||||||
|
|
||||||
|
[source,subs=quotes]
|
||||||
|
----
|
||||||
|
JETTY_BASE
|
||||||
|
├── resources
|
||||||
|
│ └── jetty-logging.properties
|
||||||
|
└── start.d
|
||||||
|
├── http.ini
|
||||||
|
└── server.ini
|
||||||
|
----
|
||||||
|
|
||||||
|
Now you can edit the `server.ini` file -- for more details see xref:og-module-server[this section].
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-protocols-https]]
|
||||||
|
==== Configuring Secure HTTP/1.1
|
||||||
|
|
||||||
|
Secure HTTP/1.1 is enabled with both the `ssl` and `https` Jetty modules with the following command (issued from within the `$JETTY_BASE` directory):
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar --add-modules=ssl,https
|
||||||
|
----
|
||||||
|
----
|
||||||
|
INFO : mkdir ${jetty.base}/start.d
|
||||||
|
INFO : server transitively enabled, ini template available with --add-module=server
|
||||||
|
INFO : logging-jetty transitively enabled
|
||||||
|
INFO : resources transitively enabled
|
||||||
|
INFO : https initialized in ${jetty.base}/start.d/https.ini
|
||||||
|
INFO : ssl initialized in ${jetty.base}/start.d/ssl.ini
|
||||||
|
INFO : threadpool transitively enabled, ini template available with --add-module=threadpool
|
||||||
|
INFO : logging/slf4j transitive provider of logging/slf4j for logging-jetty
|
||||||
|
INFO : logging/slf4j dynamic dependency of logging-jetty
|
||||||
|
INFO : bytebufferpool transitively enabled, ini template available with --add-module=bytebufferpool
|
||||||
|
INFO : mkdir ${jetty.base}/resources
|
||||||
|
INFO : copy ${jetty.home}/modules/logging/jetty/resources/jetty-logging.properties to ${jetty.base}/resources/jetty-logging.properties
|
||||||
|
INFO : Base directory was modified
|
||||||
|
----
|
||||||
|
|
||||||
|
The command above enables the `ssl` module, that provides the secure network connector, the keystore configuration and TLS configuration -- for more details see xref:og-protocols-ssl[this section].
|
||||||
|
Then, the xref:og-module-https[`https` module] adds HTTP/1.1 as the protocol secured by TLS.
|
||||||
|
|
||||||
|
The `$JETTY_BASE` directory looks like this:
|
||||||
|
|
||||||
|
[source,subs=verbatim]
|
||||||
|
----
|
||||||
|
$JETTY_BASE
|
||||||
|
├── resources
|
||||||
|
│ └── jetty-logging.properties
|
||||||
|
└── start.d
|
||||||
|
├── https.ini
|
||||||
|
└── ssl.ini
|
||||||
|
----
|
||||||
|
|
||||||
|
Note that the keystore file is missing, because you have to provide one with the cryptographic material you want (read xref:og-ssl[this section] to create your own keystore).
|
||||||
|
You need to configure these two properties by editing `ssl.ini`:
|
||||||
|
|
||||||
|
* `jetty.sslContext.keyStorePath`
|
||||||
|
* `jetty.sslContext.keyStorePassword`
|
||||||
|
|
||||||
|
As a quick example, you can enable the xref:og-module-test-keystore[`test-keystore` module], that provides a keystore containing a self-signed certificate:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar --add-modules=ssl,https
|
||||||
|
----
|
||||||
|
----
|
||||||
|
INFO : test-keystore initialized in ${jetty.base}/start.d/test-keystore.ini
|
||||||
|
INFO : mkdir ${jetty.base}/etc
|
||||||
|
INFO : copy ${jetty.home}/modules/test-keystore/test-keystore.p12 to ${jetty.base}/etc/test-keystore.p12
|
||||||
|
INFO : Base directory was modified
|
||||||
|
----
|
||||||
|
|
||||||
|
The `$JETTY_BASE` directory is now:
|
||||||
|
|
||||||
|
----
|
||||||
|
├── etc
|
||||||
|
│ └── #test-keystore.p12#
|
||||||
|
├── resources
|
||||||
|
│ └── jetty-logging.properties
|
||||||
|
└── start.d
|
||||||
|
├── https.ini
|
||||||
|
├── ssl.ini
|
||||||
|
└── test-keystore.ini
|
||||||
|
----
|
||||||
|
|
||||||
|
Starting Jetty yields:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ java -jar $JETTY_HOME/start.jar
|
||||||
|
----
|
||||||
|
[source,subs=quotes]
|
||||||
|
----
|
||||||
|
2020-09-22 08:40:49.482:INFO :oejs.Server:main: jetty-10.0.0-SNAPSHOT; built: 2020-09-21T14:44:05.094Z; git: 5c33f526e5b7426dd9644ece61b10184841bb8fa; jvm 15+36-1562
|
||||||
|
2020-09-22 08:40:49.709:INFO :oejus.SslContextFactory:main: x509=X509@14cd1699(mykey,h=[localhost],w=[]) for Server@73a1e9a9[provider=null,keyStore=file:///tmp/jetty.base/etc/test-keystore.p12,trustStore=file:///tmp/jetty.base/etc/test-keystore.p12]
|
||||||
|
2020-09-22 08:40:49.816:INFO :oejs.AbstractConnector:main: Started ServerConnector@2e1d27ba##{SSL, (ssl, http/1.1)}{0.0.0.0:8443}##
|
||||||
|
2020-09-22 08:40:49.828:INFO :oejs.Server:main: Started Server@2f177a4b{STARTING}[10.0.0-SNAPSHOT,sto=5000] @814ms
|
||||||
|
----
|
||||||
|
|
||||||
|
Note how Jetty is listening on port `8443` for the secure HTTP/1.1 protocol.
|
|
@ -0,0 +1,48 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-protocols-ssl]]
|
||||||
|
==== Configuring Secure Protocols
|
||||||
|
|
||||||
|
Secure protocols are normal protocols such as HTTP/1.1 or WebSocket that are wrapped by the link:https://en.wikipedia.org/wiki/Transport_Layer_Security[TLS protocol].
|
||||||
|
Any network protocol can be wrapped with TLS.
|
||||||
|
|
||||||
|
The `https` scheme used in URIs really means `tls+http/1.1` and similarly the `wss` scheme used in URIs really means `tls+websocket`, etc.
|
||||||
|
Senders wrap the underlying protocol bytes (e.g. HTTP/1.1 bytes or WebSocket bytes) with the TLS protocol, while receivers first interpret the TLS protocol to obtain the underlying protocol bytes, and then interpret the wrapped bytes.
|
||||||
|
|
||||||
|
Secure protocols have a slightly more complicated configuration since they require to configure a _keystore_.
|
||||||
|
|
||||||
|
A keystore is a file on the file system that contains a private key and a public certificate, along with the certificate chain of the certificate authorities that issued the certificate.
|
||||||
|
The private key, the public certificate and the certificate chain, but more generally the items present in a keystore, are typically referred to as "cryptographic material".
|
||||||
|
|
||||||
|
Keystores may encode the cryptographic material with different encodings, the most common being link:https://en.wikipedia.org/wiki/PKCS_12[PKCS12], and are typically protected by a password.
|
||||||
|
|
||||||
|
After configuring the keystore path and keystore password, you may want to further customize the parameters of the TLS protocol, such as the minimum TLS protocol version, or the TLS algorithms, etc.
|
||||||
|
|
||||||
|
The Jetty `ssl` module allows you to configure the keystore and the TLS parameters; if other modules require encryption, they declare a dependency on the `ssl` module.
|
||||||
|
|
||||||
|
Since the `ssl` module is only about encryption, it does not configure a connector listening on a network port because it does not know what is the wrapped protocol.
|
||||||
|
It is the job of other Jetty modules to configure the wrapped protocol.
|
||||||
|
|
||||||
|
For example, it is the xref:og-protocols-https[`https` module] that configures the listening network port for secure HTTP/1.1.
|
||||||
|
The `https` module depends on the `ssl` module to allow the configuration of keystore and TLS, and adds HTTP/1.1 as the protocol wrapped by TLS.
|
||||||
|
|
||||||
|
Recall from the xref:og-modules[section about modules], that only modules that are explicitly enabled get their module configuration file (`+*.ini+`) saved in `$JETTY_BASE/start.d/`, and you want `$JETTY_BASE/start.d/ssl.ini` to be present so that you can configure the keystore and TLS properties.
|
||||||
|
|
||||||
|
// TODO: section about client authentication with certificates?
|
||||||
|
// See readme_keystores.txt about the fact that the server keystore needs the CA=true extension.
|
|
@ -16,21 +16,22 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[op-session]]
|
[[og-sessions]]
|
||||||
== Session Management
|
=== HTTP Session Management
|
||||||
|
http://
|
||||||
|
|
||||||
Http sessions are a concept within the Servlet API which allow requests to store and retrieve information across the time a user spends in an application.
|
HTTP sessions are a concept within the Servlet API which allow requests to store and retrieve information across the time a user spends in an application.
|
||||||
Jetty offers a number of pluggable alternatives for managing and distributing/persisting sessions.
|
Jetty offers a number of pluggable alternatives for managing and distributing/persisting sessions.
|
||||||
Choosing the best alternative is an important consideration for every application as is the correct configuration to achieve optimum performance.
|
Choosing the best alternative is an important consideration for every application as is the correct configuration to achieve optimum performance.
|
||||||
|
|
||||||
include::session-overview.adoc[]
|
include::session-overview.adoc[]
|
||||||
include::session-base.adoc[]
|
include::session-base.adoc[]
|
||||||
include::session-sessioncache.adoc[]
|
include::session-cache.adoc[]
|
||||||
include::session-filesystem.adoc[]
|
include::session-filesystem.adoc[]
|
||||||
include::session-jdbc.adoc[]
|
include::session-jdbc.adoc[]
|
||||||
include::session-mongodb.adoc[]
|
include::session-mongodb.adoc[]
|
||||||
include::session-infinispan.adoc[]
|
include::session-infinispan.adoc[]
|
||||||
include::session-hazelcast.adoc[]
|
include::session-hazelcast.adoc[]
|
||||||
include::session-gcloud.adoc[]
|
include::session-gcloud.adoc[]
|
||||||
include::session-memcachedsessiondatastore.adoc[]
|
include::session-memcached.adoc[]
|
||||||
include::session-usecases.adoc[]
|
include::session-usecases.adoc[]
|
|
@ -16,18 +16,20 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[ops-session-base]]
|
[[og-session-base]]
|
||||||
=== The Base Session Module
|
==== The Base Session Module
|
||||||
|
|
||||||
The `sessions` module is the base module that all other session modules depend upon.
|
The `sessions` module is the base module that all other session modules depend upon.
|
||||||
As such it will be _transitively_ enabled if you enable any of the other session modules: you need to _explicitly_ enable it if you wish to _change_ any settings from their defaults.
|
As such it will be _transitively_ enabled if you enable any of the other session modules: you need to _explicitly_ enable it if you wish to _change_ any settings from their defaults.
|
||||||
|
|
||||||
Enabling the `sessions` module puts the `$jetty.home/etc/sessions/id-manager.xml` file onto the execution path and generates a `$jetty.base/start.d/sessions.ini` file.
|
Enabling the `sessions` module puts the `$JETTY_HOME/etc/sessions/id-manager.xml` file onto the execution path and generates a `$JETTY_BASE/start.d/sessions.ini` file.
|
||||||
|
|
||||||
The `id-manager.xml` file instantiates a `DefaultSessionIdManager` and `HouseKeeper`.
|
The `id-manager.xml` file instantiates a `DefaultSessionIdManager` and `HouseKeeper`.
|
||||||
The former is used to generate and manage session ids whilst the latter is responsible for periodic xref:ops-session-base-scavenge[scavenging] of expired sessions.
|
The former is used to generate and manage session ids whilst the latter is responsible for periodic xref:og-session-base-scavenge[scavenging] of expired sessions.
|
||||||
|
|
||||||
==== Configuration
|
===== Configuration
|
||||||
The `$jetty.base/start.d/sessions.ini` file contains these configuration properties:
|
|
||||||
|
The `$JETTY_BASE/start.d/sessions.ini` file contains these configuration properties:
|
||||||
|
|
||||||
jetty.sessionIdManager.workerName::
|
jetty.sessionIdManager.workerName::
|
||||||
This uniquely identifies the jetty server instance and is applied to the `SessionIdManager`.
|
This uniquely identifies the jetty server instance and is applied to the `SessionIdManager`.
|
||||||
|
@ -43,17 +45,17 @@ IMPORTANT: If you have more than one Jetty instance, it is *crucial* that you co
|
||||||
|
|
||||||
jetty.sessionScavengeInterval.seconds::
|
jetty.sessionScavengeInterval.seconds::
|
||||||
This is the period in _seconds_ between runs of the `HouseKeeper`, responsible for orchestrating the removal of expired sessions.
|
This is the period in _seconds_ between runs of the `HouseKeeper`, responsible for orchestrating the removal of expired sessions.
|
||||||
By default it will run appproximately every 600 secs (ie 10 mins).
|
By default it will run approximately every 600 secs (ie 10 mins).
|
||||||
As a rule of thumb, you should ensure that the xref:ops-session-base-scavenge[scavenge] interval is shorter than the `<session-timeout>` of your sessions to ensure that they are promptly scavenged.
|
As a rule of thumb, you should ensure that the xref:og-session-base-scavenge[scavenge] interval is shorter than the `<session-timeout>` of your sessions to ensure that they are promptly scavenged.
|
||||||
On the other hand, if you have a backend store configured for your sessions, xref:ops-session-base-scavenge[scavenging] too frequently can increase the load on it.
|
On the other hand, if you have a backend store configured for your sessions, xref:og-session-base-scavenge[scavenging] too frequently can increase the load on it.
|
||||||
|
|
||||||
TIP: Don't forget that the `<session-timeout>` is specified in web.xml in _minutes_ and the value of the `jetty.sessionScavengeInterval.seconds` is in _seconds_.
|
CAUTION: Don't forget that the `<session-timeout>` is specified in `web.xml` in _minutes_ and the value of the `jetty.sessionScavengeInterval.seconds` is in _seconds_.
|
||||||
|
|
||||||
[[ops-session-base-scavenge]]
|
[[og-session-base-scavenge]]
|
||||||
==== Session Scavenging
|
===== Session Scavenging
|
||||||
|
|
||||||
The `HouseKeeper` is responsible for the periodic initiation of session scavenge cycles.
|
The `HouseKeeper` is responsible for the periodic initiation of session scavenge cycles.
|
||||||
The `jetty.sessionScavengeInterval.seconds` property in `$jetty.base/start.d/sessions.ini` controls the periodicity of the cycle.
|
The `jetty.sessionScavengeInterval.seconds` property in `$JETTY_BASE/start.d/sessions.ini` controls the periodicity of the cycle.
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
====
|
====
|
||||||
|
@ -68,7 +70,7 @@ Scavenging occurs for all contexts on a server at every cycle.
|
||||||
The `HouseKeeper` sequentially asks the `SessionHandler` in each context to find and remove expired sessions.
|
The `HouseKeeper` sequentially asks the `SessionHandler` in each context to find and remove expired sessions.
|
||||||
The `SessionHandler` works with the `SessionDataStore` to evaluate candidates for expiry held in the `SessionCache`, and also to sweep the persistence mechanism to find expired sessions.
|
The `SessionHandler` works with the `SessionDataStore` to evaluate candidates for expiry held in the `SessionCache`, and also to sweep the persistence mechanism to find expired sessions.
|
||||||
|
|
||||||
The sweep takes two forms: once per cycle the `SessionDataStore` searches for sessions for it's own context that have expired; infrequently, the `SessionDataStore` will widen the search to expired sessions in all contexts.
|
The sweep takes two forms: once per cycle the `SessionDataStore` searches for sessions for its own context that have expired; infrequently, the `SessionDataStore` will widen the search to expired sessions in all contexts.
|
||||||
The former finds sessions that are no longer in this context's `SessionCache`, and using some heuristics, are unlikely to be in the `SessionCache` of the same context on another node either.
|
The former finds sessions that are no longer in this context's `SessionCache`, and using some heuristics, are unlikely to be in the `SessionCache` of the same context on another node either.
|
||||||
These sessions will be loaded and fully expired, meaning that `HttpSessionListener.destroy()` will be called for them.
|
These sessions will be loaded and fully expired, meaning that `HttpSessionListener.destroy()` will be called for them.
|
||||||
The latter finds sessions that have not been disposed of by scavenge cycles on any other context/node.
|
The latter finds sessions that have not been disposed of by scavenge cycles on any other context/node.
|
|
@ -16,24 +16,24 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[ops-session-sessioncache]]
|
[[og-session-cache]]
|
||||||
=== Modules for Session Caching
|
==== Modules for HTTP Session Caching
|
||||||
|
|
||||||
In this section we will look at the alternatives for the `SessionCache`, ie the L1 cache of in-use session objects.
|
In this section we will look at the alternatives for the `SessionCache`, i.e. the L1 cache of in-use session objects.
|
||||||
Jetty ships with 2 alternatives: an in-memory cache, and a null cache.
|
Jetty ships with 2 alternatives: an in-memory cache, and a null cache.
|
||||||
The latter does not actually do any caching of sessions, and can be useful if you either want to minimize your support for sessions, or you are in a clustered deployment without a sticky loadbalancer.
|
The latter does not actually do any caching of sessions, and can be useful if you either want to minimize your support for sessions, or you are in a clustered deployment without a sticky loadbalancer.
|
||||||
|
|
||||||
The xref:ops-session-usecases[scenarios] go into more detail on this.
|
The xref:og-session-usecases[scenarios] go into more detail on this.
|
||||||
|
|
||||||
[[ops-session-hash]]
|
[[og-session-cache-hash]]
|
||||||
==== Caching in Memory
|
===== Caching in Memory
|
||||||
|
|
||||||
If you wish to change any of the default configuration values you should enable the `session-cache-hash` xref:startup-modules[module].
|
If you wish to change any of the default configuration values you should enable the `session-cache-hash` xref:startup-modules[module].
|
||||||
The name `"hash"` harks back to historical Jetty session implementations, whereby sessions were kept in memory using a HashMap.
|
The name `"hash"` harks back to historical Jetty session implementations, whereby sessions were kept in memory using a HashMap.
|
||||||
|
|
||||||
===== Configuration
|
====== Configuration
|
||||||
|
|
||||||
The `$jetty.base/start.d/session-cache-hash.ini` contains the following configurable properties:
|
The `$JETTY_BASE/start.d/session-cache-hash.ini` contains the following configurable properties:
|
||||||
|
|
||||||
jetty.session.evictionPolicy::
|
jetty.session.evictionPolicy::
|
||||||
Integer, default -1.
|
Integer, default -1.
|
||||||
|
@ -81,16 +81,15 @@ jetty.session.invalidateOnShutdown::
|
||||||
Boolean, default `false`.
|
Boolean, default `false`.
|
||||||
If true, when a context is shutdown, all sessions in the cache are invalidated and deleted both from the cache and from the `SessionDataStore`.
|
If true, when a context is shutdown, all sessions in the cache are invalidated and deleted both from the cache and from the `SessionDataStore`.
|
||||||
|
|
||||||
|
[[og-session-cache-null]]
|
||||||
[[ops-session-null]]
|
===== No Caching
|
||||||
==== No Caching
|
|
||||||
|
|
||||||
You may need to use the `session-cache-null` module if your clustering setup does not have a sticky load balancer, or if you want absolutely minimal support for sessions.
|
You may need to use the `session-cache-null` module if your clustering setup does not have a sticky load balancer, or if you want absolutely minimal support for sessions.
|
||||||
If you enable this module, but you don't enable a module that provides session persistence (ie one of the `session-store-xxx` modules), then sessions will _neither_ be retained in memory _nor_ persisted.
|
If you enable this module, but you don't enable a module that provides session persistence (ie one of the `session-store-xxx` modules), then sessions will _neither_ be retained in memory _nor_ persisted.
|
||||||
|
|
||||||
===== Configuration
|
====== Configuration
|
||||||
|
|
||||||
The `$jetty.base/start.d/session-cache-null.ini` contains the following configurable properties:
|
The `$JETTY_BASE/start.d/session-cache-null.ini` contains the following configurable properties:
|
||||||
|
|
||||||
jetty.session.saveOnCreate::
|
jetty.session.saveOnCreate::
|
||||||
Boolean, default `false`.
|
Boolean, default `false`.
|
|
@ -16,20 +16,19 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[ops-session-filesystem]]
|
[[og-session-filesystem]]
|
||||||
|
==== Modules for Persistent HTTP Sessions: File System
|
||||||
|
|
||||||
=== Modules for Persistent Sessions: File System
|
The `session-store-file` Jetty module supports persistent storage of session data in a filesystem.
|
||||||
|
|
||||||
The `session-store-file` module supports persistent storage of session data in a filesystem.
|
|
||||||
|
|
||||||
IMPORTANT: Persisting sessions to the local file system should *never* be used in a clustered environment.
|
IMPORTANT: Persisting sessions to the local file system should *never* be used in a clustered environment.
|
||||||
|
|
||||||
Enabling this module creates the `$jetty.base/sessions` directory.
|
Enabling this module creates the `$JETTY_BASE/sessions` directory.
|
||||||
By default session data will be saved to this directory, one file representing each session.
|
By default session data will be saved to this directory, one file representing each session.
|
||||||
|
|
||||||
File names follow this pattern:
|
File names follow this pattern:
|
||||||
|
|
||||||
+[expiry]_[contextpath]_[virtualhost]_[id]+
|
`+[expiry]_[contextpath]_[virtualhost]_[id]+`
|
||||||
|
|
||||||
expiry::
|
expiry::
|
||||||
This is the expiry time in milliseconds since the epoch.
|
This is the expiry time in milliseconds since the epoch.
|
||||||
|
@ -38,12 +37,11 @@ contextpath::
|
||||||
This is the context path with any special characters, including `/`, replaced by the `_` underscore character.
|
This is the context path with any special characters, including `/`, replaced by the `_` underscore character.
|
||||||
For example, a context path of `/catalog` would become `_catalog`.
|
For example, a context path of `/catalog` would become `_catalog`.
|
||||||
A context path of simply `/` becomes just `__`.
|
A context path of simply `/` becomes just `__`.
|
||||||
virtualhost::
|
|
||||||
This is the first virtual host associated with the context and has the form of 4 digits separated by `.` characters.
|
|
||||||
If there are no virtual hosts associated with a context, then `0.0.0.0` is used:
|
|
||||||
|
|
||||||
[digit].[digit].[digit].[digit]
|
virtualhost::
|
||||||
|
This is the first virtual host associated with the context and has the form of 4 digits separated by `.` characters: `+[digit].[digit].[digit].[digit]+`.
|
||||||
|
If there are no virtual hosts associated with a context, then `0.0.0.0` is used.
|
||||||
|
|
||||||
id::
|
id::
|
||||||
This is the unique id of the session.
|
This is the unique id of the session.
|
||||||
|
|
||||||
|
@ -51,22 +49,24 @@ Putting all of the above together as an example, a session with an id of `node0e
|
||||||
|
|
||||||
`1599558193150__test_0.0.0.0_node0ek3vx7x2y1e7pmi3z00uqj1k0`
|
`1599558193150__test_0.0.0.0_node0ek3vx7x2y1e7pmi3z00uqj1k0`
|
||||||
|
|
||||||
|
===== Configuration
|
||||||
|
|
||||||
==== Configuration
|
The `$JETTY_BASE/start.d/sessions.ini` file contains the following properties which may be modified to customise filesystem session storage:
|
||||||
|
|
||||||
The `$jetty.base/start.d/sessions.ini` file contains the following properties which may be modified to customise filesystem session storage:
|
|
||||||
|
|
||||||
jetty.session.storeDir::
|
jetty.session.storeDir::
|
||||||
The default is `${jetty.base}/sessions`.
|
The default is `$JETTY_BASE/sessions`.
|
||||||
This is a path that defines the location for storage of session files.
|
This is a path that defines the location for storage of session files.
|
||||||
|
|
||||||
jetty.session.file.deleteUnrestorableFiles::
|
jetty.session.file.deleteUnrestorableFiles::
|
||||||
Boolean, default `false`.
|
Boolean, default `false`.
|
||||||
If set to `true`, unreadable files will be deleted.
|
If set to `true`, unreadable files will be deleted.
|
||||||
This is useful to prevent repeated logging of the same error when the scavenger periodically (re-)attempts to load the corrupted information for a session in order to expire it.
|
This is useful to prevent repeated logging of the same error when the scavenger periodically (re-)attempts to load the corrupted information for a session in order to expire it.
|
||||||
|
|
||||||
jetty.session.gracePeriod.seconds::
|
jetty.session.gracePeriod.seconds::
|
||||||
Integer, default 3600.
|
Integer, default 3600.
|
||||||
Used during session xref:ops-session-base-scavenge[scavenging].
|
Used during session xref:og-session-base-scavenge[scavenging].
|
||||||
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:ops-session-base-scavenge[scavenged].
|
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:og-session-base-scavenge[scavenged].
|
||||||
|
|
||||||
jetty.session.savePeriod.seconds::
|
jetty.session.savePeriod.seconds::
|
||||||
Integer, in seconds, default is `0`.
|
Integer, in seconds, default is `0`.
|
||||||
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
||||||
|
@ -78,4 +78,4 @@ The value of this property is used to skip writes for these kinds of sessions: t
|
||||||
====
|
====
|
||||||
You should be careful in the use of this property in clustered environments: if you set too large a value for this property, the session may not be written out sufficiently often to update its `expiry` time thus making it appear to other nodes that it has expired.
|
You should be careful in the use of this property in clustered environments: if you set too large a value for this property, the session may not be written out sufficiently often to update its `expiry` time thus making it appear to other nodes that it has expired.
|
||||||
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - it would be undesirable to set a `savePeriod` that is larger than the `maxIdleTime`.
|
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - it would be undesirable to set a `savePeriod` that is larger than the `maxIdleTime`.
|
||||||
====
|
====
|
|
@ -16,15 +16,14 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[ops-session-gcloud]]
|
[[og-session-gcloud]]
|
||||||
|
==== Modules for Persistent HTTP Sessions: Google Cloud DataStore
|
||||||
=== Modules for Persistent Sessions: Google Cloud DataStore
|
|
||||||
|
|
||||||
Jetty can store http session information into GCloud by enabling the `session-store-gcloud` module.
|
Jetty can store http session information into GCloud by enabling the `session-store-gcloud` module.
|
||||||
|
|
||||||
==== Preparation
|
===== Preparation
|
||||||
|
|
||||||
You will first need to create a project and enable the Google Cloud api: https://cloud.google.com/docs/authentication#preparation.
|
You will first need to create a project and enable the Google Cloud api: link:https://cloud.google.com/docs/authentication#preparation[].
|
||||||
Take note of the project id that you create in this step as you need to supply it in later steps.
|
Take note of the project id that you create in this step as you need to supply it in later steps.
|
||||||
|
|
||||||
===== Communicating with GCloudDataStore
|
===== Communicating with GCloudDataStore
|
||||||
|
@ -34,7 +33,7 @@ Take note of the project id that you create in this step as you need to supply i
|
||||||
Before running Jetty, you will need to choose one of the following methods to set up the local environment to enable remote GCloud DataStore communications.
|
Before running Jetty, you will need to choose one of the following methods to set up the local environment to enable remote GCloud DataStore communications.
|
||||||
|
|
||||||
1. Using the GCloud SDK:
|
1. Using the GCloud SDK:
|
||||||
* Ensure you have the GCloud SDK installed: https://cloud.google.com/sdk/?hl=en.
|
* Ensure you have the GCloud SDK installed: link:https://cloud.google.com/sdk/?hl=en[]
|
||||||
* Use the GCloud tool to set up the project you created in the preparation step: `gcloud config set project PROJECT_ID`
|
* Use the GCloud tool to set up the project you created in the preparation step: `gcloud config set project PROJECT_ID`
|
||||||
* Use the GCloud tool to authenticate a google account associated with the project created in the preparation step: `gcloud auth login ACCOUNT`
|
* Use the GCloud tool to authenticate a google account associated with the project created in the preparation step: `gcloud auth login ACCOUNT`
|
||||||
|
|
||||||
|
@ -42,17 +41,16 @@ Before running Jetty, you will need to choose one of the following methods to se
|
||||||
* Define the environment variable `GCLOUD_PROJECT` with the project id you created in the preparation step.
|
* Define the environment variable `GCLOUD_PROJECT` with the project id you created in the preparation step.
|
||||||
* Generate a JSON link:https://cloud.google.com/storage/docs/authentication?hl=en#service_accounts[service account key] and then define the environment variable `GOOGLE_APPLICATION_CREDENTIALS=/path/to/my/key.json`
|
* Generate a JSON link:https://cloud.google.com/storage/docs/authentication?hl=en#service_accounts[service account key] and then define the environment variable `GOOGLE_APPLICATION_CREDENTIALS=/path/to/my/key.json`
|
||||||
|
|
||||||
|
|
||||||
====== When Running Jetty Inside of Google Infrastructure
|
====== When Running Jetty Inside of Google Infrastructure
|
||||||
|
|
||||||
The Google deployment tools will automatically configure the project and authentication information for you.
|
The Google deployment tools will automatically configure the project and authentication information for you.
|
||||||
|
|
||||||
==== Configuring Indexes for Session Data
|
===== Configuring Indexes for Session Data
|
||||||
|
|
||||||
Using some special, composite indexes can speed up session search operations, although it may make write operations slower.
|
Using some special, composite indexes can speed up session search operations, although it may make write operations slower.
|
||||||
By default, indexes will _not_ be used.
|
By default, indexes will _not_ be used.
|
||||||
In order to use them, you will need to manually upload a file that defines the indexes.
|
In order to use them, you will need to manually upload a file that defines the indexes.
|
||||||
This file is named `index.yaml` and you can find it in your distribution in `${jetty.base}/etc/sessions/gcloud/index.yaml`.
|
This file is named `index.yaml` and you can find it in your distribution in `$JETTY_BASE/etc/sessions/gcloud/index.yaml`.
|
||||||
|
|
||||||
Follow the instructions link:https://cloud.google.com/datastore/docs/tools/#the_development_workflow_using_gcloud[here] to upload the pre-generated `index.yaml` file.
|
Follow the instructions link:https://cloud.google.com/datastore/docs/tools/#the_development_workflow_using_gcloud[here] to upload the pre-generated `index.yaml` file.
|
||||||
|
|
||||||
|
@ -60,10 +58,10 @@ Follow the instructions link:https://cloud.google.com/datastore/docs/tools/#the_
|
||||||
|
|
||||||
To enable communication using the GCloud Emulator:
|
To enable communication using the GCloud Emulator:
|
||||||
|
|
||||||
* Ensure you have the GCloud SDK installed: https://cloud.google.com/sdk/?hl=en
|
* Ensure you have the GCloud SDK installed: link:https://cloud.google.com/sdk/?hl=en[]
|
||||||
* Follow the instructions link:https://cloud.google.com/datastore/docs/tools/datastore-emulator[here] on how to start the GCloud datastore emulator, and how to propagate the environment variables that it creates to the terminal in which you run Jetty.
|
* Follow the instructions link:https://cloud.google.com/datastore/docs/tools/datastore-emulator[here] on how to start the GCloud datastore emulator, and how to propagate the environment variables that it creates to the terminal in which you run Jetty.
|
||||||
|
|
||||||
==== Enabling the Google Cloud DataStore Module
|
===== Enabling the Google Cloud DataStore Module
|
||||||
|
|
||||||
The `session-store-gcloud` module provides GCloud support for storing session data.
|
The `session-store-gcloud` module provides GCloud support for storing session data.
|
||||||
|
|
||||||
|
@ -74,25 +72,28 @@ Therefore, you will _also_ need to enable one of the SLF4J implementation module
|
||||||
You can either choose one ahead of time and enable it at the same time as the `session-store-gcloud` module, or you can just enable `session-store-gcloud` module and it will print out a list of available SLF4J implementations.
|
You can either choose one ahead of time and enable it at the same time as the `session-store-gcloud` module, or you can just enable `session-store-gcloud` module and it will print out a list of available SLF4J implementations.
|
||||||
You can then choose one and enable it.
|
You can then choose one and enable it.
|
||||||
|
|
||||||
IMPORTANT: If you want to use updated versions of the jar files automatically downloaded during the module enablement, you can place them in the associated `${jetty.base}/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
|
IMPORTANT: If you want to use updated versions of the jar files automatically downloaded during the module enablement, you can place them in the associated `$JETTY_BASE/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
|
||||||
|
|
||||||
==== Configuration
|
==== Configuration
|
||||||
|
|
||||||
The `$jetty.base/start.d/session-store-gcloud.ini` file contains all of the configurable properties for the `session-store-gcloud` module:
|
The `$JETTY_BASE/start.d/session-store-gcloud.ini` file contains all of the configurable properties for the `session-store-gcloud` module:
|
||||||
|
|
||||||
jetty.session.gcloud.maxRetries::
|
jetty.session.gcloud.maxRetries::
|
||||||
Integer.
|
Integer.
|
||||||
Default 5.
|
Default 5.
|
||||||
Maximum number of retries to connect to GCloud DataStore to write a session.
|
Maximum number of retries to connect to GCloud DataStore to write a session.
|
||||||
|
|
||||||
jetty.session.gcloud.backoffMs::
|
jetty.session.gcloud.backoffMs::
|
||||||
Integer in milliseconds.
|
Integer in milliseconds.
|
||||||
Default 1000.
|
Default 1000.
|
||||||
Number of milliseconds between successive attempts to connect to the GCloud DataStore to write a session.
|
Number of milliseconds between successive attempts to connect to the GCloud DataStore to write a session.
|
||||||
|
|
||||||
jetty.session.gracePeriod.seconds::
|
jetty.session.gracePeriod.seconds::
|
||||||
Integer, in seconds.
|
Integer, in seconds.
|
||||||
Default 3600.
|
Default 3600.
|
||||||
Used during session xref:session-base-scavenge[scavenging].
|
Used during session xref:og-session-base-scavenge[scavenging].
|
||||||
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:session-base-scavenge[scavenged].
|
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:og-session-base-scavenge[scavenged].
|
||||||
|
|
||||||
jetty.session.savePeriod.seconds::
|
jetty.session.savePeriod.seconds::
|
||||||
Integer, in seconds, default is `0`.
|
Integer, in seconds, default is `0`.
|
||||||
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
||||||
|
@ -111,43 +112,42 @@ Optional.
|
||||||
Sets the namespace for GCloud Datastore to use.
|
Sets the namespace for GCloud Datastore to use.
|
||||||
If set, partitions the visibility of session data between webapps, which is helpful for multi-tenant deployments.
|
If set, partitions the visibility of session data between webapps, which is helpful for multi-tenant deployments.
|
||||||
More information can be found link:https://cloud.google.com/datastore/docs/concepts/multitenancy[here.]
|
More information can be found link:https://cloud.google.com/datastore/docs/concepts/multitenancy[here.]
|
||||||
|
|
||||||
Configuration of the stored session object and its fields names-::
|
Configuration of the stored session object and its fields names-::
|
||||||
You should very rarely, if ever, need to change these defaults.
|
You should very rarely, if ever, need to change these defaults.
|
||||||
jetty.session.gcloud.model.kind:::
|
jetty.session.gcloud.model.kind:::
|
||||||
The default is "GCloudSession".
|
The default is "GCloudSession".
|
||||||
This is the type of the object that is stored in GCloud.
|
This is the type of the object that is stored in GCloud.
|
||||||
jetty.session.gcloud.model.id:::
|
jetty.session.gcloud.model.id:::
|
||||||
The default is "id".
|
The default is "id".
|
||||||
This is the session id.
|
This is the session id.
|
||||||
jetty.session.gcloud.model.contextPath:::
|
jetty.session.gcloud.model.contextPath:::
|
||||||
The default is "contextPath".
|
The default is "contextPath".
|
||||||
This is the canonicalized context path of the context to which the session belongs.
|
This is the canonicalized context path of the context to which the session belongs.
|
||||||
jetty.session.gcloud.model.vhost:::
|
jetty.session.gcloud.model.vhost:::
|
||||||
The default is "vhost".
|
The default is "vhost".
|
||||||
This is the canonicalized virtual host of the context to which the session belongs.
|
This is the canonicalized virtual host of the context to which the session belongs.
|
||||||
jetty.session.gcloud.model.accessed:::
|
jetty.session.gcloud.model.accessed:::
|
||||||
The default is "accessed".
|
The default is "accessed".
|
||||||
This is the current access time of the session.
|
This is the current access time of the session.
|
||||||
jetty.session.gcloud.model.lastAccessed:::
|
jetty.session.gcloud.model.lastAccessed:::
|
||||||
The default is "lastAccessed".
|
The default is "lastAccessed".
|
||||||
This is the last access time of the session.
|
This is the last access time of the session.
|
||||||
jetty.session.gcloud.model.createTime:::
|
jetty.session.gcloud.model.createTime:::
|
||||||
The default is "createTime".
|
The default is "createTime".
|
||||||
This is the time, in ms since the epoch, at which the session was created.
|
This is the time, in ms since the epoch, at which the session was created.
|
||||||
jetty.session.gcloud.model.cookieSetTime:::
|
jetty.session.gcloud.model.cookieSetTime:::
|
||||||
The default is "cookieSetTime".
|
The default is "cookieSetTime".
|
||||||
This is the time at which the session cookie was last set.
|
This is the time at which the session cookie was last set.
|
||||||
jetty.session.gcloud.model.lastNode:::
|
jetty.session.gcloud.model.lastNode:::
|
||||||
The default is "lastNode".
|
The default is "lastNode".
|
||||||
This is the `workerName` of the last node to manage the session.
|
This is the `workerName` of the last node to manage the session.
|
||||||
jetty.session.gcloud.model.expiry:::
|
jetty.session.gcloud.model.expiry:::
|
||||||
The default is "expiry".
|
The default is "expiry".
|
||||||
This is the time, in ms since the epoch, at which the session will expire.
|
This is the time, in ms since the epoch, at which the session will expire.
|
||||||
jetty.session.gcloud.model.maxInactive:::
|
jetty.session.gcloud.model.maxInactive:::
|
||||||
The default is "maxInactive".
|
The default is "maxInactive".
|
||||||
This is the session timeout in ms.
|
This is the session timeout in ms.
|
||||||
jetty.session.gcloud.model.attributes:::
|
jetty.session.gcloud.model.attributes:::
|
||||||
The default is "attributes".
|
The default is "attributes".
|
||||||
This is a map of all the session attributes.
|
This is a map of all the session attributes.
|
||||||
|
|
||||||
|
|
|
@ -16,50 +16,55 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[ops-session-hazelcast]]
|
[[og-session-hazelcast]]
|
||||||
|
==== Modules for Persistent HTTP Sessions: Hazelcast
|
||||||
=== Modules for Persistent Sessions: Hazelcast
|
|
||||||
|
|
||||||
Hazelcast can be used to cluster session information in one of two modes: either remote or embedded.
|
Hazelcast can be used to cluster session information in one of two modes: either remote or embedded.
|
||||||
Remote mode means that Hazelcast will create a client to talk to other instances, possibly on other nodes.
|
Remote mode means that Hazelcast will create a client to talk to other instances, possibly on other nodes.
|
||||||
Embedded mode means that Hazelcast will start a local instance and communicate with that.
|
Embedded mode means that Hazelcast will start a local instance and communicate with that.
|
||||||
|
|
||||||
[[ops-session-hazelcast-remote]]
|
[[og-session-hazelcast-remote]]
|
||||||
==== Remote Hazelcast Clustering
|
===== Remote Hazelcast Clustering
|
||||||
|
|
||||||
Enabling the `session-store-hazelcast-remote` module allows jetty to communicate with a remote Hazelcast instance to cluster session data.
|
Enabling the `session-store-hazelcast-remote` module allows jetty to communicate with a remote Hazelcast instance to cluster session data.
|
||||||
|
|
||||||
Because Hazelcast is not a technology provided by the Eclipse Foundation, you will be prompted to assent to the licenses of the external vendor (Apache in this case).
|
Because Hazelcast is not a technology provided by the Eclipse Foundation, you will be prompted to assent to the licenses of the external vendor (Apache in this case).
|
||||||
|
|
||||||
Hazelcast-specific jar files will be downloaded and saved to a directory named `${jetty.base}/lib/hazelcast/`.
|
Hazelcast-specific jar files will be downloaded and saved to a directory named `$JETTY_BASE/lib/hazelcast/`.
|
||||||
|
|
||||||
NOTE: If you have updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `${jetty.base}/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
|
NOTE: If you have updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `$JETTY_BASE/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
|
||||||
|
|
||||||
===== Configuration
|
====== Configuration
|
||||||
|
|
||||||
The `start.d/session-store-hazelcast-remote.ini` contains a list of all the configurable options for the Hazelcast module:
|
The `start.d/session-store-hazelcast-remote.ini` contains a list of all the configurable options for the Hazelcast module:
|
||||||
|
|
||||||
jetty.session.hazelcast.mapName::
|
jetty.session.hazelcast.mapName::
|
||||||
The default is "jetty-distributed-session-map".
|
The default is "jetty-distributed-session-map".
|
||||||
This is the name of the Map in Hazelcast where sessions will be stored.
|
This is the name of the Map in Hazelcast where sessions will be stored.
|
||||||
|
|
||||||
jetty.session.hazelcast.onlyClient::
|
jetty.session.hazelcast.onlyClient::
|
||||||
Boolean, default `true`.
|
Boolean, default `true`.
|
||||||
The Hazelcast instance will be configured in client mode.
|
The Hazelcast instance will be configured in client mode.
|
||||||
|
|
||||||
jetty.session.hazelcast.configurationLocation::
|
jetty.session.hazelcast.configurationLocation::
|
||||||
Optional.
|
Optional.
|
||||||
This is the path to an external Hazelcast xml configuration file.
|
This is the path to an external Hazelcast xml configuration file.
|
||||||
|
|
||||||
jetty.session.hazelcast.useQueries::
|
jetty.session.hazelcast.useQueries::
|
||||||
Boolean, default `false`.
|
Boolean, default `false`.
|
||||||
If `true`, Jetty will use Hazelcast queries to find sessions to xref:session-base-scavenge[scavenge].
|
If `true`, Jetty will use Hazelcast queries to find sessions to xref:og-session-base-scavenge[scavenge].
|
||||||
If `false` sessions that are not currently in a xref:op-session-sessioncache[session cache] cannot be xref:session-base-scavenge[scavenged], and will need to be removed by some external process.
|
If `false` sessions that are not currently in a xref:og-session-cache[session cache] cannot be xref:og-session-base-scavenge[scavenged], and will need to be removed by some external process.
|
||||||
|
|
||||||
jetty.session.hazelcast.addresses::
|
jetty.session.hazelcast.addresses::
|
||||||
Optional.
|
Optional.
|
||||||
These are the addresses of remote Hazelcast instances with which to communicate.
|
These are the addresses of remote Hazelcast instances with which to communicate.
|
||||||
|
|
||||||
jetty.session.gracePeriod.seconds::
|
jetty.session.gracePeriod.seconds::
|
||||||
Integer, in seconds.
|
Integer, in seconds.
|
||||||
Default 3600.
|
Default 3600.
|
||||||
Used during session xref:session-base-scavenge[scavenging].
|
Used during session xref:og-session-base-scavenge[scavenging].
|
||||||
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:session-base-scavenge[scavenged].
|
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:og-session-base-scavenge[scavenged].
|
||||||
|
|
||||||
jetty.session.savePeriod.seconds::
|
jetty.session.savePeriod.seconds::
|
||||||
Integer, in seconds, default is `0`.
|
Integer, in seconds, default is `0`.
|
||||||
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
||||||
|
@ -75,8 +80,8 @@ Thorough consideration of the `maxIdleTime` of the session when setting the `sav
|
||||||
|
|
||||||
IMPORTANT: Be aware that if your session attributes contain classes from inside your webapp (or Jetty classes) then you will need to put these classes onto the classpath of all of your Hazelcast instances.
|
IMPORTANT: Be aware that if your session attributes contain classes from inside your webapp (or Jetty classes) then you will need to put these classes onto the classpath of all of your Hazelcast instances.
|
||||||
|
|
||||||
[[ops-session-hazelcast-embedded]]
|
[[og-session-hazelcast-embedded]]
|
||||||
==== Embedded Hazelcast Clustering
|
===== Embedded Hazelcast Clustering
|
||||||
|
|
||||||
This will run an in-process instance of Hazelcast.
|
This will run an in-process instance of Hazelcast.
|
||||||
This can be useful for example during testing.
|
This can be useful for example during testing.
|
||||||
|
@ -84,11 +89,11 @@ To enable this you enable the `session-store-hazelcast-embedded` module.
|
||||||
|
|
||||||
Because Hazelcast is not a technology provided by the Eclipse Foundation, you will be prompted to assent to the licenses of the external vendor (Apache in this case).
|
Because Hazelcast is not a technology provided by the Eclipse Foundation, you will be prompted to assent to the licenses of the external vendor (Apache in this case).
|
||||||
|
|
||||||
Hazelcast-specific jar files will be downloaded to a directory named `${jetty.base}/lib/hazelcast/`.
|
Hazelcast-specific jar files will be downloaded to a directory named `$JETTY_BASE/lib/hazelcast/`.
|
||||||
|
|
||||||
===== Configuration
|
====== Configuration
|
||||||
|
|
||||||
The `$jetty.base/start.d/start.d/session-store-hazelcast-embedded.ini` contains a list of all the configurable options for the Hazelcast module:
|
The `$JETTY_BASE/start.d/start.d/session-store-hazelcast-embedded.ini` contains a list of all the configurable options for the Hazelcast module:
|
||||||
|
|
||||||
jetty.session.hazelcast.mapName::
|
jetty.session.hazelcast.mapName::
|
||||||
The default is "jetty-distributed-session-map".
|
The default is "jetty-distributed-session-map".
|
||||||
|
@ -96,18 +101,22 @@ This is the name of the Map in Hazelcast where sessions will be stored.
|
||||||
jetty.session.hazelcast.hazelcastInstanceName
|
jetty.session.hazelcast.hazelcastInstanceName
|
||||||
Default is "JETTY_DISTRIBUTED_SESSION_INSTANCE".
|
Default is "JETTY_DISTRIBUTED_SESSION_INSTANCE".
|
||||||
This is the unique name of the Hazelcast instance that will be created.
|
This is the unique name of the Hazelcast instance that will be created.
|
||||||
|
|
||||||
jetty.session.hazelcast.configurationLocation::
|
jetty.session.hazelcast.configurationLocation::
|
||||||
Optional.
|
Optional.
|
||||||
This is the path to an external Hazelcast xml configuration file.
|
This is the path to an external Hazelcast xml configuration file.
|
||||||
|
|
||||||
jetty.session.hazelcast.useQueries::
|
jetty.session.hazelcast.useQueries::
|
||||||
Boolean, default `false'.
|
Boolean, default `false'.
|
||||||
If `true`, Jetty will use Hazelcast queries to find expired sessions to xref:session-base-scavenge[scavenge].
|
If `true`, Jetty will use Hazelcast queries to find expired sessions to xref:og-session-base-scavenge[scavenge].
|
||||||
If `false` sessions that are not currently in a xref:op-session-sessioncache[session cache] cannot be xref:session-base-scavenge[scavenged], and will need to be removed by some external process.
|
If `false` sessions that are not currently in a xref:og-session-cache[session cache] cannot be xref:og-session-base-scavenge[scavenged], and will need to be removed by some external process.
|
||||||
|
|
||||||
jetty.session.gracePeriod.seconds::
|
jetty.session.gracePeriod.seconds::
|
||||||
Integer, in seconds.
|
Integer, in seconds.
|
||||||
Default 3600.
|
Default 3600.
|
||||||
Used during session xref:session-base-scavenge[scavenging].
|
Used during session xref:og-session-base-scavenge[scavenging].
|
||||||
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:session-base-scavenge[scavenged].
|
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:og-session-base-scavenge[scavenged].
|
||||||
|
|
||||||
jetty.session.savePeriod.seconds::
|
jetty.session.savePeriod.seconds::
|
||||||
Integer, in seconds, default is `0`.
|
Integer, in seconds, default is `0`.
|
||||||
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
||||||
|
@ -122,4 +131,3 @@ Thorough consideration of the `maxIdleTime` of the session when setting the `sav
|
||||||
====
|
====
|
||||||
|
|
||||||
IMPORTANT: If your session attributes contain classes from inside your webapp (or jetty classes) then you will need to put these classes onto the classpath of all of your hazelcast instances. In the case of embedded hazelcast, as it is started before your webapp, it will NOT have access to your webapp's classes - you will need to extract these classes and put them onto the jetty server's classpath.
|
IMPORTANT: If your session attributes contain classes from inside your webapp (or jetty classes) then you will need to put these classes onto the classpath of all of your hazelcast instances. In the case of embedded hazelcast, as it is started before your webapp, it will NOT have access to your webapp's classes - you will need to extract these classes and put them onto the jetty server's classpath.
|
||||||
|
|
|
@ -16,49 +16,48 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[ops-sessions-infinispan]]
|
[[og-session-infinispan]]
|
||||||
|
==== Modules for Persistent HTTP Sessions: Infinispan
|
||||||
=== Modules for Persistent Sessions: Infinispan
|
|
||||||
|
|
||||||
In order to persist/cluster sessions using Infinispan, Jetty needs to know how to contact Infinispan.
|
In order to persist/cluster sessions using Infinispan, Jetty needs to know how to contact Infinispan.
|
||||||
There are two options: a remote Infinispan instance, or an in-process Infinispan instance.
|
There are two options: a remote Infinispan instance, or an in-process Infinispan instance.
|
||||||
The former is referred to as "remote" Infinispan and the latter as "embedded" Infinispan.
|
The former is referred to as "remote" Infinispan and the latter as "embedded" Infinispan.
|
||||||
If you wish Jetty to be able to xref:ops-session-base-scavenge[scavenge] expired sessions, you will also need to enable the appropriate `infinispan-[remote|embedded]-query` module.
|
If you wish Jetty to be able to xref:og-session-base-scavenge[scavenge] expired sessions, you will also need to enable the appropriate `infinispan-[remote|embedded]-query` module.
|
||||||
|
|
||||||
|
[[og-session-infinispan-remote]]
|
||||||
[[ops-session-infinispan-remote]]
|
===== Remote Infinispan Session Module
|
||||||
==== Remote Infinispan Session Module
|
|
||||||
|
|
||||||
The `session-store-infinispan-remote` module configures Jetty to talk to an external Infinispan instance to store session data.
|
The `session-store-infinispan-remote` module configures Jetty to talk to an external Infinispan instance to store session data.
|
||||||
|
|
||||||
Because Infinispan is not a technology provided by the Eclipse Foundation, you will be prompted to assent to the licenses of the external vendor (Apache in this case).
|
Because Infinispan is not a technology provided by the Eclipse Foundation, you will be prompted to assent to the licenses of the external vendor (Apache in this case).
|
||||||
|
|
||||||
Infinispan-specific jar files are download to the directory named `${jetty.base}/lib/infinispan/`.
|
Infinispan-specific jar files are download to the directory named `$JETTY_BASE/lib/infinispan/`.
|
||||||
|
|
||||||
In addition to adding these modules to the classpath of the server it also added several ini configuration files to the `${jetty.base}/start.d` directory.
|
In addition to adding these modules to the classpath of the server it also added several ini configuration files to the `$JETTY_BASE/start.d` directory.
|
||||||
|
|
||||||
NOTE: If you have updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `${jetty.base}/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
|
NOTE: If you have updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `$JETTY_BASE/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
|
||||||
|
|
||||||
==== Configuration
|
====== Configuration
|
||||||
|
|
||||||
The `$jetty.base/start.d/session-store-infinispan-remote.ini` contains the following configurable properties:
|
The `$JETTY_BASE/start.d/session-store-infinispan-remote.ini` contains the following configurable properties:
|
||||||
|
|
||||||
jetty.session.infinispan.remoteCacheName::
|
jetty.session.infinispan.remoteCacheName::
|
||||||
Default `"sessions"`.
|
Default `"sessions"`.
|
||||||
This is the name of the cache in Infinispan where sessions will be stored.
|
This is the name of the cache in Infinispan where sessions will be stored.
|
||||||
|
|
||||||
jetty.session.infinispan.idleTimeout.seconds::
|
jetty.session.infinispan.idleTimeout.seconds::
|
||||||
Integer, in seconds, default `0`.
|
Integer, in seconds, default `0`.
|
||||||
This is the amount of time, in seconds, that a session entry in Infinispan can be idle (ie neither read nor written) before Infinispan will delete its entry.
|
This is the amount of time, in seconds, that a session entry in Infinispan can be idle (ie neither read nor written) before Infinispan will delete its entry.
|
||||||
Usually, you do *not* want to set a value for this, as you want Jetty to manage all session expiration (and call any HttpSessionListeners).
|
Usually, you do *not* want to set a value for this, as you want Jetty to manage all session expiration (and call any HttpSessionListeners).
|
||||||
You *should* enable the xref:ops-session-infinispan-remote-query[infinispan-remote-query] to allow jetty to xref:ops-session-base-scavenge[scavenge] for expired sessions.
|
You *should* enable the xref:og-session-infinispan-remote-query[infinispan-remote-query] to allow jetty to xref:og-session-base-scavenge[scavenge] for expired sessions.
|
||||||
If you do not, then there is the possibility that sessions can be left in Infinispan but no longer referenced by any Jetty node (so called "zombie" or "orphan" sessions), in which case you can use this feature to ensure their removal.
|
If you do not, then there is the possibility that sessions can be left in Infinispan but no longer referenced by any Jetty node (so called "zombie" or "orphan" sessions), in which case you can use this feature to ensure their removal.
|
||||||
|
|
||||||
IMPORTANT: You should make sure that the number of seconds you specify is larger than the configured `maxIdleTime` for sessions.
|
IMPORTANT: You should make sure that the number of seconds you specify is larger than the configured `maxIdleTime` for sessions.
|
||||||
|
|
||||||
jetty.session.gracePeriod.seconds::
|
jetty.session.gracePeriod.seconds::
|
||||||
Integer, default 3600.
|
Integer, default 3600.
|
||||||
Used during session xref:ops-session-base-scavenge[scavenging].
|
Used during session xref:og-session-base-scavenge[scavenging].
|
||||||
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:ops-session-base-scavenge[scavenged].
|
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:og-session-base-scavenge[scavenged].
|
||||||
|
|
||||||
jetty.session.savePeriod.seconds::
|
jetty.session.savePeriod.seconds::
|
||||||
Integer, in seconds, default is `0`.
|
Integer, in seconds, default is `0`.
|
||||||
|
@ -73,41 +72,41 @@ You should be careful in the use of this property in clustered environments: if
|
||||||
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - it would be undesirable to set a `savePeriod` that is larger than the `maxIdleTime`.
|
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - it would be undesirable to set a `savePeriod` that is larger than the `maxIdleTime`.
|
||||||
====
|
====
|
||||||
|
|
||||||
[[ops-session-infinispan-remote-query]]
|
[[og-session-infinispan-remote-query]]
|
||||||
==== Remote Infinispan Query Module
|
===== Remote Infinispan Query Module
|
||||||
|
|
||||||
The `infinispan-remote-query` module allows Jetty to xref:ops-session-base-scavenge[scavenge] expired sessions.
|
The `infinispan-remote-query` module allows Jetty to xref:og-session-base-scavenge[scavenge] expired sessions.
|
||||||
Note that this is an *additional* module, to be used in conjunction with the `session-store-infinispan-remote` module.
|
Note that this is an *additional* module, to be used in conjunction with the `session-store-infinispan-remote` module.
|
||||||
|
|
||||||
There are no configuration properties associated with this module.
|
There are no configuration properties associated with this module.
|
||||||
|
|
||||||
[[ops-session-infinispan-embedded]]
|
[[og-session-infinispan-embedded]]
|
||||||
==== Embedded Infinispan Session Module
|
===== Embedded Infinispan Session Module
|
||||||
|
|
||||||
Enabling the `session-store-infinispan-embedded` module runs an in-process instance of Infinispan.
|
Enabling the `session-store-infinispan-embedded` module runs an in-process instance of Infinispan.
|
||||||
|
|
||||||
Because Infinispan is not a technology provided by the Eclipse Foundation, you will be prompted to assent to the licenses of the external vendor (Apache in this case).
|
Because Infinispan is not a technology provided by the Eclipse Foundation, you will be prompted to assent to the licenses of the external vendor (Apache in this case).
|
||||||
Infinispan-specific jar files will be downloaded and saved to a directory named `${jetty.base}/lib/infinispan/`.
|
Infinispan-specific jar files will be downloaded and saved to a directory named `$JETTY_BASE/lib/infinispan/`.
|
||||||
|
|
||||||
NOTE: If you have updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `${jetty.base}/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
|
NOTE: If you have updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `$JETTY_BASE/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
|
||||||
|
|
||||||
==== Configuration
|
====== Configuration
|
||||||
|
|
||||||
The `$jetty.base/start.d/session-store-infinispan-embedded.ini` contains the following configurable properties:
|
The `$JETTY_BASE/start.d/session-store-infinispan-embedded.ini` contains the following configurable properties:
|
||||||
|
|
||||||
jetty.session.infinispan.idleTimeout.seconds::
|
jetty.session.infinispan.idleTimeout.seconds::
|
||||||
Integer, in seconds, default `0`.
|
Integer, in seconds, default `0`.
|
||||||
This is the amount of time, in seconds, that a session entry in Infinispan can be idle (ie neither read nor written) before Infinispan will delete its entry.
|
This is the amount of time, in seconds, that a session entry in Infinispan can be idle (ie neither read nor written) before Infinispan will delete its entry.
|
||||||
Usually, you do *not* want to set a value for this, as you want Jetty to manage all session expiration (and call any HttpSessionListeners).
|
Usually, you do *not* want to set a value for this, as you want Jetty to manage all session expiration (and call any HttpSessionListeners).
|
||||||
You *should* enable the xref:ops-session-infinispan-embedded-query[infinispan-embedded-query] to allow Jetty to xref:session-base-scavenge[scavenge] for expired sessions.
|
You *should* enable the xref:og-session-infinispan-embedded-query[infinispan-embedded-query] to allow Jetty to xref:og-session-base-scavenge[scavenge] for expired sessions.
|
||||||
If you do not, then there is the possibility that expired sessions can be left in Infinispan.
|
If you do not, then there is the possibility that expired sessions can be left in Infinispan.
|
||||||
|
|
||||||
IMPORTANT: You should make sure that the number of seconds you specify is larger than the configured `maxIdleTime` for sessions.
|
IMPORTANT: You should make sure that the number of seconds you specify is larger than the configured `maxIdleTime` for sessions.
|
||||||
|
|
||||||
jetty.session.gracePeriod.seconds::
|
jetty.session.gracePeriod.seconds::
|
||||||
Integer, default 3600.
|
Integer, default 3600.
|
||||||
Used during session xref:ops-session-base-scavenge[scavenging].
|
Used during session xref:og-session-base-scavenge[scavenging].
|
||||||
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:ops-session-base-scavenge[scavenged].
|
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:og-session-base-scavenge[scavenged].
|
||||||
|
|
||||||
jetty.session.savePeriod.seconds::
|
jetty.session.savePeriod.seconds::
|
||||||
Integer, in seconds, default is `0`.
|
Integer, in seconds, default is `0`.
|
||||||
|
@ -121,20 +120,18 @@ The value of this property is used to skip writes for these kinds of sessions: t
|
||||||
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - it would be undesirable to set a `savePeriod` that is larger than the `maxIdleTime`.
|
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - it would be undesirable to set a `savePeriod` that is larger than the `maxIdleTime`.
|
||||||
====
|
====
|
||||||
|
|
||||||
|
[[og-session-infinispan-embedded-query]]
|
||||||
|
===== Embedded Infinispan Query Module
|
||||||
|
|
||||||
==== Embedded Infinispan Query Module
|
The `infinispan-embedded-query` module allows Jetty to xref:og-session-base-scavenge[scavenge] expired sessions.
|
||||||
|
|
||||||
The `infinispan-embedded-query` module allows Jetty to xref:ops-session-base-scavenge[scavenge] expired sessions.
|
|
||||||
|
|
||||||
|
|
||||||
There are no configuration properties associated with this module.
|
There are no configuration properties associated with this module.
|
||||||
|
|
||||||
|
===== Converting Session Format for Jetty-9.4.13
|
||||||
==== Converting Session Format for Jetty-9.4.13
|
|
||||||
|
|
||||||
From Jetty-9.4.13 onwards, we have changed the format of the serialized session when using a remote cache (ie using hotrod).
|
From Jetty-9.4.13 onwards, we have changed the format of the serialized session when using a remote cache (ie using hotrod).
|
||||||
Prior to release 9.4.13 we used the default Infinispan serialization, however this was not able to store sufficient information to allow Jetty to properly deserialize session attributes in all circumstances.
|
Prior to release 9.4.13 we used the default Infinispan serialization, however this was not able to store sufficient information to allow Jetty to properly deserialize session attributes in all circumstances.
|
||||||
See issue https://github.com/eclipse/jetty.project/issues/2919 for more background.
|
See issue link:https://github.com/eclipse/jetty.project/issues/2919[] for more background.
|
||||||
|
|
||||||
We have provided a conversion program which will convert any sessions stored in Infinispan to the new format.
|
We have provided a conversion program which will convert any sessions stored in Infinispan to the new format.
|
||||||
|
|
||||||
|
@ -142,7 +139,6 @@ IMPORTANT: We recommend that you backup your stored sessions before running the
|
||||||
|
|
||||||
How to use the converter:
|
How to use the converter:
|
||||||
|
|
||||||
[source, screen, subs="{sub-order}"]
|
|
||||||
----
|
----
|
||||||
java -cp jetty-servlet-api-4.0.2.jar:jetty-util-{VERSION}.jar:jetty-server-{VERSION}.jar:infinispan-remote-9.1.0.Final.jar:jetty-infinispan-{VERSION}.jar:[other classpath] org.eclipse.jetty.session.infinispan.InfinispanSessionLegacyConverter
|
java -cp jetty-servlet-api-4.0.2.jar:jetty-util-{VERSION}.jar:jetty-server-{VERSION}.jar:infinispan-remote-9.1.0.Final.jar:jetty-infinispan-{VERSION}.jar:[other classpath] org.eclipse.jetty.session.infinispan.InfinispanSessionLegacyConverter
|
||||||
|
|
||||||
|
@ -151,18 +147,17 @@ Usage: InfinispanSessionLegacyConverter [-Dhost=127.0.0.1] [-Dverbose=true|fals
|
||||||
|
|
||||||
The classpath::
|
The classpath::
|
||||||
Must contain the servlet-api, jetty-util, jetty-server, jetty-infinispan and infinispan-remote jars. If your sessions contain attributes that use application classes, you will also need to also put those classes onto the classpath. If your session has been authenticated, you may also need to include the jetty-security and jetty-http jars on the classpath.
|
Must contain the servlet-api, jetty-util, jetty-server, jetty-infinispan and infinispan-remote jars. If your sessions contain attributes that use application classes, you will also need to also put those classes onto the classpath. If your session has been authenticated, you may also need to include the jetty-security and jetty-http jars on the classpath.
|
||||||
|
|
||||||
Parameters::
|
Parameters::
|
||||||
When used with no arguments the usage message is printed. When used with the `cache-name` parameter the conversion is performed. When used with both `cache-name` and `check` parameters, sessions are checked for whether or not they are converted.
|
When used with no arguments the usage message is printed. When used with the `cache-name` parameter the conversion is performed. When used with both `cache-name` and `check` parameters, sessions are checked for whether or not they are converted.
|
||||||
|
-Dhost::: you can optionally provide a system property with the address of your remote Infinispan server. Defaults to the localhost.
|
||||||
-Dhost::: you can optionally provide a system property with the address of your remote Infinispan server. Defaults to the localhost.
|
-Dverbose::: defaults to false. If true, prints more comprehensive stacktrace information about failures. Useful to diagnose why a session is not converted.
|
||||||
-Dverbose::: defaults to false. If true, prints more comprehensive stacktrace information about failures. Useful to diagnose why a session is not converted.
|
cache-name::: the name of the remote cache containing your sessions. This is mandatory.
|
||||||
cache-name::: the name of the remote cache containing your sessions. This is mandatory.
|
check::: the optional check command will verify sessions have been converted. Use it _after_ doing the conversion.
|
||||||
check::: the optional check command will verify sessions have been converted. Use it _after_ doing the conversion.
|
|
||||||
|
|
||||||
To perform the conversion, run the InfinispanSessionLegacyConverter with just the `cache-name`, and optionally the `host` system property.
|
To perform the conversion, run the InfinispanSessionLegacyConverter with just the `cache-name`, and optionally the `host` system property.
|
||||||
The following command will attempt to convert all sessions in the cached named `my-remote-cache` on the machine `myhost`, ensuring that application classes in the `/my/custom/classes` directory are on the classpath:
|
The following command will attempt to convert all sessions in the cached named `my-remote-cache` on the machine `myhost`, ensuring that application classes in the `/my/custom/classes` directory are on the classpath:
|
||||||
|
|
||||||
[source, screen, subs="{sub-order}"]
|
|
||||||
----
|
----
|
||||||
java -cp jetty-servlet-api-4.0.2.jar:jetty-util-{VERSION}.jar:jetty-server-{VERSION}.jar:infinispan-remote-9.1.0.Final.jar:jetty-infinispan-{VERSION}.jar:/my/custom/classes org.eclipse.jetty.session.infinispan.InfinispanSessionLegacyConverter -Dhost=myhost my-remote-cache
|
java -cp jetty-servlet-api-4.0.2.jar:jetty-util-{VERSION}.jar:jetty-server-{VERSION}.jar:infinispan-remote-9.1.0.Final.jar:jetty-infinispan-{VERSION}.jar:/my/custom/classes org.eclipse.jetty.session.infinispan.InfinispanSessionLegacyConverter -Dhost=myhost my-remote-cache
|
||||||
----
|
----
|
|
@ -16,21 +16,20 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[ops-sessions-jdbc]]
|
[[og-session-jdbc]]
|
||||||
|
==== Modules for Persistent HTTP Sessions: JDBC
|
||||||
=== Modules for Persistent Sessions: JDBC
|
|
||||||
|
|
||||||
Enabling the `session-store-jdbc` module configures Jetty to persist session data in a relational database.
|
Enabling the `session-store-jdbc` module configures Jetty to persist session data in a relational database.
|
||||||
|
|
||||||
|
===== Configuration
|
||||||
|
|
||||||
==== Configuration
|
After enabling the module, the `$JETTY_BASE/start.d/session-store-jdbc.ini` file contains the following customizable properties:
|
||||||
|
|
||||||
After enabling the module, the `$jetty.base/start.d/session-store-jdbc.ini` file contains the following customizable properties:
|
|
||||||
|
|
||||||
jetty.session.gracePeriod.seconds::
|
jetty.session.gracePeriod.seconds::
|
||||||
Integer, default 3600.
|
Integer, default 3600.
|
||||||
Used during session xref:ops-session-base-scavenge[scavenging].
|
Used during session xref:og-session-base-scavenge[scavenging].
|
||||||
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:ops-session-base-scavenge[scavenged].
|
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:og-session-base-scavenge[scavenged].
|
||||||
|
|
||||||
jetty.session.savePeriod.seconds::
|
jetty.session.savePeriod.seconds::
|
||||||
Integer, in seconds, default is `0`.
|
Integer, in seconds, default is `0`.
|
||||||
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
||||||
|
@ -49,27 +48,29 @@ Default `datasource`.
|
||||||
Set to either `datasource` or `driver` depending on the type of connection being used.
|
Set to either `datasource` or `driver` depending on the type of connection being used.
|
||||||
Depending which you select, there are additional properties available:
|
Depending which you select, there are additional properties available:
|
||||||
|
|
||||||
`datasource`:::
|
`datasource`:::
|
||||||
jetty.session.jdbc.datasourceName::::
|
jetty.session.jdbc.datasourceName::::
|
||||||
Name of the remote datasource.
|
Name of the remote datasource.
|
||||||
|
|
||||||
`driver`:::
|
`driver`:::
|
||||||
jetty.session.jdbc.driverClass::::
|
jetty.session.jdbc.driverClass::::
|
||||||
Name of the JDBC driver that controls access to the remote database, such as `com.mysql.jdbc.Driver`
|
Name of the JDBC driver that controls access to the remote database, such as `com.mysql.jdbc.Driver`
|
||||||
jetty.session.jdbc.driverUrl::::
|
jetty.session.jdbc.driverUrl::::
|
||||||
URL of the database which includes the driver type, host name and port, service name and any specific attributes unique to the database, such as a username.
|
URL of the database which includes the driver type, host name and port, service name and any specific attributes unique to the database, such as a username.
|
||||||
As an example, here is a mysql connection with the username appended: `jdbc:mysql://127.0.0.1:3306/sessions?user=sessionsadmin`.
|
As an example, here is a mysql connection with the username appended: `jdbc:mysql://127.0.0.1:3306/sessions?user=sessionsadmin`.
|
||||||
|
|
||||||
jetty.session.jdbc.blobType::
|
jetty.session.jdbc.blobType::
|
||||||
Optional.
|
Optional.
|
||||||
Default `blob` or `bytea` for Postgres.
|
Default `blob` or `bytea` for Postgres.
|
||||||
This is the keyword used by the particular database to identify the blob data type.
|
This is the keyword used by the particular database to identify the blob data type.
|
||||||
If netiher default is suitable you can set this value explicitly.
|
If netiher default is suitable you can set this value explicitly.
|
||||||
|
|
||||||
jetty.session.jdbc.longType::
|
jetty.session.jdbc.longType::
|
||||||
Optional.
|
Optional.
|
||||||
Default `bigint` or `number(20)` for Oracle.
|
Default `bigint` or `number(20)` for Oracle.
|
||||||
This is the keyword used by the particular database to identify the long integer data type.
|
This is the keyword used by the particular database to identify the long integer data type.
|
||||||
Set this explicitly if neither of the default values is appropriate.
|
Set this explicitly if neither of the default values is appropriate.
|
||||||
|
|
||||||
jetty.session.jdbc.stringType::
|
jetty.session.jdbc.stringType::
|
||||||
Optional.
|
Optional.
|
||||||
Default `varchar`.
|
Default `varchar`.
|
||||||
|
@ -80,7 +81,7 @@ jetty.session.jdbc.schema.schemaName::
|
||||||
jetty.session.jdbc.schema.catalogName::
|
jetty.session.jdbc.schema.catalogName::
|
||||||
Optional.
|
Optional.
|
||||||
The exact meaning of these two properties is dependent on your database vendor, but can broadly be described as further scoping for the session table name.
|
The exact meaning of these two properties is dependent on your database vendor, but can broadly be described as further scoping for the session table name.
|
||||||
See https://en.wikipedia.org/wiki/Database_schema and https://en.wikipedia.org/wiki/Database_catalog.
|
See link:https://en.wikipedia.org/wiki/Database_schema[] and link:https://en.wikipedia.org/wiki/Database_catalog[].
|
||||||
These extra scoping names can come into play at startup time when Jetty determines if the session table already exists, or otherwise creates it on-the-fly.
|
These extra scoping names can come into play at startup time when Jetty determines if the session table already exists, or otherwise creates it on-the-fly.
|
||||||
If you have employed either of these concepts when you pre-created the session table, or you want to ensure that Jetty uses them when it auto-creates the session table, then you have two options: either set them explicitly, or let Jetty infer them from a database connection (obtained using either a Datasource or Driver according to the `db-connection-type` you have configured).
|
If you have employed either of these concepts when you pre-created the session table, or you want to ensure that Jetty uses them when it auto-creates the session table, then you have two options: either set them explicitly, or let Jetty infer them from a database connection (obtained using either a Datasource or Driver according to the `db-connection-type` you have configured).
|
||||||
To set them explicitly, uncomment and supply appropriate values for the `jetty.session.jdbc.schema.schemaName` and/or `jetty.session.jdbc.schema.catalogName` properties.
|
To set them explicitly, uncomment and supply appropriate values for the `jetty.session.jdbc.schema.schemaName` and/or `jetty.session.jdbc.schema.catalogName` properties.
|
|
@ -16,36 +16,22 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[ops-session-memcachedsessiondatastore]]
|
[[og-session-memcached]]
|
||||||
|
|
||||||
=== Modules for Persistent Sessions: The L2 Session Data Cache
|
==== Modules for Persistent HTTP Sessions: The L2 Session Data Cache
|
||||||
|
|
||||||
If your chosen persistence technology is slow, it can be helpful to locally cache the session data.
|
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.
|
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
|
===== MemcachedSessionDataMap
|
||||||
|
|
||||||
The `MemcachedSessionDataMap` uses `memcached` to perform caching.
|
The `MemcachedSessionDataMap` uses `memcached` to perform caching of `SessionData`.
|
||||||
|
|
||||||
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.
|
To enable it with the Jetty distribution, enable the `session-store-cache` module, along with your chosen `session-store-xxxx` module.
|
||||||
|
|
||||||
After enabling, the `$jetty.base/start.d/session-store-cache.ini` file will be generated:
|
====== Configuration
|
||||||
|
|
||||||
[source, screen, subs="{sub-order}"]
|
The `$JETTY_BASE/start.d/session-store-cache.ini` contains the following configurable properties:
|
||||||
----
|
|
||||||
--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::
|
jetty.session.memcached.host::
|
||||||
Default value is `localhost`.
|
Default value is `localhost`.
|
||||||
|
@ -61,4 +47,4 @@ This is the length of time in seconds that an item can remain in the memcached c
|
||||||
|
|
||||||
jetty.session.memcached.heartbeats::
|
jetty.session.memcached.heartbeats::
|
||||||
Default value `true`.
|
Default value `true`.
|
||||||
Whether or not the memcached system should generate heartbeats.
|
Whether the memcached system should generate heartbeats.
|
|
@ -16,51 +16,54 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[ops-session-mongo]]
|
[[og-session-mongo]]
|
||||||
|
==== Modules for Persistent HTTP Sessions: MongoDB
|
||||||
=== Modules for Persistent Sessions: MongoDB
|
|
||||||
|
|
||||||
Enabling the `session-store-mongo` module configures Jetty to store session data in MongoDB.
|
Enabling the `session-store-mongo` module configures Jetty to store session data in MongoDB.
|
||||||
|
|
||||||
Because MongoDB is not a technology provided by the Eclipse Foundation, you will be prompted to assent to the licenses of the external vendor (Apache in this case) during the install.
|
Because MongoDB is not a technology provided by the Eclipse Foundation, you will be prompted to assent to the licenses of the external vendor (Apache in this case) during the install.
|
||||||
Jars needed by MongoDB are downloaded and stored into a directory named `${jetty.base}/lib/nosql/`.
|
Jars needed by MongoDB are downloaded and stored into a directory named `$JETTY_BASE/lib/nosql/`.
|
||||||
|
|
||||||
IMPORTANT: If you want to use updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `${jetty.base}/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
|
IMPORTANT: If you want to use updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `$JETTY_BASE/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
|
||||||
|
|
||||||
==== Configuration
|
===== Configuration
|
||||||
|
|
||||||
The `$jetty.base/start.d/session-store-mongo.ini` file contains these configurable properties:
|
The `$JETTY_BASE/start.d/session-store-mongo.ini` file contains these configurable properties:
|
||||||
|
|
||||||
jetty.session.mongo.dbName::
|
jetty.session.mongo.dbName::
|
||||||
Default is "HttpSessions".
|
Default is "HttpSessions".
|
||||||
This is the name of the database in MongoDB used to store the session collection.
|
This is the name of the database in MongoDB used to store the session collection.
|
||||||
|
|
||||||
jetty.session.mongo.collectionName::
|
jetty.session.mongo.collectionName::
|
||||||
Default is "jettySessions".
|
Default is "jettySessions".
|
||||||
This is the name of the collection in MongoDB used to store all of the sessions.
|
This is the name of the collection in MongoDB used to store all of the sessions.
|
||||||
|
|
||||||
The connection type-::
|
The connection type-::
|
||||||
You can connect to MongoDB either using a host/port combination, or a URI.
|
You can connect to MongoDB either using a host/port combination, or a URI.
|
||||||
By default, the host/port method is selected, but you can change this by commenting out the unwanted method, and uncommenting the other one.
|
By default, the host/port method is selected, but you can change this by commenting out the unwanted method, and uncommenting the other one.
|
||||||
connection-type=address:::
|
connection-type=address:::
|
||||||
Used when utilizing a direct connection to the MongoDB server.
|
Used when utilizing a direct connection to the MongoDB server.
|
||||||
jetty.session.mongo.host::::
|
jetty.session.mongo.host::::
|
||||||
Host name or address for the remote MongoDB instance.
|
Host name or address for the remote MongoDB instance.
|
||||||
jetty.session.mongo.port::::
|
jetty.session.mongo.port::::
|
||||||
Port number for the remote MongoDB instance.
|
Port number for the remote MongoDB instance.
|
||||||
connection-type=uri:::
|
connection-type=uri:::
|
||||||
Used when utilizing MongoURI for secured connections.
|
Used when utilizing MongoURI for secured connections.
|
||||||
jetty.session.mongo.connectionString::::
|
jetty.session.mongo.connectionString::::
|
||||||
The string defining the MongoURI value, such as `mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]`.
|
The string defining the MongoURI value, such as `+mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]+`.
|
||||||
More information on how to format the MongoURI string can be found in the https://docs.mongodb.com/manual/reference/connection-string/[official documentation for mongo.]
|
More information on how to format the MongoURI string can be found in the link:https://docs.mongodb.com/manual/reference/connection-string/[official documentation for mongo].
|
||||||
[NOTE]
|
[NOTE]
|
||||||
====
|
====
|
||||||
You will only use *one* `connection-type` at a time, either `address` or `uri`.
|
You will only use *one* `connection-type` at a time, either `address` or `uri`.
|
||||||
If both are utilized in your `session-store-mongo.ini`, only the _last_ `connection-type` configured in the file will be used.
|
If both are utilized in your `session-store-mongo.ini`, only the _last_ `connection-type` configured in the file will be used.
|
||||||
====
|
====
|
||||||
|
|
||||||
jetty.session.gracePeriod.seconds::
|
jetty.session.gracePeriod.seconds::
|
||||||
Integer, in seconds.
|
Integer, in seconds.
|
||||||
Default 3600.
|
Default 3600.
|
||||||
Used during session xref:ops-session-base-scavenge[scavenging].
|
Used during session xref:og-session-base-scavenge[scavenging].
|
||||||
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:ops-session-base-scavenge[scavenged].
|
Multiples of this period are used to define how long ago a stored session must have expired before it should be xref:og-session-base-scavenge[scavenged].
|
||||||
|
|
||||||
jetty.session.savePeriod.seconds::
|
jetty.session.savePeriod.seconds::
|
||||||
Integer, in seconds, default is `0`.
|
Integer, in seconds, default is `0`.
|
||||||
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
Whenever a session is accessed by a request, its `lastAccessTime` and `expiry` are updated.
|
||||||
|
@ -73,4 +76,3 @@ The value of this property is used to skip writes for these kinds of sessions: t
|
||||||
You should be careful in the use of this property in clustered environments: if you set too large a value for this property, the session may not be written out sufficiently often to update its `expiry` time thus making it appear to other nodes that it has expired.
|
You should be careful in the use of this property in clustered environments: if you set too large a value for this property, the session may not be written out sufficiently often to update its `expiry` time thus making it appear to other nodes that it has expired.
|
||||||
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - it would be undesirable to set a `savePeriod` that is larger than the `maxIdleTime`.
|
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - it would be undesirable to set a `savePeriod` that is larger than the `maxIdleTime`.
|
||||||
====
|
====
|
||||||
|
|
|
@ -16,35 +16,40 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[ops-session-overview]]
|
[[og-session-overview]]
|
||||||
|
==== HTTP Session Overview
|
||||||
|
|
||||||
=== Session Overview
|
===== Terminology
|
||||||
|
|
||||||
==== Terminology
|
Before diving into the specifics of how to plug-in and configure various alternative HTTP session management modules, let's review some useful terminology:
|
||||||
|
|
||||||
Before diving into the specifics of how to plug-in and configure various alternative http session management modules, let's review some useful terminology:
|
|
||||||
|
|
||||||
Session::
|
Session::
|
||||||
is a means of retaining information across requests for a particular user.
|
is a means of retaining information across requests for a particular user.
|
||||||
The Servlet Specification defines the semantics of sessions.
|
The Servlet Specification defines the semantics of sessions.
|
||||||
Some of the most important characteristics of sessions is that they have a unique id and that their contents cannot be shared between different contexts (although the id can be): if a session is invalidated in one context, then all other sessions that share the same id in other contexts will also be invalidated.
|
Some of the most important characteristics of sessions is that they have a unique id and that their contents cannot be shared between different contexts (although the id can be): if a session is invalidated in one context, then all other sessions that share the same id in other contexts will also be invalidated.
|
||||||
Sessions can expire or they can be explicitly invalidated.
|
Sessions can expire or they can be explicitly invalidated.
|
||||||
SessionIdManager::
|
|
||||||
|
SessionIdManager::
|
||||||
is responsible for allocating session ids.
|
is responsible for allocating session ids.
|
||||||
Any Jetty server can have at most 1 SessionIdManager.
|
A Jetty server can have at most 1 SessionIdManager.
|
||||||
HouseKeeper::
|
|
||||||
|
HouseKeeper::
|
||||||
is responsible for periodically orchestrating the removal of expired sessions.
|
is responsible for periodically orchestrating the removal of expired sessions.
|
||||||
This process is referred to as xref:ops-session-base-scavenge["scavenging"].
|
This process is referred to as xref:og-session-base-scavenge["scavenging"].
|
||||||
SessionHandler::
|
|
||||||
|
SessionHandler::
|
||||||
is responsible for managing the lifecycle of sessions.
|
is responsible for managing the lifecycle of sessions.
|
||||||
A context can have at most 1 `SessionHandler`.
|
A context can have at most 1 `SessionHandler`.
|
||||||
|
|
||||||
SessionCache::
|
SessionCache::
|
||||||
is an L1 cache of in-use session objects.
|
is a L1 cache of in-use session objects.
|
||||||
The `SessionCache` is used by the `SessionHandler`.
|
The `SessionCache` is used by the `SessionHandler`.
|
||||||
|
|
||||||
SessionDataStore::
|
SessionDataStore::
|
||||||
is responsible for all clustering/persistence operations on sessions.
|
is responsible for all clustering/persistence operations on sessions.
|
||||||
A `SessionCache` uses a `SessionDataStore` as a backing store.
|
A `SessionCache` uses a `SessionDataStore` as a backing store.
|
||||||
CachingSessionDataStore::
|
|
||||||
|
CachingSessionDataStore::
|
||||||
is an L2 cache of session data.
|
is an L2 cache of session data.
|
||||||
A `SessionCache` can use a `CachingSessionDataStore` as its backing store.
|
A `SessionCache` can use a `CachingSessionDataStore` as its backing store.
|
||||||
|
|
||||||
|
@ -52,29 +57,30 @@ More details on these concepts can be found in the link:{PROGGUIDE}/server/sessi
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
====
|
====
|
||||||
`SessionDataStores` interface with other, usually third party, systems responsible for storing and/or distributing session information.
|
``SessionDataStore``s implementations interact with other, usually third party, systems responsible for storing and/or distributing session information.
|
||||||
Sessions can be distributed without being persisted.
|
Sessions can be distributed without being persisted.
|
||||||
They can also be persisted without being distributed.
|
They can also be persisted without being distributed.
|
||||||
Because persisting session information to a shared store is a very common way of distributing (also known as "clustering") sessions, in the documentation we will often refer to just "persisting".
|
Because persisting session information to a shared store is a very common way of distributing (also known as "clustering") sessions, in the documentation we will often refer to just "persisting".
|
||||||
====
|
====
|
||||||
|
|
||||||
==== Session Modules
|
[[og-session-modules]]
|
||||||
|
===== Session Modules
|
||||||
|
|
||||||
There are a number of modules that offer pluggable alternatives for http session management.
|
There are a number of modules that offer pluggable alternatives for http session management.
|
||||||
You can design how you want to cache and store http sessions by selecting alternative combinations of session modules.
|
You can design how you want to cache and store http sessions by selecting alternative combinations of session modules.
|
||||||
|
|
||||||
For example, Jetty ships with two alternative implementations of the `SessionCache`:
|
For example, Jetty ships with two alternative implementations of the `SessionCache`:
|
||||||
|
|
||||||
* one that caches sessions in memory: xref:ops-session-hash[`session-cache-hash`]
|
* one that caches sessions in memory: xref:og-session-cache-hash[`session-cache-hash`]
|
||||||
* one that does not actually cache: xref:ops-session-null[`session-cache-null`]
|
* one that does not actually cache: xref:og-session-cache-null[`session-cache-null`]
|
||||||
|
|
||||||
There are at least 6 alternative implementations of the `SessionDataStore` that you can use to persist/distribute your http sessions:
|
There are at least 6 alternative implementations of the `SessionDataStore` that you can use to persist/distribute your http sessions:
|
||||||
|
|
||||||
* file system storage: xref:ops-session-filesystem[`session-store-file`]
|
* file system storage: xref:og-session-filesystem[`session-store-file`]
|
||||||
* relational database storage: xref:ops-session-jdbc[`session-store-jdbc`]
|
* relational database storage: xref:og-session-jdbc[`session-store-jdbc`]
|
||||||
* NoSQL database storage: xref:ops-session-mongo[`session-store-mongo`]
|
* NoSQL database storage: xref:og-session-mongo[`session-store-mongo`]
|
||||||
* Google Cloud datastore storage: xref:ops-session-gcloud[`session-store-gcloud`]
|
* Google Cloud datastore storage: xref:og-session-gcloud[`session-store-gcloud`]
|
||||||
* Hazelcast: xref:ops-session-hazelcast-remote[`session-store-hazelcast-remote`] or xref:ops-session-hazelcast-embedded[`session-store-hazelcast-embedded`]
|
* Hazelcast: xref:og-session-hazelcast-remote[`session-store-hazelcast-remote`] or xref:og-session-hazelcast-embedded[`session-store-hazelcast-embedded`]
|
||||||
* Infinispan: xref:ops-session-infinispan[`session-store-infinispan-remote`] or xref:ops-session-infinispan-embedded[`session-store-infinispan-embedded`]
|
* Infinispan: xref:og-session-infinispan[`session-store-infinispan-remote`] or xref:og-session-infinispan-embedded[`session-store-infinispan-embedded`]
|
||||||
|
|
||||||
TIP: It is worth noting that if you do not configure _any_ session modules, Jetty will still provide http sessions that are cached in memory but are never persisted.
|
TIP: It is worth noting that if you do not configure _any_ session modules, Jetty will still provide HTTP sessions that are cached in memory but are never persisted.
|
|
@ -16,25 +16,25 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[ops-session-usecases]]
|
[[og-session-usecases]]
|
||||||
=== Session Scenarios
|
==== Session Scenarios
|
||||||
|
|
||||||
==== Minimizing Support for Sessions
|
===== Minimizing Support for Sessions
|
||||||
|
|
||||||
The standard support for webapps in Jetty will use sessions cached in memory, but not persisted/clustered, with a scavenge for expired sessions that occurs every 10mins.
|
The standard support for webapps in Jetty will use sessions cached in memory, but not persisted/clustered, with a scavenge for expired sessions that occurs every 10 minutes.
|
||||||
If you wish to pare back support for sessions because you know your app doesn't use them (or use JSPs that use them), then you can do the following:
|
If you wish to pare back support for sessions because you know your app doesn't use them (or use JSPs that use them), then you can do the following:
|
||||||
|
|
||||||
* enable the xref:ops-session-base[base sessions module] and xref:ops-session-base[configure the scavenge interval] to 0 to prevent scavenging
|
* enable the xref:og-session-base[base sessions module] and xref:og-session-base[configure the scavenge interval] to 0 to prevent scavenging
|
||||||
* enable the xref:ops-session-null[null session cache module] to prevent sessions being cached in memory
|
* enable the xref:og-session-cache-null[null session cache module] to prevent sessions being cached in memory
|
||||||
|
|
||||||
If you wish to do any further minimization, you should consult the link:{PROGGUIDE}[Programming Guide].
|
If you wish to do any further minimization, you should consult the link:{PROGGUIDE}[Programming Guide].
|
||||||
|
|
||||||
==== Clustering with a Sticky Load Balancer
|
===== Clustering with a Sticky Load Balancer
|
||||||
|
|
||||||
Preferably, your cluster will utilize 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.
|
This will route requests for the same session to the same Jetty instance.
|
||||||
In this case, the xref:ops-session-hash[`DefaultSessionCache`] can be used to keep in-use session objects xref:ops-session-hash[in memory].
|
In this case, the xref:og-session-cache-hash[`DefaultSessionCache`] can be used to keep in-use session objects xref:og-session-cache-hash[in memory].
|
||||||
You can fine-tune the cache by controlling how long session objects remain in memory with the xref:ops-session-hash[eviction policy settings].
|
You can fine-tune the cache by controlling how long session objects remain in memory with the xref:og-session-cache-hash[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.
|
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.
|
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.
|
||||||
|
@ -47,13 +47,12 @@ With this policy, session objects will remain in the cache until they either exp
|
||||||
|
|
||||||
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.
|
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
|
||||||
==== Clustering Without a Sticky Load Balancer
|
|
||||||
|
|
||||||
Without a sticky load balancer requests for the same session may arrive on any node in the cluster.
|
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.
|
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 xref:ops-session-null[`NullSessionCache`] or to de-tune the xref:ops-session-hash[`DefaultSessionCache`].
|
In this case, your choices are to use either the xref:og-session-cache-null[`NullSessionCache`] or to de-tune the xref:og-session-cache-hash[`DefaultSessionCache`].
|
||||||
If you use the NullSessionCache all session object caching is avoided.
|
If you use the `NullSessionCache` all session object caching is avoided.
|
||||||
This means that every time a request references a session it must be read in from persistent storage.
|
This means that every time a request references a session it must be read 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 independent session object.
|
It also means that there can be no sharing of session objects for multiple requests for the same session: each will have their own independent session object.
|
||||||
Furthermore, the outcome of session writes are indeterminate because the Servlet Specification does not mandate ACID transactions for sessions.
|
Furthermore, the outcome of session writes are indeterminate because the Servlet Specification does not mandate ACID transactions for sessions.
|
||||||
|
@ -63,10 +62,9 @@ To mitigate this somewhat you can use the `EVICT_ON_SESSION_EXIT` eviction polic
|
||||||
Again, due to the lack of session transactionality, the ordering outcome of write operations cannot be guaranteed.
|
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.
|
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 Unreadable Session Data
|
||||||
==== Handling Corrupted or Unreadable Session Data
|
|
||||||
|
|
||||||
For various reasons it might not be possible for the `SessionDataStore` to re-read a stored session.
|
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 re-deployment there in an incompatible class change.
|
One scenario is that the session stores a serialized object in its attributes, and after a re-deployment there in an incompatible class change.
|
||||||
Setting the `${jetty.base}/start.d/session-cache-hash.ini` or `${jetty.base}/start.d/session-cache-null.ini` property `jetty.session.removeUnloadableSessions` to `true` will allow the unreadable session to be removed from persistent storage.
|
Setting the `$JETTY_BASE/start.d/session-cache-hash.ini` or `$JETTY_BASE/start.d/session-cache-null.ini` property `jetty.session.removeUnloadableSessions` to `true` will allow the unreadable session to be removed from persistent storage.
|
||||||
This can be useful for preventing the xref:ops-session-base-scavenge[scavenger] from continually generating errors on the same expired, but un-readable session.
|
This can be useful for preventing the xref:og-session-base-scavenge[scavenger] from continually generating errors on the same expired, but un-readable session.
|
|
@ -23,7 +23,7 @@ TODO : decide whether to keep this info
|
||||||
With the provided session modules, there is no need to configure a context xml or `jetty-web.xml` file for sessions.
|
With the provided session modules, there is no need to configure a context xml or `jetty-web.xml` file for sessions.
|
||||||
That said, if a user wishes to configure sessions this way, it is possible using xref:jetty-xml-syntax[Jetty IoC XML format.]
|
That said, if a user wishes to configure sessions this way, it is possible using xref:jetty-xml-syntax[Jetty IoC XML format.]
|
||||||
|
|
||||||
Below is an example of how you could configure a the xref:ops-session-filesystem[`FileSessionDataStore`], but the same concept would apply to any of the *SessionDataStores discussed in this chapter:
|
Below is an example of how you could configure a the xref:og-session-filesystem[`FileSessionDataStore`], but the same concept would apply to any of the *SessionDataStores discussed in this chapter:
|
||||||
|
|
||||||
[source, xml, subs="{sub-order}"]
|
[source, xml, subs="{sub-order}"]
|
||||||
----
|
----
|
|
@ -0,0 +1,20 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
include::start-details.adoc[]
|
||||||
|
include::start-jar.adoc[]
|
|
@ -0,0 +1,25 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-start-details]]
|
||||||
|
=== Starting Eclipse Jetty: Details
|
||||||
|
|
||||||
|
// TODO: how start.jar builds a classpath, etc.
|
||||||
|
// how command line overrides base, that overrides home
|
||||||
|
// how you can start Jetty on-the-fly without modules or ini files
|
||||||
|
// etc.
|
|
@ -16,9 +16,11 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
[[start-jar]]
|
[[og-start-jar]]
|
||||||
=== Using start.jar
|
=== Using start.jar
|
||||||
|
|
||||||
|
TODO: review in light of Jetty 10
|
||||||
|
|
||||||
The most basic way of starting the Jetty standalone server is to execute the `start.jar`, which is a bootstrap for starting Jetty with the configuration you want.
|
The most basic way of starting the Jetty standalone server is to execute the `start.jar`, which is a bootstrap for starting Jetty with the configuration you want.
|
||||||
|
|
||||||
[source, screen, subs="{sub-order}"]
|
[source, screen, subs="{sub-order}"]
|
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
include::xml.adoc[]
|
|
@ -0,0 +1,24 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[og-xml]]
|
||||||
|
=== Jetty XML
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
// TODO: port the documentation from old_docs/jetty-xml/*.adoc
|
|
@ -17,45 +17,11 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
:doctitle: Eclipse Jetty: Programming Guide
|
:doctitle: Eclipse Jetty: Programming Guide
|
||||||
:author: Jetty Developers
|
|
||||||
:email: jetty-dev@eclipse.org
|
|
||||||
:revnumber: {version}
|
|
||||||
:revdate: {TIMESTAMP}
|
|
||||||
:toc: left
|
|
||||||
:toc-title: Programming Guide
|
:toc-title: Programming Guide
|
||||||
:toc-style:
|
|
||||||
|
|
||||||
:header-style: eclipse-thin
|
|
||||||
:breadcrumb-style: eclipse-thin
|
|
||||||
:footer-style: default
|
|
||||||
|
|
||||||
:breadcrumb: Home:../index.html | Programming Guide:./index.html
|
:breadcrumb: Home:../index.html | Programming Guide:./index.html
|
||||||
|
:idprefix: pg-
|
||||||
|
|
||||||
// docinfo lets you pull in shared content and/or influence via render type
|
include::../config.adoc[]
|
||||||
//:docinfodir: {DOCINFODIR}/documentation
|
|
||||||
//:docinfo1:
|
|
||||||
|
|
||||||
// html specific directives
|
|
||||||
ifdef::backend-html5[]
|
|
||||||
:safe-mode-unsafe:
|
|
||||||
:stylesdir: ../common/css
|
|
||||||
:stylesheet: jetty.css
|
|
||||||
:linkcss:
|
|
||||||
:scriptsdir: ../common/js
|
|
||||||
endif::[]
|
|
||||||
|
|
||||||
// options for special blocks, code snippets, screen, etc
|
|
||||||
:sub-order: attributes+
|
|
||||||
|
|
||||||
// uncomment to allow include::https:// style content inclusion
|
|
||||||
//:allow-uri-read: true
|
|
||||||
|
|
||||||
// use fonts for admonitions
|
|
||||||
:icons: font
|
|
||||||
|
|
||||||
// suppress automatic id generation
|
|
||||||
:sectids!:
|
|
||||||
|
|
||||||
include::.asciidoctorconfig[]
|
include::.asciidoctorconfig[]
|
||||||
include::introduction.adoc[]
|
include::introduction.adoc[]
|
||||||
include::client/client.adoc[]
|
include::client/client.adoc[]
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[pg-server-session-cachingsessiondatastore]]
|
||||||
|
==== Session Components: The CachingSessionDataStore
|
||||||
|
|
||||||
|
[plantuml]
|
||||||
|
----
|
||||||
|
interface SessionDataMap
|
||||||
|
class CachingSessionDataStore
|
||||||
|
interface SessionDataStore
|
||||||
|
|
||||||
|
CachingSessionDataStore "1" *-down- "1" SessionDataMap
|
||||||
|
CachingSessionDataStore "1" *-down- "1" SessionDataStore
|
||||||
|
SessionDataMap <|-- MemcachedSessionDataMap
|
||||||
|
----
|
||||||
|
|
||||||
|
The `CachingSessionDataStore` is a special type of `SessionDataStore` that checks an L2 cache for `SessionData` before checking a delegate `SessionDataStore`.
|
||||||
|
This can improve the performance of slow stores.
|
||||||
|
|
||||||
|
The L2 cache is an instance of a link:{JDURL}/org/eclipse/jetty/server/session/SessionDataMap.html[SessionDataMap].
|
||||||
|
Jetty provides one implementation of this L2 cache based on `memcached`, link:{JDURL}/org/eclipse/jetty/memcached/session/MemcachedSessionDataMap.html[MemcachedSessionDataMap].
|
||||||
|
|
||||||
|
Here's an example of how to programmatically configure ``CachingSessionDataStore``s, using a `FileSessionDataStore` as a delegate, and `memcached` as the L2 cache:
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
----
|
||||||
|
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java[tags=cachingsds]
|
||||||
|
----
|
||||||
|
|
|
@ -23,15 +23,20 @@ There is one `SessionCache` per `SessionHandler`, and thus one per context.
|
||||||
Its purpose is to provide an L1 cache of `Session` objects.
|
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.
|
Having a working set of `Session` objects in memory allows multiple simultaneous requests for the same session to share the same `Session` object.
|
||||||
A `SessionCache` uses a `SessionDataStore` to create, read, store and delete the `SessionData` associated with the `Session`.
|
A `SessionCache` uses a `SessionDataStore` to create, read, store and delete the `SessionData` associated with the `Session`.
|
||||||
``SessionCache``s can be created by `SessionHandlers` as needed via a `SessionCacheFactory` registered as a bean on the `Server`.
|
|
||||||
Alternatively, you can construct and configure an instance of a `SessionCache` and explicitly set it on a `SessionHander`.
|
There are two ways to create a `SessionCache` for a `SessionHandler`:
|
||||||
Be aware that in this case, you must _also_ ensure your instance is set up with a `SessionDataStore`.
|
|
||||||
If instead the `SessionHandler` uses the `SessionCacheFactory` to create a `SessionCache` instance, it will be responsible for choosing a `SessionDataStore`: if a `SessionDataStoreFactory` bean is found on the `Server` instance, it will use that; otherwise it uses the `NullSessionDataStore`.
|
. allow the `SessionHandler` to create one lazily at startup
|
||||||
More on ``SessionDataStore``s later, in this section we will concentrate the `SessionCache`.
|
The `SessionHandler` looks for a `SessionCacheFactory` bean on the server to produce the `SessionCache` instance.
|
||||||
|
It then looks for a `SessionDataStoreFactory` bean on the server to produce a `SessionDataStore` instance to use with the `SessionCache`.
|
||||||
|
. pass a fully configured `SessionCache` instance to the `SessionHandler`
|
||||||
|
You are responsible for configuring both the `SessionCache` instance and its `SessionDataStore`
|
||||||
|
|
||||||
|
More on ``SessionDataStore``s xref:pg-server-session-sessiondatastore[later], in this section we will concentrate on the `SessionCache` and `SessionCacheFactory`.
|
||||||
|
|
||||||
|
|
||||||
The link:{JDURL}/org/eclipse/jetty/server/session/AbstractSessionCache.html[AbstractSessionCache] provides most of the behaviour of ``SessionCache``s.
|
The link:{JDURL}/org/eclipse/jetty/server/session/AbstractSessionCache.html[AbstractSessionCache] provides most of the behaviour of ``SessionCache``s.
|
||||||
If you are implementing a custom `SessionCache` we recommend you extend this base class, as the Servlet Specification has many subtleties and extending the base class ensures that your implementation will take account of them.
|
If you are implementing a custom `SessionCache` we strongly recommend you extend this base class, as the Servlet Specification has many subtleties and extending the base class ensures that your implementation will take account of them.
|
||||||
|
|
||||||
Some of the important behaviours of ``SessionCache``s are:
|
Some of the important behaviours of ``SessionCache``s are:
|
||||||
|
|
||||||
|
@ -51,7 +56,7 @@ The eviction strategies are:
|
||||||
saveOnInactiveEviction::
|
saveOnInactiveEviction::
|
||||||
This controls whether a session will be persisted to the `SessionDataStore` if it is being evicted due to the EVICT_ON_INACTIVITY policy.
|
This controls whether a session will be persisted to the `SessionDataStore` if it is being evicted due to the EVICT_ON_INACTIVITY policy.
|
||||||
Usually sessions are written to the `SessionDataStore` whenever the last simultaneous request exits the session.
|
Usually sessions are written to the `SessionDataStore` whenever the last simultaneous request exits the session.
|
||||||
However, as `SessionDataStores` can be configured to xref:pg-server-session-sessiondatastore[skip some writes], this option ensures that the session will be written out.
|
However, as `SessionDataStores` can be configured to xref:pg-server-session-sessiondatastore-skip[skip some writes], this option ensures that the session will be written out.
|
||||||
|
|
||||||
saveOnCreate::
|
saveOnCreate::
|
||||||
Usually a session will be written through to the configured `SessionDataStore` when the last request for it finishes.
|
Usually a session will be written through to the configured `SessionDataStore` when the last request for it finishes.
|
||||||
|
@ -99,14 +104,16 @@ The link:{JDURL}/org/eclipse/jetty/server/session/DefaultSessionCache.html#getSe
|
||||||
reset::
|
reset::
|
||||||
The link:{JDURL}/org/eclipse/jetty/server/session/DefaultSessionCache.html#resetStats()[DefaultSessionCache.resetStats()] zeros out the statistics counters.
|
The link:{JDURL}/org/eclipse/jetty/server/session/DefaultSessionCache.html#resetStats()[DefaultSessionCache.resetStats()] zeros out the statistics counters.
|
||||||
|
|
||||||
As a convenience, you can use the link:{JDURL}/org/eclipse/jetty/server/session/DefaultSessionCacheFactory.html[DefaultSessionFactory] to create a `DefaultSessionCache` whenever a new `SessionHandler` is started.
|
If you create a link:{JDURL}/org/eclipse/jetty/server/session/DefaultSessionCacheFactory.html[DefaultSessionFactory] and register it as `Server` bean, a `SessionHandler` will be able to lazily create a `DefaultSessionCache`.
|
||||||
|
The `DefaultSessionCacheFactory` has all of the same configuration setters as a `DefaultSessionCache`.
|
||||||
|
Alternatively, if you only have a single `SessionHandler`, or you need to configure a `DefaultSessionCache` differently for every `SessionHandler`, then you could dispense with the `DefaultSessionCacheFactory` and simply instantiate, configure and pass in the `DefaultSessionCache` yourself.
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
----
|
----
|
||||||
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java[tags=defaultsessioncache]
|
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java[tags=defaultsessioncache]
|
||||||
----
|
----
|
||||||
|
|
||||||
NOTE:: If you don't configure any `SessionCache` or `SessionCacheFactory`, the `SessionHandler` will automatically use a `DefaultSessionCache`.
|
NOTE:: If you don't configure any `SessionCache` or `SessionCacheFactory`, the `SessionHandler` will automatically create a `DefaultSessionCache`.
|
||||||
|
|
||||||
[[pg-server-session-null]]
|
[[pg-server-session-null]]
|
||||||
===== The NullSessionCache
|
===== The NullSessionCache
|
||||||
|
@ -115,6 +122,11 @@ It is suitable for clustered deployments without a sticky load balancer and non-
|
||||||
|
|
||||||
As no sessions are actually cached, of course functions like `invalidateOnShutdown` and all of the eviction strategies have no meaning for the `NullSessionCache`.
|
As no sessions are actually cached, of course functions like `invalidateOnShutdown` and all of the eviction strategies have no meaning for the `NullSessionCache`.
|
||||||
|
|
||||||
|
There is a `NullSessionCacheFactory` which you can instantiate, configure and set as a `Server` bean to enable the `SessionHandler` to automatically create new ``NullCache``s as needed.
|
||||||
|
All of the same configuration options are available on the `NullSessionCacheFactory` as the `NullSessionCache` itself.
|
||||||
|
Alternatively, if you only have a single `SessionHandler`, or you need to configure a `NullSessionCache` differently for every `SessionHandler`, then you could dispense with the `NullSessionCacheFactory` and simply instantiate, configure and pass in the `NullSessionCache` yourself.
|
||||||
|
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
----
|
----
|
||||||
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java[tags=nullsessioncache]
|
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java[tags=nullsessioncache]
|
||||||
|
@ -123,15 +135,15 @@ include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/Sess
|
||||||
[[pg-server-session-customcache]]
|
[[pg-server-session-customcache]]
|
||||||
===== Implementing a Custom SessionCache
|
===== Implementing a Custom SessionCache
|
||||||
|
|
||||||
As previously mentioned, the best thing to do is to extend the `AbstractSessionCache`.
|
As previously mentioned, we highly recommend that you extend the link:{JDURL}/org/eclipse/jetty/server/session/AbstractSessionCache.html[AbstractSessionCache].
|
||||||
|
|
||||||
===== Heterogenous Caching
|
===== Heterogenous Caching
|
||||||
|
|
||||||
Using the `DefaultSessionCacheFactory` or the `NullSessionCacheFactory` will ensure that every time a `SessionHandler` starts, by default it will create a new instance of the corresponding type of `SessionCache`.
|
Using one of the ``SessionCacheFactory``s will ensure that every time a `SessionHandler` starts it will create a new instance of the corresponding type of `SessionCache`.
|
||||||
|
|
||||||
But, what if you deploy multiple webapps, and for one of them, you don't want to use sessions?
|
But, what if you deploy multiple webapps, and for one of them, you don't want to use sessions?
|
||||||
Or alternatively, you don't want to use sessions, but you have one webapp that now needs them?
|
Or alternatively, you don't want to use sessions, but you have one webapp that now needs them?
|
||||||
In that case, you can configure the factory appropriate to the majority, and then specifically create the right type of cache for the others.
|
In that case, you can configure the `SessionCacheFactory` appropriate to the majority, and then specifically create the right type of `SessionCache` for the others.
|
||||||
Here's an example where we configure the `DefaultSessionCacheFactory` to handle most webapps, but then specifically use a `NullSessionCache` for another:
|
Here's an example where we configure the `DefaultSessionCacheFactory` to handle most webapps, but then specifically use a `NullSessionCache` for another:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[pg-server-session-sessiondatastore-file]]
|
||||||
|
==== Session Components: The FileSessionDataStore
|
||||||
|
|
||||||
|
The `FileSessionDataStore` supports persistent storage of session data in a filesystem.
|
||||||
|
|
||||||
|
IMPORTANT: Persisting sessions to the local file system should *never* be used in a clustered environment.
|
||||||
|
|
||||||
|
One file represents one session in one context.
|
||||||
|
|
||||||
|
File names follow this pattern:
|
||||||
|
|
||||||
|
+[expiry]_[contextpath]_[virtualhost]_[id]+
|
||||||
|
|
||||||
|
expiry::
|
||||||
|
This is the expiry time in milliseconds since the epoch.
|
||||||
|
|
||||||
|
contextpath::
|
||||||
|
This is the context path with any special characters, including `/`, replaced by the `_` underscore character.
|
||||||
|
For example, a context path of `/catalog` would become `_catalog`.
|
||||||
|
A context path of simply `/` becomes just `__`.
|
||||||
|
virtualhost::
|
||||||
|
This is the first virtual host associated with the context and has the form of 4 digits separated by `.` characters.
|
||||||
|
If there are no virtual hosts associated with a context, then `0.0.0.0` is used:
|
||||||
|
|
||||||
|
[digit].[digit].[digit].[digit]
|
||||||
|
|
||||||
|
id::
|
||||||
|
This is the unique id of the session.
|
||||||
|
|
||||||
|
Putting all of the above together as an example, a session with an id of `node0ek3vx7x2y1e7pmi3z00uqj1k0` for the context with path `/test` with no virtual hosts and an expiry of `1599558193150` would have a file name of:
|
||||||
|
|
||||||
|
`1599558193150__test_0.0.0.0_node0ek3vx7x2y1e7pmi3z00uqj1k0`
|
||||||
|
|
||||||
|
|
||||||
|
==== Configuration
|
||||||
|
|
||||||
|
You can configure either a `FileSessionDataStore` individually, or a `FileSessionDataStoreFactory` if you want multiple ``SessionHandler``s to use ``FileSessionDataStore``s that are identically configured.
|
||||||
|
The configuration methods are:
|
||||||
|
|
||||||
|
storeDir::
|
||||||
|
This is a File that defines the location for storage of session files.
|
||||||
|
If the directory does not exist at startup, it will be created.
|
||||||
|
If you use the same `storeDir` for multiple `SessionHandlers`, then the sessions for all of those contexts are stored in the same directory.
|
||||||
|
This is not a problem, as the name of the file is unique because it contains the context information.
|
||||||
|
You _must_ supply a value for this, otherwise startup of the `FileSessionDataStore` will fail.
|
||||||
|
|
||||||
|
deleteUnrestorableFiles::
|
||||||
|
Boolean, default `false`.
|
||||||
|
If set to `true`, unreadable files will be deleted.
|
||||||
|
This is useful to prevent repeated logging of the same error when the xref:pg-server-session-housekeeper[scavenger] periodically (re-)attempts to load the corrupted information for a session in order to expire it.
|
||||||
|
|
||||||
|
gracePeriod::
|
||||||
|
See xref:pg-server-session-sessiondata-grace[the gracePeriod].
|
||||||
|
|
||||||
|
savePeriod::
|
||||||
|
See xref:pg-server-session-sessiondata-skip[the savePeriod].
|
||||||
|
|
||||||
|
Let's look at an example of configuring a `FileSessionDataStoreFactory`:
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
----
|
||||||
|
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java[tags=filesessiondatastorefactory]
|
||||||
|
----
|
||||||
|
|
||||||
|
Here's an alternate example, configuring a `FileSessionDataStore` directly:
|
||||||
|
|
||||||
|
[source,java,indent=0]
|
||||||
|
----
|
||||||
|
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java[tags=filesessiondatastore]
|
||||||
|
----
|
|
@ -0,0 +1,160 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
[[pg-server-session-sessiondatastore-jdbc]]
|
||||||
|
==== Session Components: The JDBCSessionDataStore
|
||||||
|
|
||||||
|
The `JDBCSessionDataStore` supports persistent storage of session data in a relational database.
|
||||||
|
To do that, it requires a `DatabaseAdaptor` that handles the differences between databases (eg Oracle, Postgres etc), and a `SessionTableSchema` that allows for the customization of table and column names.
|
||||||
|
|
||||||
|
[plantuml]
|
||||||
|
----
|
||||||
|
class JDBCSessionDataStore
|
||||||
|
class DatabaseAdaptor
|
||||||
|
class SessionTableSchema
|
||||||
|
|
||||||
|
JDBCSessionDataStore "1" *-- "1" DatabaseAdaptor
|
||||||
|
JDBCSessionDataStore "1" *-- "1" SessionTableSchema
|
||||||
|
----
|
||||||
|
|
||||||
|
`SessionData` is stored in a table with one row per session.
|
||||||
|
This is the table, with the table name, column names and type keywords at their default settings:
|
||||||
|
|
||||||
|
|
||||||
|
[caption="Table:"]
|
||||||
|
.JettySessions
|
||||||
|
[frame=all]
|
||||||
|
[cols=12*,options="header"]
|
||||||
|
|===
|
||||||
|
|sessionId
|
||||||
|
|contextPath
|
||||||
|
|virtualHost
|
||||||
|
|lastNode
|
||||||
|
|accessTime
|
||||||
|
|lastAccessTime
|
||||||
|
|createTime
|
||||||
|
|cookieTime
|
||||||
|
|lastSavedTime
|
||||||
|
|expiryTime
|
||||||
|
|maxInterval
|
||||||
|
|map
|
||||||
|
|120 varchar|60 varchar|60 varchar|60 varchar|long|long|long|long|long|long|long|blob
|
||||||
|
|===
|
||||||
|
|
||||||
|
The name of the table and all columns can be configured using the `SessionTableSchema` class described below.
|
||||||
|
Many databases use different keywords for the `long`, `blob` and `varchar` types, so you can explicitly configure these if jetty cannot determine what they should be at runtime based on the metadata available from a db connection using the `DatabaseAdaptor` class described below.
|
||||||
|
|
||||||
|
==== Configuration
|
||||||
|
|
||||||
|
gracePeriod::
|
||||||
|
See xref:pg-server-session-sessiondata-grace[the gracePeriod].
|
||||||
|
|
||||||
|
savePeriod::
|
||||||
|
See xref:pg-server-session-sessiondata-skip[the savePeriod].
|
||||||
|
|
||||||
|
DatabaseAdaptor::
|
||||||
|
The `DatabaseAdaptor` can connect to a database either via a `javax.sql.Datasource` or a `java.sql.Driver`.
|
||||||
|
Additionally, a database-specific keyword can be configured for the `blob`, `varchar` and `long` types.
|
||||||
|
Note that the `DatabaseAdaptor` tries to automatically detect the type of the database from the first connection and select the appropriate type keywords, however you may need to explicitly configure them if you're not using `Postgres` or `Oracle`.
|
||||||
|
|
||||||
|
datasource:::
|
||||||
|
This can either be a `Datasource` instance or the jndi name of a `Datasource` to look up.
|
||||||
|
[source,java,indent=0]
|
||||||
|
----
|
||||||
|
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java[tags=dbaDatasource]
|
||||||
|
----
|
||||||
|
|
||||||
|
driverInfo:::
|
||||||
|
This is the name or instance of a jdbc `Driver` class and a connection url.
|
||||||
|
[source,java,indent=0]
|
||||||
|
----
|
||||||
|
include::../../{doc_code}/org/eclipse/jetty/docs/programming/server/session/SessionDocs.java[tags=dbaDriver]
|
||||||
|
----
|
||||||
|
|
||||||
|
blobType:::
|
||||||
|
Default `blob` or `bytea` for Postgres.
|
||||||
|
|
||||||
|
longType:::
|
||||||
|
Default `bigint` or `number(20)` for Oracle.
|
||||||
|
|
||||||
|
stringType:::
|
||||||
|
Default `varchar`.
|
||||||
|
|
||||||
|
|
||||||
|
SessionTableSchema::
|
||||||
|
schemaName:::
|
||||||
|
catalogName:::
|
||||||
|
The exact meaning of these two are dependent on your database vendor, but can broadly be described as further scoping for the session table name.
|
||||||
|
See https://en.wikipedia.org/wiki/Database_schema and https://en.wikipedia.org/wiki/Database_catalog.
|
||||||
|
These extra scoping names can come into play at startup time when Jetty determines if the session table already exists, or otherwise creates it on-the-fly.
|
||||||
|
If you have employed either of these concepts when you pre-created the session table, or you want to ensure that Jetty uses them when it auto-creates the session table, then you have two options: either set them explicitly, or let Jetty infer them from a database connection.
|
||||||
|
If you leave them unset, then no scoping will be done.
|
||||||
|
If you use the special value `INFERRED`, Jetty will determine them from a database connection.
|
||||||
|
|
||||||
|
tableName:::
|
||||||
|
Default `JettySessions`.
|
||||||
|
This is the name of the table in which session data is stored.
|
||||||
|
|
||||||
|
accessTimeColumn:::
|
||||||
|
Default `accessTime`.
|
||||||
|
This is the name of the column that stores the time - in ms since the epoch - at which a session was last accessed
|
||||||
|
|
||||||
|
contextPathColumn:::
|
||||||
|
Default `contextPath`.
|
||||||
|
This is the name of the column that stores the `contextPath` of a session.
|
||||||
|
|
||||||
|
cookieTimeColumn:::
|
||||||
|
Default `cookieTime`.
|
||||||
|
This is the name of the column that stores the time - in ms since the epoch - that the cookie was last set for a session.
|
||||||
|
|
||||||
|
createTimeColumn:::
|
||||||
|
Default `createTime`.
|
||||||
|
This is the name of the column that stores the time - in ms since the epoch - at which a session was created.
|
||||||
|
|
||||||
|
expiryTimeColumn:::
|
||||||
|
Default `expiryTime`.
|
||||||
|
This is name of the column that stores - in ms since the epoch - the time at which a session will expire.
|
||||||
|
|
||||||
|
lastAccessTimeColumn:::
|
||||||
|
Default `lastAccessTime`.
|
||||||
|
This is the name of the column that stores the time - in ms since the epoch - that a session was previously accessed.
|
||||||
|
|
||||||
|
lastSavedTimeColumn:::
|
||||||
|
Default `lastSavedTime`.
|
||||||
|
This is the name of the column that stores the time - in ms since the epoch - at which a session was last written.
|
||||||
|
|
||||||
|
idColumn:::
|
||||||
|
Default `sessionId`.
|
||||||
|
This is the name of the column that stores the id of a session.
|
||||||
|
|
||||||
|
lastNodeColumn:::
|
||||||
|
Default `lastNode`.
|
||||||
|
This is the name of the column that stores the `workerName` of the last node to write a session.
|
||||||
|
|
||||||
|
virtualHostColumn:::
|
||||||
|
Default `virtualHost`.
|
||||||
|
This is the name of the column that stores the first virtual host of the context of a session.
|
||||||
|
|
||||||
|
maxIntervalColumn:::
|
||||||
|
Default `maxInterval`.
|
||||||
|
This is the name of the column that stores the interval - in ms - during which a session can be idle before being considered expired.
|
||||||
|
|
||||||
|
mapColumn:::
|
||||||
|
Default `map`.
|
||||||
|
This is the name of the column that stores the serialized attributes of a session.
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
[[pg-server-session-sessiondatastore]]
|
[[pg-server-session-sessiondatastore]]
|
||||||
==== Session Components: The SessionDataStore
|
==== Session Components: The SessionDataStore
|
||||||
|
|
||||||
There is one link:{JDURL}/org/eclipse/jetty/server/session/SessionDataStore.html[SessionDataStore] per `SessionCache`.
|
A link:{JDURL}/org/eclipse/jetty/server/session/SessionDataStore.html[SessionDataStore] mediates the storage, retrieval and deletion of `SessionData`.
|
||||||
Its purpose is to create, store, read and delete the `SessionData` related to a `Session`.
|
There is one `SessionDataStore` per `SessionCache`.
|
||||||
The server libraries provide a number of alternative `SessionDataStore` implementations.
|
The server libraries provide a number of alternative `SessionDataStore` implementations.
|
||||||
|
|
||||||
[plantuml]
|
[plantuml]
|
||||||
|
@ -48,50 +48,33 @@ AbstractSessionDataStore <|-- MongoSessionDataStore
|
||||||
SessionDataStore <|-- CachingSessionDataStore
|
SessionDataStore <|-- CachingSessionDataStore
|
||||||
----
|
----
|
||||||
|
|
||||||
The `AbstractSessionDataStore` provides most of the behaviour common to ``SessionDataStore``s.
|
The link:{JDURL}/org/eclipse/jetty/server/session/AbstractSessionDataStore.html[AbstractSessionDataStore] provides most of the behaviour common to ``SessionDataStore``s:
|
||||||
The common characteristics for all ``SessionDataStore``s that derive from `AbstractSessionDataStore` are:
|
|
||||||
|
|
||||||
passivation::
|
passivation::
|
||||||
Supporting passivation means that session data is serialized.
|
Supporting passivation means that session data is serialized.
|
||||||
Some persistence mechanisms serialize, such as JDBC, GCloud Datastore etc.
|
Some persistence mechanisms serialize, such as JDBC, GCloud Datastore etc.
|
||||||
Others store an object in shared memory, e.g. Infinispan.
|
Others store an object in shared memory, e.g. Infinispan and thus don't serialize session data.
|
||||||
Whether or not a clustering technology entails passivation controls whether or not ``HttpSessionActivationListener``s will be called.
|
Whether or not a persistence technology entails passivation controls whether or not ``HttpSessionActivationListener``s will be called.
|
||||||
When implementing a custom `SessionDataStore` you need to decide whether or not passivation will be supported.
|
When implementing a custom `SessionDataStore` you need to decide whether or not passivation will be supported.
|
||||||
|
|
||||||
|
[[pg-server-session-sessiondata-skip]]
|
||||||
savePeriod::
|
savePeriod::
|
||||||
This is an interval defined in seconds.
|
This is an interval defined in seconds.
|
||||||
It is used to reduce the frequency with which `SessionData` is written.
|
It is used to reduce the frequency with which `SessionData` is written.
|
||||||
Normally, whenever the last concurrent request leaves a `Session`, the `SessionData` for that `Session` is always persisted, even if the only thing that changed is the `lastAccessTime`.
|
Normally, whenever the last concurrent request leaves a `Session`, the `SessionData` for that `Session` is always persisted, even if the only thing that changed is the `lastAccessTime`.
|
||||||
If the `savePeriod` is non-zero, the `SessionData` will not be persisted if no session attributes changed, unless the time since the last save exceeds the `savePeriod`.
|
If the `savePeriod` is non-zero, the `SessionData` will not be persisted if no session attributes changed, _unless_ the time since the last save exceeds the `savePeriod`.
|
||||||
Setting a non-zero value can reduce the load on the persistence mechanism, but in a clustered environment runs the risk that other nodes will see the session as expired because it has not been persisted sufficiently recently.
|
Setting a non-zero value can reduce the load on the persistence mechanism, but in a clustered environment runs the risk that other nodes will see the session as expired because it has not been persisted sufficiently recently.
|
||||||
|
|
||||||
|
[[pg-server-session-sessiondata-grace]]
|
||||||
gracePeriod::
|
gracePeriod::
|
||||||
The `gracePeriod` is an interval defined in seconds.
|
The `gracePeriod` is an interval defined in seconds.
|
||||||
It is an attempt to deal with the non-transactional nature of sessions with regard to finding sessions that have expired.
|
It is an attempt to deal with the non-transactional nature of sessions with regard to finding sessions that have expired.
|
||||||
Because the servlet api does not define session transactions, in a clustered configuration - even with a sticky load balancer - it is always possible that a session is live on a node but not yet updated in the persistent store.
|
In a clustered configuration - even with a sticky load balancer - it is always possible that a session is "live" on a node but not yet updated in the persistent store.
|
||||||
This means that it can be hard to determine at any given moment whether a clustered session has truly expired.
|
This means that it can be hard to determine at any given moment whether a clustered session has truly expired.
|
||||||
Thus, we use the `gracePeriod` to provide a bit of leeway around the moment of expiry.
|
Thus, we use the `gracePeriod` to provide a bit of leeway around the moment of expiry during xref:pg-server-session-housekeeper[scavenge]:
|
||||||
The `AbstraceSessionDataStore` uses the `gracePeriod` in the following manner to help xref:pg-server-session-housekeeper[scavenge] expired sessions:
|
|
||||||
|
|
||||||
* on every scavenge cycle it searches for sessions that belong to our context that expired at least one `gracePeriod` ago
|
* on every xref:pg-server-session-housekeeper[scavenge] cycle an `AbstractSessionDataStore` searches for sessions that belong to the context that expired at least one `gracePeriod` ago
|
||||||
* infrequently we also do a scan to find and summarily delete sessions - from any context - that expired at least 10 `gracePeriod``s ago
|
* infrequently the `AbstractSessionDataStore` searches for and summarily deletes sessions - from any context - that expired at least 10 ``gracePeriod``s ago
|
||||||
|
|
||||||
The trivial link:{JDURL}/org/eclipse/jetty/server/session/NullSessionDataStore.html[NullSessionDataStore] - which does not persist sessions - is the default used by the `SessionHandler`.
|
NOTE:: The trivial link:{JDURL}/org/eclipse/jetty/server/session/NullSessionDataStore.html[NullSessionDataStore] - which does not persist sessions - is the default used by the `SessionHandler`.
|
||||||
|
|
||||||
===== CachingSessionDataStore
|
|
||||||
[plantuml]
|
|
||||||
----
|
|
||||||
interface SessionDataMap
|
|
||||||
class CachingSessionDataStore
|
|
||||||
interface SessionDataStore
|
|
||||||
|
|
||||||
CachingSessionDataStore "1" *-down- "1" SessionDataMap
|
|
||||||
CachingSessionDataStore "`" *-down- "1" SessionDataStore
|
|
||||||
----
|
|
||||||
|
|
||||||
The `CachingSessionDataStore` is a special type of `SessionDataStore` that acts as an L2 cache for `SessionData`.
|
|
||||||
It has 2 components: the cache, and the actual backing `SessionDataStore`.
|
|
||||||
The cache is an instance of a link:{JDURL}/org/eclipse/jetty/server/session/SessionDataMap.html[SessionDataMap].
|
|
||||||
The `CachingSessionDataStore` consults this cache before consulting the actual `SessionDataStore`.
|
|
||||||
Using a cache for the `SessionData` can improve the performance of slow stores.
|
|
||||||
|
|
||||||
Jetty provides one implementation of this L2 cache based on `Memcached`, link:{JDURL}/org/eclipse/jetty/memcached/session/MemcachedSessionDataMap.html[MemcachedSessionDataMap].
|
|
||||||
|
|
||||||
|
|
|
@ -20,49 +20,140 @@
|
||||||
==== Session Components: The SessionHandler
|
==== Session Components: The SessionHandler
|
||||||
|
|
||||||
Each context can have a single `SessionHandler`.
|
Each context can have a single `SessionHandler`.
|
||||||
The purpose of the `SessionHandler` is to interact with the `Request` and `Response` to create, maintain and propagate sessions
|
The purpose of the `SessionHandler` is to interact with the `Request` and `Response` to create, maintain and propagate sessions.
|
||||||
It also calls the context-level session listeners at appropriate points in the session lifecycle.
|
It also calls the context-level session listeners at appropriate points in the session lifecycle.
|
||||||
|
|
||||||
|
===== Configuration =====
|
||||||
|
|
||||||
The majority of configuration for the `SessionHandler` can be done via `web.xml` `<session-config>` declarations, or the `javax.servlet.SessionCookieConfig` api.
|
The majority of configuration for the `SessionHandler` can be done via `web.xml` `<session-config>` declarations, or the `javax.servlet.SessionCookieConfig` api.
|
||||||
There are also a few jetty-specific configuration options that we will cover here:
|
There are also a few jetty-specific configuration options that we will cover here:
|
||||||
|
|
||||||
checkingRemoteSessionIdEncoding::
|
checkingRemoteSessionIdEncoding::
|
||||||
Boolean, default `false`.
|
Boolean, default `false`.
|
||||||
This controls whether or not the `javax.servlet.http.Response.encodeURL(String)` method will include the session id as a path parameter when the URL is destined for a remote node.
|
This controls whether or not the `javax.servlet.http.Response.encodeURL(String)` method will include the session id as a path parameter when the URL is destined for a remote node.
|
||||||
|
This can also be configured by:
|
||||||
|
* setting the `org.eclipse.jetty.servlet.CheckingRemoteSessionIdEncoding` context init paramter
|
||||||
|
|
||||||
setMaxInactiveInterval::
|
setMaxInactiveInterval::
|
||||||
Integer, seconds.
|
Integer, seconds.
|
||||||
This is equivalent to the `<session-config><session-timeout/></session-config>` that can be set in `web.xml`, although take note that that in `web.xml` this is specified in _minutes_ but this method uses _seconds_.
|
This is the amount of time after which an unused session may be scavenged.
|
||||||
|
This can also be configured by:
|
||||||
|
|
||||||
|
* defining the `<session-config><session-timeout/></session-config>` element in `web.xml`, although take note that this element is specified in _minutes_ but this method uses _seconds_.
|
||||||
|
* calling the `javax.servlet.ServletContext.setSessionTimeout(int)` method, where the timeout is configured in _minutes_.
|
||||||
|
|
||||||
setHttpOnly::
|
setHttpOnly::
|
||||||
Boolean, default `false`.
|
Boolean, default `false`.
|
||||||
This is equivalent to using `javax.servlet.SessionCookieConfig.setHttpOnly(boolean)` method, or the `<session-config><cookie-config><http-only/></cookie-config></session-config>` element.
|
|
||||||
If `true`, the session cookie will not be exposed to client-side scripting code.
|
If `true`, the session cookie will not be exposed to client-side scripting code.
|
||||||
|
This can also be configured by:
|
||||||
|
|
||||||
|
* using `javax.servlet.SessionCookieConfig.setHttpOnly(boolean)` method
|
||||||
|
* defining the `<session-config><cookie-config><http-only/></cookie-config></session-config>` element in `web.xml`
|
||||||
|
|
||||||
|
[[pg-server-session-refreshcookie]]
|
||||||
refreshCookieAge::
|
refreshCookieAge::
|
||||||
Integer, seconds, default is `-1`.
|
Integer, seconds, default is `-1`.
|
||||||
This controls resetting the session cookie when `SessionCookieConfig.setMaxAge(int)` is non-zero.
|
This controls resetting the session cookie when `SessionCookieConfig.setMaxAge(int)` is non-zero.
|
||||||
|
See also xref:pg-server-session-maxAge[setting the max session cookie age with an init parameter].
|
||||||
If the amount of time since the session cookie was last set exceeds this time, the session cookie is regenerated to keep the session cookie valid.
|
If the amount of time since the session cookie was last set exceeds this time, the session cookie is regenerated to keep the session cookie valid.
|
||||||
|
|
||||||
sameSite::
|
sameSite::
|
||||||
|
`HttpCookie.SameSite`, default `null`.
|
||||||
|
The values are `HttpCookie.SameSite.NONE`, `HttpCookie.SameSite.STRICT`, `HttpCookie.SameSite.LAX`.
|
||||||
|
|
||||||
secureRequestOnly::
|
secureRequestOnly::
|
||||||
Boolean, default true.
|
Boolean, default `true`.
|
||||||
|
If `true` and the request is HTTPS, the set session cookie will be marked as `secure`, meaning the client will only send the session cookie to the server on subsequent requests over HTTPS.
|
||||||
|
This can also be configured by:
|
||||||
|
|
||||||
|
* using the `javax.servlet.SessionCookieConfig.setSecure(true)` method, in which case the set session cookie will _always_ be marked as `secure`, even if the request triggering the creation of the cookie was not over HTTPS.
|
||||||
|
|
||||||
sessionCookie::
|
sessionCookie::
|
||||||
String, default is `JSESSIONID`.
|
String, default is `JSESSIONID`.
|
||||||
|
This is the name of the session cookie.
|
||||||
|
It can alternatively be configured by:
|
||||||
|
|
||||||
|
* using `javax.servlet.SessionCookieConfig.setName(String)` method
|
||||||
|
* setting the `org.eclipse.jetty.servlet.SessionCookie` context init parameter.
|
||||||
|
|
||||||
sessionIdPathParameterName::
|
sessionIdPathParameterName::
|
||||||
String, default is `jsessionid`.
|
String, default is `jsessionid`.
|
||||||
|
This is the name of the path parameter used to transmit the session id on request URLs, and on encoded URLS in responses.
|
||||||
|
It can alternatively be configured by:
|
||||||
|
|
||||||
|
* setting the `org.eclipse.jetty.servlet.SessionIdPathParameterName` context init parameter
|
||||||
|
|
||||||
|
|
||||||
sessionTrackingModes::
|
sessionTrackingModes::
|
||||||
|
`Set<javax.servlet.SessionTrackingMode>`.
|
||||||
|
Default is `SessionTrackingMode.COOKIE`, `SessionTrackingMode.URL`.
|
||||||
|
This can also be configured by:
|
||||||
|
|
||||||
|
* using the `setSessionTrackingModes(Set<javax.servlet.SessionTrackingMode>)` method
|
||||||
|
* using the `javax.servlet.ServletContext.setSessionTrackingModes<Set<javax.servlet.SessionTrackingMode>)` method
|
||||||
|
* defining up to three ``<tracking-mode>``s for the `<session-config>` element in `web.xml`
|
||||||
|
|
||||||
usingCookies::
|
usingCookies::
|
||||||
Boolean, default `true`.
|
Boolean, default `true`.
|
||||||
|
Determines whether or not the `SessionHandler` will look for session cookies on requests, and will set session cookies on responses.
|
||||||
|
If `false` session ids must be transmitted as path params on URLs.
|
||||||
|
This can also be configured by:
|
||||||
|
|
||||||
|
* using the `setSessionTrackingModes(Set<javax.servlet.SessionTrackingMode>)` method
|
||||||
|
* using the `javax.servlet.ServletContext.setSessionTrackingModes<Set<javax.servlet.SessionTrackingMode>)` method
|
||||||
|
|
||||||
|
|
||||||
|
There are also a few session settings that do not have SessionHandler setters, but can be configured with context init parameters:
|
||||||
|
|
||||||
|
[[pg-server-session-maxAge]]
|
||||||
|
org.eclipse.jetty.servlet.MaxAge::
|
||||||
|
This is the maximum number of seconds that the session cookie will be considered to be valid.
|
||||||
|
By default, the cookie has no maximum validity time.
|
||||||
|
See also xref:pg-server-session-refreshcookie[refreshing the session cookie].
|
||||||
|
The value can also be configured by:
|
||||||
|
|
||||||
|
* calling the `SessionCookieConfig.setMaxAge(int)` method.
|
||||||
|
|
||||||
|
|
||||||
|
org.eclipse.jetty.servlet.SessionDomain::
|
||||||
|
String, default `null`.
|
||||||
|
This is the domain of the session cookie.
|
||||||
|
This can also be configured by:
|
||||||
|
|
||||||
|
* using the `javax.servlet.SessionCookieConfig.setDomain(String)` method
|
||||||
|
* defining the `<session-config><cookie-config><domain/></cookie-config></session-config>` element in `web.xml`
|
||||||
|
|
||||||
|
|
||||||
|
org.eclipse.jetty.servlet.SessionPath::
|
||||||
|
String, default `null`.
|
||||||
|
This is used when creating a new session cookie.
|
||||||
|
If nothing is configured, the context path is used instead, defaulting to `/`.
|
||||||
|
This can also be configured by:
|
||||||
|
|
||||||
|
* using the `javax.servlet.SessionCookieConfig.setPath(String)` method
|
||||||
|
* defining the `<session-config><cookie-config><path/></cookie-config></session-config>` element in `web.xml`
|
||||||
|
|
||||||
|
===== Statistics =====
|
||||||
|
|
||||||
|
Some statistics about the sessions for a context can be obtained from the `SessionHandler`, either by calling the methods directly or via `jmx`:
|
||||||
|
|
||||||
|
sessionsCreated::
|
||||||
|
This is the total number of sessions that have been created for this context since Jetty started.
|
||||||
|
|
||||||
|
sessionTimeMax::
|
||||||
|
The longest period of time a session was valid in this context before being invalidated.
|
||||||
|
|
||||||
|
sessionTimeMean::
|
||||||
|
The average period of time a session in this context was valid.
|
||||||
|
|
||||||
|
sessionTimeStdDev::
|
||||||
|
The standard deviation of the session validity times for this context.
|
||||||
|
|
||||||
|
sessionTimeTotal::
|
||||||
|
The total time that all sessions in this context have remained valid.
|
||||||
|
|
||||||
|
You can reset the statistics counters by either calling the following method directly on the the `SessionHandler`, or using `jmx`:
|
||||||
|
|
||||||
|
statsReset::
|
||||||
|
Resets the `SessionHandler` statistics counters.
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ The `DefaultSessionIdManager` uses `SecureRandom` to generate unique session ids
|
||||||
|
|
||||||
The `SessionHandler` class, which is used by both the `ServletContextHandler` and the `WebAppContext` classes, will instantiate a `DefaultSessionIdManager` on startup if it does not detect one already present for the `Server`.
|
The `SessionHandler` class, which is used by both the `ServletContextHandler` and the `WebAppContext` classes, will instantiate a `DefaultSessionIdManager` on startup if it does not detect one already present for the `Server`.
|
||||||
|
|
||||||
Here is an example of explicitly setting up a `DefaultSessionIdManager` in code:
|
Here is an example of explicitly setting up a `DefaultSessionIdManager` with a `workerName` of `server3` in code:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
----
|
----
|
||||||
|
|
|
@ -23,5 +23,9 @@ Sessions are a concept within the Servlet API which allow requests to store and
|
||||||
|
|
||||||
include::session-architecture.adoc[]
|
include::session-architecture.adoc[]
|
||||||
include::session-sessionidmgr.adoc[]
|
include::session-sessionidmgr.adoc[]
|
||||||
|
include::session-sessionhandler.adoc[]
|
||||||
include::session-sessioncache.adoc[]
|
include::session-sessioncache.adoc[]
|
||||||
include::session-sessiondatastore.adoc[]
|
include::session-sessiondatastore.adoc[]
|
||||||
|
include::session-sessiondatastore-file.adoc[]
|
||||||
|
include::session-sessiondatastore-jdbc.adoc[]
|
||||||
|
include::session-cachingsessiondatastore.adoc[]
|
||||||
|
|
|
@ -18,15 +18,26 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.docs.programming.server.session;
|
package org.eclipse.jetty.docs.programming.server.session;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.memcached.session.MemcachedSessionDataMapFactory;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||||
|
import org.eclipse.jetty.server.session.CachingSessionDataStoreFactory;
|
||||||
|
import org.eclipse.jetty.server.session.DatabaseAdaptor;
|
||||||
|
import org.eclipse.jetty.server.session.DefaultSessionCache;
|
||||||
import org.eclipse.jetty.server.session.DefaultSessionCacheFactory;
|
import org.eclipse.jetty.server.session.DefaultSessionCacheFactory;
|
||||||
import org.eclipse.jetty.server.session.DefaultSessionIdManager;
|
import org.eclipse.jetty.server.session.DefaultSessionIdManager;
|
||||||
|
import org.eclipse.jetty.server.session.FileSessionDataStore;
|
||||||
|
import org.eclipse.jetty.server.session.FileSessionDataStoreFactory;
|
||||||
import org.eclipse.jetty.server.session.HouseKeeper;
|
import org.eclipse.jetty.server.session.HouseKeeper;
|
||||||
import org.eclipse.jetty.server.session.NullSessionCache;
|
import org.eclipse.jetty.server.session.NullSessionCache;
|
||||||
import org.eclipse.jetty.server.session.NullSessionCacheFactory;
|
import org.eclipse.jetty.server.session.NullSessionCacheFactory;
|
||||||
import org.eclipse.jetty.server.session.NullSessionDataStore;
|
import org.eclipse.jetty.server.session.NullSessionDataStore;
|
||||||
import org.eclipse.jetty.server.session.SessionCache;
|
import org.eclipse.jetty.server.session.SessionCache;
|
||||||
|
import org.eclipse.jetty.server.session.SessionHandler;
|
||||||
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
|
||||||
public class SessionDocs
|
public class SessionDocs
|
||||||
|
@ -37,7 +48,7 @@ public class SessionDocs
|
||||||
Server server = new Server();
|
Server server = new Server();
|
||||||
DefaultSessionIdManager idMgr = new DefaultSessionIdManager(server);
|
DefaultSessionIdManager idMgr = new DefaultSessionIdManager(server);
|
||||||
//you must set the workerName unless you set the env viable JETTY_WORKER_NAME
|
//you must set the workerName unless you set the env viable JETTY_WORKER_NAME
|
||||||
idMgr.setWorkerName("3");
|
idMgr.setWorkerName("server3");
|
||||||
server.setSessionIdManager(idMgr);
|
server.setSessionIdManager(idMgr);
|
||||||
//end::default[]
|
//end::default[]
|
||||||
}
|
}
|
||||||
|
@ -49,7 +60,7 @@ public class SessionDocs
|
||||||
//tag::housekeeper[]
|
//tag::housekeeper[]
|
||||||
Server server = new Server();
|
Server server = new Server();
|
||||||
DefaultSessionIdManager idMgr = new DefaultSessionIdManager(server);
|
DefaultSessionIdManager idMgr = new DefaultSessionIdManager(server);
|
||||||
idMgr.setWorkerName("7");
|
idMgr.setWorkerName("server7");
|
||||||
server.setSessionIdManager(idMgr);
|
server.setSessionIdManager(idMgr);
|
||||||
|
|
||||||
HouseKeeper houseKeeper = new HouseKeeper();
|
HouseKeeper houseKeeper = new HouseKeeper();
|
||||||
|
@ -65,6 +76,38 @@ public class SessionDocs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void servletContextWithSessionHandler()
|
||||||
|
{
|
||||||
|
//tag:schsession[]
|
||||||
|
Server server = new Server();
|
||||||
|
|
||||||
|
ServletContextHandler context = new ServletContextHandler(server, "/foo", ServletContextHandler.SESSIONS);
|
||||||
|
SessionHandler sessions = context.getSessionHandler();
|
||||||
|
//make idle sessions valid for only 5mins
|
||||||
|
sessions.setMaxInactiveInterval(300);
|
||||||
|
//turn off use of cookies
|
||||||
|
sessions.setUsingCookies(false);
|
||||||
|
|
||||||
|
server.setHandler(context);
|
||||||
|
//end::schsession[]
|
||||||
|
}
|
||||||
|
|
||||||
|
public void webAppWithSessionHandler()
|
||||||
|
{
|
||||||
|
//tag:wacsession[]
|
||||||
|
Server server = new Server();
|
||||||
|
|
||||||
|
WebAppContext context = new WebAppContext();
|
||||||
|
SessionHandler sessions = context.getSessionHandler();
|
||||||
|
//make idle sessions valid for only 5mins
|
||||||
|
sessions.setMaxInactiveInterval(300);
|
||||||
|
//turn off use of cookies
|
||||||
|
sessions.setUsingCookies(false);
|
||||||
|
|
||||||
|
server.setHandler(context);
|
||||||
|
//end::wacsession[]
|
||||||
|
}
|
||||||
|
|
||||||
public void defaultSessionCache()
|
public void defaultSessionCache()
|
||||||
{
|
{
|
||||||
//tag::defaultsessioncache[]
|
//tag::defaultsessioncache[]
|
||||||
|
@ -139,4 +182,110 @@ public class SessionDocs
|
||||||
app2.getSessionHandler().setSessionCache(nullSessionCache);
|
app2.getSessionHandler().setSessionCache(nullSessionCache);
|
||||||
//end::mixedsessioncache[]
|
//end::mixedsessioncache[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void fileSessionDataStoreFactory()
|
||||||
|
{
|
||||||
|
//tag::filesessiondatastorefactory[]
|
||||||
|
Server server = new Server();
|
||||||
|
|
||||||
|
//First lets configure a DefaultSessionCacheFactory
|
||||||
|
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
|
||||||
|
//NEVER_EVICT
|
||||||
|
cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT);
|
||||||
|
cacheFactory.setFlushOnResponseCommit(true);
|
||||||
|
cacheFactory.setInvalidateOnShutdown(false);
|
||||||
|
cacheFactory.setRemoveUnloadableSessions(true);
|
||||||
|
cacheFactory.setSaveOnCreate(true);
|
||||||
|
|
||||||
|
//Add the factory as a bean to the server, now whenever a
|
||||||
|
//SessionHandler starts it will consult the bean to create a new DefaultSessionCache
|
||||||
|
server.addBean(cacheFactory);
|
||||||
|
|
||||||
|
//Now, lets configure a FileSessionDataStoreFactory
|
||||||
|
FileSessionDataStoreFactory storeFactory = new FileSessionDataStoreFactory();
|
||||||
|
storeFactory.setStoreDir(new File("/tmp/sessions"));
|
||||||
|
storeFactory.setGracePeriodSec(3600);
|
||||||
|
storeFactory.setSavePeriodSec(0);
|
||||||
|
|
||||||
|
//Add the factory as a bean on the server, now whenever a
|
||||||
|
//SessionHandler starts, it will consult the bean to create a new FileSessionDataStore
|
||||||
|
//for use by the DefaultSessionCache
|
||||||
|
server.addBean(storeFactory);
|
||||||
|
//end::filesessiondatastorefactory[]
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fileSessionDataStore()
|
||||||
|
{
|
||||||
|
//tag::filesessiondatastore[]
|
||||||
|
|
||||||
|
//create a context
|
||||||
|
WebAppContext app1 = new WebAppContext();
|
||||||
|
app1.setContextPath("/app1");
|
||||||
|
|
||||||
|
//First, we create a DefaultSessionCache
|
||||||
|
DefaultSessionCache cache = new DefaultSessionCache(app1.getSessionHandler());
|
||||||
|
cache.setEvictionPolicy(SessionCache.NEVER_EVICT);
|
||||||
|
cache.setFlushOnResponseCommit(true);
|
||||||
|
cache.setInvalidateOnShutdown(false);
|
||||||
|
cache.setRemoveUnloadableSessions(true);
|
||||||
|
cache.setSaveOnCreate(true);
|
||||||
|
|
||||||
|
//Now, we configure a FileSessionDataStore
|
||||||
|
FileSessionDataStore store = new FileSessionDataStore();
|
||||||
|
store.setStoreDir(new File("/tmp/sessions"));
|
||||||
|
store.setGracePeriodSec(3600);
|
||||||
|
store.setSavePeriodSec(0);
|
||||||
|
|
||||||
|
//Tell the cache to use the store
|
||||||
|
cache.setSessionDataStore(store);
|
||||||
|
|
||||||
|
//Tell the contex to use the cache/store combination
|
||||||
|
app1.getSessionHandler().setSessionCache(cache);
|
||||||
|
|
||||||
|
//end::filesessiondatastore[]
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cachingSessionDataStore()
|
||||||
|
{
|
||||||
|
//tag::cachingsds[]
|
||||||
|
Server server = new Server();
|
||||||
|
|
||||||
|
//Make a factory for memcached L2 caches for SessionData
|
||||||
|
MemcachedSessionDataMapFactory mapFactory = new MemcachedSessionDataMapFactory();
|
||||||
|
mapFactory.setExpirySec(0); //items in memcached don't expire
|
||||||
|
mapFactory.setHeartbeats(true);//tell memcached to use heartbeats
|
||||||
|
mapFactory.setAddresses(new InetSocketAddress("localhost", 11211)); //use a local memcached instance
|
||||||
|
mapFactory.setWeights(new int[] {100}); //set the weighting
|
||||||
|
|
||||||
|
|
||||||
|
//Make a FileSessionDataStoreFactory for creating FileSessionDataStores
|
||||||
|
//to persist the session data
|
||||||
|
FileSessionDataStoreFactory storeFactory = new FileSessionDataStoreFactory();
|
||||||
|
storeFactory.setStoreDir(new File("/tmp/sessions"));
|
||||||
|
storeFactory.setGracePeriodSec(3600);
|
||||||
|
storeFactory.setSavePeriodSec(0);
|
||||||
|
|
||||||
|
//Make a factory that plugs the L2 cache into the SessionDataStore
|
||||||
|
CachingSessionDataStoreFactory cachingSessionDataStoreFactory = new CachingSessionDataStoreFactory();
|
||||||
|
cachingSessionDataStoreFactory.setSessionDataMapFactory(mapFactory);
|
||||||
|
cachingSessionDataStoreFactory.setSessionStoreFactory(storeFactory);
|
||||||
|
|
||||||
|
//Register it as a bean so that all SessionHandlers will use it
|
||||||
|
//to make FileSessionDataStores that use memcached as an L2 SessionData cache.
|
||||||
|
server.addBean(cachingSessionDataStoreFactory);
|
||||||
|
//end::cachingsds[]
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jdbcSessionDataStore()
|
||||||
|
{
|
||||||
|
//tag::dbaDatasource[]
|
||||||
|
DatabaseAdaptor datasourceAdaptor = new DatabaseAdaptor();
|
||||||
|
datasourceAdaptor.setDatasourceName("/jdbc/myDS");
|
||||||
|
//end::dbaDatasource[]
|
||||||
|
|
||||||
|
//tag::dbaDriver[]
|
||||||
|
DatabaseAdaptor driverAdaptor = new DatabaseAdaptor();
|
||||||
|
driverAdaptor.setDriverInfo("com.mysql.jdbc.Driver", "jdbc:mysql://127.0.0.1:3306/sessions?user=sessionsadmin");
|
||||||
|
//end::dbaDriver[]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.util.zip.ZipException;
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
import org.eclipse.jetty.util.BufferUtil;
|
import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.component.Destroyable;
|
import org.eclipse.jetty.util.component.Destroyable;
|
||||||
|
import org.eclipse.jetty.util.compression.InflaterPool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Decoder for the "gzip" content encoding.</p>
|
* <p>Decoder for the "gzip" content encoding.</p>
|
||||||
|
@ -41,9 +42,10 @@ public class GZIPContentDecoder implements Destroyable
|
||||||
private static final long UINT_MAX = 0xFFFFFFFFL;
|
private static final long UINT_MAX = 0xFFFFFFFFL;
|
||||||
|
|
||||||
private final List<ByteBuffer> _inflateds = new ArrayList<>();
|
private final List<ByteBuffer> _inflateds = new ArrayList<>();
|
||||||
private final Inflater _inflater = new Inflater(true);
|
private final InflaterPool _inflaterPool;
|
||||||
private final ByteBufferPool _pool;
|
private final ByteBufferPool _pool;
|
||||||
private final int _bufferSize;
|
private final int _bufferSize;
|
||||||
|
private Inflater _inflater;
|
||||||
private State _state;
|
private State _state;
|
||||||
private int _size;
|
private int _size;
|
||||||
private long _value;
|
private long _value;
|
||||||
|
@ -62,6 +64,13 @@ public class GZIPContentDecoder implements Destroyable
|
||||||
|
|
||||||
public GZIPContentDecoder(ByteBufferPool pool, int bufferSize)
|
public GZIPContentDecoder(ByteBufferPool pool, int bufferSize)
|
||||||
{
|
{
|
||||||
|
this(null, pool, bufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GZIPContentDecoder(InflaterPool inflaterPool, ByteBufferPool pool, int bufferSize)
|
||||||
|
{
|
||||||
|
_inflaterPool = inflaterPool;
|
||||||
|
_inflater = (inflaterPool == null) ? new Inflater(true) : inflaterPool.acquire();
|
||||||
_bufferSize = bufferSize;
|
_bufferSize = bufferSize;
|
||||||
_pool = pool;
|
_pool = pool;
|
||||||
reset();
|
reset();
|
||||||
|
@ -207,8 +216,9 @@ public class GZIPContentDecoder implements Destroyable
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int length = _inflater.inflate(buffer.array(), buffer.arrayOffset(), buffer.capacity());
|
int pos = BufferUtil.flipToFill(buffer);
|
||||||
buffer.limit(length);
|
_inflater.inflate(buffer);
|
||||||
|
BufferUtil.flipToFlush(buffer, pos);
|
||||||
}
|
}
|
||||||
catch (DataFormatException x)
|
catch (DataFormatException x)
|
||||||
{
|
{
|
||||||
|
@ -226,23 +236,10 @@ public class GZIPContentDecoder implements Destroyable
|
||||||
{
|
{
|
||||||
if (!compressed.hasRemaining())
|
if (!compressed.hasRemaining())
|
||||||
return;
|
return;
|
||||||
if (compressed.hasArray())
|
_inflater.setInput(compressed);
|
||||||
{
|
|
||||||
_inflater.setInput(compressed.array(), compressed.arrayOffset() + compressed.position(), compressed.remaining());
|
|
||||||
compressed.position(compressed.limit());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO use the pool
|
|
||||||
byte[] input = new byte[compressed.remaining()];
|
|
||||||
compressed.get(input);
|
|
||||||
_inflater.setInput(input);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (_inflater.finished())
|
else if (_inflater.finished())
|
||||||
{
|
{
|
||||||
int remaining = _inflater.getRemaining();
|
|
||||||
compressed.position(compressed.limit() - remaining);
|
|
||||||
_state = State.CRC;
|
_state = State.CRC;
|
||||||
_size = 0;
|
_size = 0;
|
||||||
_value = 0;
|
_value = 0;
|
||||||
|
@ -386,7 +383,6 @@ public class GZIPContentDecoder implements Destroyable
|
||||||
if (_value != (_inflater.getBytesWritten() & UINT_MAX))
|
if (_value != (_inflater.getBytesWritten() & UINT_MAX))
|
||||||
throw new ZipException("Invalid input size");
|
throw new ZipException("Invalid input size");
|
||||||
|
|
||||||
// TODO ByteBuffer result = output == null ? BufferUtil.EMPTY_BUFFER : ByteBuffer.wrap(output);
|
|
||||||
reset();
|
reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -420,7 +416,12 @@ public class GZIPContentDecoder implements Destroyable
|
||||||
@Override
|
@Override
|
||||||
public void destroy()
|
public void destroy()
|
||||||
{
|
{
|
||||||
_inflater.end();
|
if (_inflaterPool == null)
|
||||||
|
_inflater.end();
|
||||||
|
else
|
||||||
|
_inflaterPool.release(_inflater);
|
||||||
|
|
||||||
|
_inflater = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFinished()
|
public boolean isFinished()
|
||||||
|
|
|
@ -639,22 +639,28 @@ public interface HttpFields extends Iterable<HttpField>
|
||||||
|
|
||||||
public Mutable add(HttpFields fields)
|
public Mutable add(HttpFields fields)
|
||||||
{
|
{
|
||||||
|
if (_fields == null)
|
||||||
|
_fields = new HttpField[fields.size() + 4];
|
||||||
|
else if (_size + fields.size() >= _fields.length)
|
||||||
|
_fields = Arrays.copyOf(_fields, _size + fields.size() + 4);
|
||||||
|
|
||||||
|
if (fields.size() == 0)
|
||||||
|
return this;
|
||||||
|
|
||||||
if (fields instanceof Immutable)
|
if (fields instanceof Immutable)
|
||||||
{
|
{
|
||||||
Immutable b = (Immutable)fields;
|
Immutable b = (Immutable)fields;
|
||||||
_fields = Arrays.copyOf(b._fields, b._fields.length + 4);
|
System.arraycopy(b._fields, 0, _fields, _size, b._fields.length);
|
||||||
_size = b._fields.length;
|
_size += b._fields.length;
|
||||||
}
|
}
|
||||||
else if (fields instanceof Mutable)
|
else if (fields instanceof Mutable)
|
||||||
{
|
{
|
||||||
Mutable b = (Mutable)fields;
|
Mutable b = (Mutable)fields;
|
||||||
_fields = Arrays.copyOf(b._fields, b._fields.length);
|
System.arraycopy(b._fields, 0, _fields, _size, b._size);
|
||||||
_size = b._size;
|
_size += b._size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_fields = new HttpField[fields.size() + 4];
|
|
||||||
_size = 0;
|
|
||||||
for (HttpField f : fields)
|
for (HttpField f : fields)
|
||||||
_fields[_size++] = f;
|
_fields[_size++] = f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,14 +25,14 @@ import org.eclipse.jetty.util.BufferUtil;
|
||||||
import org.eclipse.jetty.util.Trie;
|
import org.eclipse.jetty.util.Trie;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* HTTP and WebSocket Schemes
|
||||||
*/
|
*/
|
||||||
public enum HttpScheme
|
public enum HttpScheme
|
||||||
{
|
{
|
||||||
HTTP("http"),
|
HTTP("http", 80),
|
||||||
HTTPS("https"),
|
HTTPS("https", 443),
|
||||||
WS("ws"),
|
WS("ws", 80),
|
||||||
WSS("wss");
|
WSS("wss", 443);
|
||||||
|
|
||||||
public static final Trie<HttpScheme> CACHE = new ArrayTrie<HttpScheme>();
|
public static final Trie<HttpScheme> CACHE = new ArrayTrie<HttpScheme>();
|
||||||
|
|
||||||
|
@ -46,11 +46,13 @@ public enum HttpScheme
|
||||||
|
|
||||||
private final String _string;
|
private final String _string;
|
||||||
private final ByteBuffer _buffer;
|
private final ByteBuffer _buffer;
|
||||||
|
private final int _defaultPort;
|
||||||
|
|
||||||
HttpScheme(String s)
|
HttpScheme(String s, int port)
|
||||||
{
|
{
|
||||||
_string = s;
|
_string = s;
|
||||||
_buffer = BufferUtil.toBuffer(s);
|
_buffer = BufferUtil.toBuffer(s);
|
||||||
|
_defaultPort = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ByteBuffer asByteBuffer()
|
public ByteBuffer asByteBuffer()
|
||||||
|
@ -60,7 +62,7 @@ public enum HttpScheme
|
||||||
|
|
||||||
public boolean is(String s)
|
public boolean is(String s)
|
||||||
{
|
{
|
||||||
return s != null && _string.equalsIgnoreCase(s);
|
return _string.equalsIgnoreCase(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String asString()
|
public String asString()
|
||||||
|
@ -68,9 +70,31 @@ public enum HttpScheme
|
||||||
return _string;
|
return _string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getDefaultPort()
|
||||||
|
{
|
||||||
|
return _defaultPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int normalizePort(int port)
|
||||||
|
{
|
||||||
|
return port == _defaultPort ? 0 : port;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return _string;
|
return _string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getDefaultPort(String scheme)
|
||||||
|
{
|
||||||
|
HttpScheme httpScheme = scheme == null ? null : CACHE.get(scheme);
|
||||||
|
return httpScheme == null ? HTTP.getDefaultPort() : httpScheme.getDefaultPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int normalizePort(String scheme, int port)
|
||||||
|
{
|
||||||
|
HttpScheme httpScheme = scheme == null ? null : CACHE.get(scheme);
|
||||||
|
return httpScheme == null ? port : httpScheme.normalizePort(port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -638,11 +638,12 @@ public interface HttpURI
|
||||||
|
|
||||||
public Mutable normalize()
|
public Mutable normalize()
|
||||||
{
|
{
|
||||||
if (_port == 80 && HttpScheme.HTTP.is(_scheme))
|
HttpScheme scheme = _scheme == null ? null : HttpScheme.CACHE.get(_scheme);
|
||||||
|
if (scheme != null && _port == scheme.getDefaultPort())
|
||||||
|
{
|
||||||
_port = 0;
|
_port = 0;
|
||||||
if (_port == 443 && HttpScheme.HTTPS.is(_scheme))
|
_uri = null;
|
||||||
_port = 0;
|
}
|
||||||
_uri = null;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -742,6 +742,25 @@ public class HttpFieldsTest
|
||||||
assertThat(fields.size(), is(0));
|
assertThat(fields.size(), is(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddHttpFields()
|
||||||
|
{
|
||||||
|
HttpFields.Mutable fields = new HttpFields.Mutable(new HttpFields.Mutable());
|
||||||
|
fields.add("One", "1");
|
||||||
|
|
||||||
|
fields = new HttpFields.Mutable(fields);
|
||||||
|
|
||||||
|
fields.add(HttpFields.build().add("two", "2").add("three", "3"));
|
||||||
|
fields.add(HttpFields.build().add("four", "4").add("five", "5").asImmutable());
|
||||||
|
|
||||||
|
assertThat(fields.size(), is(5));
|
||||||
|
assertThat(fields.get("one"), is("1"));
|
||||||
|
assertThat(fields.get("two"), is("2"));
|
||||||
|
assertThat(fields.get("three"), is("3"));
|
||||||
|
assertThat(fields.get("four"), is("4"));
|
||||||
|
assertThat(fields.get("five"), is("5"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPutNullName()
|
public void testPutNullName()
|
||||||
{
|
{
|
||||||
|
|
|
@ -109,7 +109,6 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.ant</groupId>
|
<groupId>org.apache.ant</groupId>
|
||||||
<artifactId>ant</artifactId>
|
<artifactId>ant</artifactId>
|
||||||
<version>1.10.8</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<reporting>
|
<reporting>
|
||||||
|
|
|
@ -21,7 +21,7 @@ assert buildLog.text.contains( 'Started Server' )
|
||||||
|
|
||||||
assert buildLog.text.contains( '(1a) >> javax.servlet.ServletContextListener loaded from jar:' )
|
assert buildLog.text.contains( '(1a) >> javax.servlet.ServletContextListener loaded from jar:' )
|
||||||
|
|
||||||
assert buildLog.text.contains( '/org/eclipse/jetty/toolchain/jetty-servlet-api/4.0.3/jetty-servlet-api-4.0.3.jar!/javax/servlet/ServletContextListener.class << (1b)' )
|
assert buildLog.text.contains( '/org/eclipse/jetty/toolchain/jetty-servlet-api/4.0.4/jetty-servlet-api-4.0.4.jar!/javax/servlet/ServletContextListener.class << (1b)' )
|
||||||
|
|
||||||
assert buildLog.text.contains( '(2a) >> mca.common.CommonService loaded from file:' )
|
assert buildLog.text.contains( '(2a) >> mca.common.CommonService loaded from file:' )
|
||||||
assert buildLog.text.contains( 'common/target/classes/mca/common/CommonService.class << (2b)' )
|
assert buildLog.text.contains( 'common/target/classes/mca/common/CommonService.class << (2b)' )
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.eclipse.jetty.quickstart.QuickStartConfiguration;
|
import org.eclipse.jetty.quickstart.QuickStartConfiguration;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
@ -337,17 +338,8 @@ public class WebAppPropertyConverter
|
||||||
* @param resources the resources to convert
|
* @param resources the resources to convert
|
||||||
* @return csv string of resource filenames
|
* @return csv string of resource filenames
|
||||||
*/
|
*/
|
||||||
private static String toCSV(Resource[] resources)
|
private static String toCSV(List<Resource> resources)
|
||||||
{
|
{
|
||||||
StringBuilder rb = new StringBuilder();
|
return resources.stream().map(Object::toString).collect(Collectors.joining(","));
|
||||||
|
|
||||||
for (Resource r : resources)
|
|
||||||
{
|
|
||||||
if (rb.length() > 0)
|
|
||||||
rb.append(",");
|
|
||||||
rb.append(r.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return rb.toString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory;
|
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
import org.objectweb.asm.Opcodes;
|
|
||||||
import org.osgi.framework.Bundle;
|
import org.osgi.framework.Bundle;
|
||||||
import org.osgi.framework.Constants;
|
import org.osgi.framework.Constants;
|
||||||
|
|
||||||
|
@ -145,7 +144,7 @@ public class AnnotationParser extends org.eclipse.jetty.annotations.AnnotationPa
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
boolean hasDotPath = false;
|
boolean hasDotPath = false;
|
||||||
StringTokenizer tokenizer = new StringTokenizer(bundleClasspath, ",;", false);
|
StringTokenizer tokenizer = new StringTokenizer(bundleClasspath, StringUtil.DEFAULT_DELIMS, false);
|
||||||
while (tokenizer.hasMoreTokens())
|
while (tokenizer.hasMoreTokens())
|
||||||
{
|
{
|
||||||
String token = tokenizer.nextToken().trim();
|
String token = tokenizer.nextToken().trim();
|
||||||
|
|
|
@ -233,7 +233,7 @@ public class ServerInstanceWrapper
|
||||||
Thread.currentThread().setContextClassLoader(libExtClassLoader);
|
Thread.currentThread().setContextClassLoader(libExtClassLoader);
|
||||||
|
|
||||||
String jettyConfigurationUrls = (String)props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS);
|
String jettyConfigurationUrls = (String)props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS);
|
||||||
List<URL> jettyConfigurations = jettyConfigurationUrls != null ? Util.fileNamesAsURLs(jettyConfigurationUrls, Util.DEFAULT_DELIMS) : null;
|
List<URL> jettyConfigurations = jettyConfigurationUrls != null ? Util.fileNamesAsURLs(jettyConfigurationUrls, StringUtil.DEFAULT_DELIMS) : null;
|
||||||
|
|
||||||
_server = configure(server, jettyConfigurations, props);
|
_server = configure(server, jettyConfigurations, props);
|
||||||
|
|
||||||
|
@ -418,7 +418,7 @@ public class ServerInstanceWrapper
|
||||||
|
|
||||||
List<URL> libURLs = new ArrayList<>();
|
List<URL> libURLs = new ArrayList<>();
|
||||||
|
|
||||||
StringTokenizer tokenizer = new StringTokenizer(sharedURLs, ",;", false);
|
StringTokenizer tokenizer = new StringTokenizer(sharedURLs, StringUtil.DEFAULT_DELIMS, false);
|
||||||
while (tokenizer.hasMoreTokens())
|
while (tokenizer.hasMoreTokens())
|
||||||
{
|
{
|
||||||
String tok = tokenizer.nextToken();
|
String tok = tokenizer.nextToken();
|
||||||
|
|
|
@ -20,15 +20,12 @@ package org.eclipse.jetty.osgi.boot.internal.webapp;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
|
||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
|
|
||||||
|
@ -201,22 +198,16 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
||||||
@Override
|
@Override
|
||||||
public void addClassPath(String classPath) throws IOException
|
public void addClassPath(String classPath) throws IOException
|
||||||
{
|
{
|
||||||
|
for (Resource resource : Resource.fromList(classPath, false, (path) -> getContext().newResource(path)))
|
||||||
StringTokenizer tokenizer = new StringTokenizer(classPath, ",;");
|
|
||||||
while (tokenizer.hasMoreTokens())
|
|
||||||
{
|
{
|
||||||
String path = tokenizer.nextToken();
|
|
||||||
Resource resource = getContext().newResource(path);
|
|
||||||
|
|
||||||
// Resolve file path if possible
|
|
||||||
File file = resource.getFile();
|
File file = resource.getFile();
|
||||||
if (file != null && isAcceptableLibrary(file, JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED))
|
if (file != null && isAcceptableLibrary(file, JAR_WITH_SUCH_CLASS_MUST_BE_EXCLUDED))
|
||||||
{
|
{
|
||||||
super.addClassPath(path);
|
super.addClassPath(resource);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG.info("Did not add {} to the classloader of the webapp {}", path, getContext());
|
LOG.info("Did not add {} to the classloader of the webapp {}", resource, getContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,37 +263,4 @@ public class OSGiWebappClassLoader extends WebAppClassLoader implements BundleRe
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Field _contextField;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* In the case of the generation of a webapp via a jetty context file we
|
|
||||||
* need a proper classloader to setup the app before we have the
|
|
||||||
* WebappContext So we place a fake one there to start with. We replace it
|
|
||||||
* with the actual webapp context with this method. We also apply the
|
|
||||||
* extraclasspath there at the same time.
|
|
||||||
*
|
|
||||||
* @param webappContext the web app context
|
|
||||||
*/
|
|
||||||
public void setWebappContext(WebAppContext webappContext)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_contextField == null)
|
|
||||||
{
|
|
||||||
_contextField = WebAppClassLoader.class.getDeclaredField("_context");
|
|
||||||
_contextField.setAccessible(true);
|
|
||||||
}
|
|
||||||
_contextField.set(this, webappContext);
|
|
||||||
if (webappContext.getExtraClasspath() != null)
|
|
||||||
{
|
|
||||||
addClassPath(webappContext.getExtraClasspath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Throwable t)
|
|
||||||
{
|
|
||||||
// humf that will hurt if it does not work.
|
|
||||||
LOG.warn("Unable to set webappcontext", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,6 @@ import org.osgi.framework.InvalidSyntaxException;
|
||||||
*/
|
*/
|
||||||
public class Util
|
public class Util
|
||||||
{
|
{
|
||||||
public static final String DEFAULT_DELIMS = ",;";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an osgi filter for the given classname and server name.
|
* Create an osgi filter for the given classname and server name.
|
||||||
*
|
*
|
||||||
|
@ -101,7 +99,7 @@ public class Util
|
||||||
public static List<URL> fileNamesAsURLs(String val, String delims)
|
public static List<URL> fileNamesAsURLs(String val, String delims)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
String separators = DEFAULT_DELIMS;
|
String separators = StringUtil.DEFAULT_DELIMS;
|
||||||
if (delims == null)
|
if (delims == null)
|
||||||
delims = separators;
|
delims = separators;
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.eclipse.jetty.servlet.ServletContextHandler.JspConfig;
|
||||||
import org.eclipse.jetty.servlet.ServletHandler;
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
import org.eclipse.jetty.servlet.ServletMapping;
|
import org.eclipse.jetty.servlet.ServletMapping;
|
||||||
|
import org.eclipse.jetty.servlet.Source;
|
||||||
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
import org.eclipse.jetty.util.QuotedStringTokenizer;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
@ -212,6 +213,9 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration
|
||||||
if (context.getServletHandler().getListeners() != null)
|
if (context.getServletHandler().getListeners() != null)
|
||||||
for (ListenerHolder e : context.getServletHandler().getListeners())
|
for (ListenerHolder e : context.getServletHandler().getListeners())
|
||||||
{
|
{
|
||||||
|
if (e.getSource() == Source.EMBEDDED)
|
||||||
|
continue;
|
||||||
|
|
||||||
out.openTag("listener", origin(md, e.getClassName() + ".listener"))
|
out.openTag("listener", origin(md, e.getClassName() + ".listener"))
|
||||||
.tag("listener-class", e.getClassName())
|
.tag("listener-class", e.getClassName())
|
||||||
.closeTag();
|
.closeTag();
|
||||||
|
@ -223,14 +227,20 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration
|
||||||
{
|
{
|
||||||
for (FilterHolder holder : servlets.getFilters())
|
for (FilterHolder holder : servlets.getFilters())
|
||||||
{
|
{
|
||||||
|
if (holder.getSource() == Source.EMBEDDED)
|
||||||
|
continue;
|
||||||
outholder(out, md, holder);
|
outholder(out, md, holder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (servlets.getFilterMappings() != null)
|
if (servlets.getFilterMappings() != null)
|
||||||
{
|
{
|
||||||
for (FilterMapping mapping : servlets.getFilterMappings())
|
for (FilterMapping mapping :servlets.getFilterMappings())
|
||||||
{
|
{
|
||||||
|
FilterHolder f = servlets.getFilter(mapping.getFilterName());
|
||||||
|
if (f != null && f.getSource() == Source.EMBEDDED)
|
||||||
|
continue;
|
||||||
|
|
||||||
out.openTag("filter-mapping");
|
out.openTag("filter-mapping");
|
||||||
out.tag("filter-name", mapping.getFilterName());
|
out.tag("filter-name", mapping.getFilterName());
|
||||||
if (mapping.getPathSpecs() != null)
|
if (mapping.getPathSpecs() != null)
|
||||||
|
@ -265,6 +275,8 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration
|
||||||
{
|
{
|
||||||
for (ServletHolder holder : servlets.getServlets())
|
for (ServletHolder holder : servlets.getServlets())
|
||||||
{
|
{
|
||||||
|
if (holder.getSource() == Source.EMBEDDED)
|
||||||
|
continue;
|
||||||
outholder(out, md, holder);
|
outholder(out, md, holder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,6 +285,10 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration
|
||||||
{
|
{
|
||||||
for (ServletMapping mapping : servlets.getServletMappings())
|
for (ServletMapping mapping : servlets.getServletMappings())
|
||||||
{
|
{
|
||||||
|
ServletHolder sh = servlets.getServlet(mapping.getServletName());
|
||||||
|
if (sh != null && sh.getSource() == Source.EMBEDDED)
|
||||||
|
continue;
|
||||||
|
|
||||||
out.openTag("servlet-mapping", origin(md, mapping.getServletName() + ".servlet.mappings"));
|
out.openTag("servlet-mapping", origin(md, mapping.getServletName() + ".servlet.mappings"));
|
||||||
out.tag("servlet-name", mapping.getServletName());
|
out.tag("servlet-name", mapping.getServletName());
|
||||||
if (mapping.getPathSpecs() != null)
|
if (mapping.getPathSpecs() != null)
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||||
|
//
|
||||||
|
// This program and the accompanying materials are made available under
|
||||||
|
// the terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
// https://www.eclipse.org/legal/epl-2.0
|
||||||
|
//
|
||||||
|
// This Source Code may also be made available under the following
|
||||||
|
// Secondary Licenses when the conditions for such availability set
|
||||||
|
// forth in the Eclipse Public License, v. 2.0 are satisfied:
|
||||||
|
// the Apache License v2.0 which is available at
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
package org.eclipse.jetty.quickstart;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.servlet.Filter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.FilterConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
|
||||||
|
public class FooFilter implements Filter
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void init(FilterConfig filterConfig) throws ServletException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||||
|
throws IOException, ServletException
|
||||||
|
{
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,19 +19,23 @@
|
||||||
package org.eclipse.jetty.quickstart;
|
package org.eclipse.jetty.quickstart;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URL;
|
import java.util.Arrays;
|
||||||
import java.net.URLClassLoader;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.servlet.FilterHolder;
|
||||||
import org.eclipse.jetty.servlet.ListenerHolder;
|
import org.eclipse.jetty.servlet.ListenerHolder;
|
||||||
import org.eclipse.jetty.servlet.ServletHolder;
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
import org.eclipse.jetty.toolchain.test.FS;
|
import org.eclipse.jetty.toolchain.test.FS;
|
||||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||||
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
@ -42,17 +46,11 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
*/
|
*/
|
||||||
public class TestQuickStart
|
public class TestQuickStart
|
||||||
{
|
{
|
||||||
File testDir;
|
|
||||||
File webInf;
|
|
||||||
Server server;
|
Server server;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp()
|
public void setUp()
|
||||||
{
|
{
|
||||||
testDir = MavenTestingUtils.getTargetTestingDir("foo");
|
|
||||||
FS.ensureEmpty(testDir);
|
|
||||||
webInf = new File(testDir, "WEB-INF");
|
|
||||||
FS.ensureDirExists(webInf);
|
|
||||||
server = new Server();
|
server = new Server();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +63,11 @@ public class TestQuickStart
|
||||||
@Test
|
@Test
|
||||||
public void testProgrammaticOverrideOfDefaultServletMapping() throws Exception
|
public void testProgrammaticOverrideOfDefaultServletMapping() throws Exception
|
||||||
{
|
{
|
||||||
|
File testDir = MavenTestingUtils.getTargetTestingDir("pgoverride");
|
||||||
|
FS.ensureEmpty(testDir);
|
||||||
|
File webInf = new File(testDir, "WEB-INF");
|
||||||
|
FS.ensureDirExists(webInf);
|
||||||
|
|
||||||
File quickstartXml = new File(webInf, "quickstart-web.xml");
|
File quickstartXml = new File(webInf, "quickstart-web.xml");
|
||||||
assertFalse(quickstartXml.exists());
|
assertFalse(quickstartXml.exists());
|
||||||
|
|
||||||
|
@ -87,27 +90,36 @@ public class TestQuickStart
|
||||||
|
|
||||||
assertTrue(quickstartXml.exists());
|
assertTrue(quickstartXml.exists());
|
||||||
|
|
||||||
//now run the webapp again purely from the generated quickstart
|
//now run the webapp again
|
||||||
WebAppContext webapp = new WebAppContext();
|
WebAppContext webapp = new WebAppContext();
|
||||||
webapp.setResourceBase(testDir.getAbsolutePath());
|
webapp.setResourceBase(testDir.getAbsolutePath());
|
||||||
webapp.addConfiguration(new QuickStartConfiguration());
|
webapp.addConfiguration(new QuickStartConfiguration());
|
||||||
|
webapp.getServerClassMatcher().exclude("org.eclipse.jetty.quickstart.");
|
||||||
webapp.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART);
|
webapp.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART);
|
||||||
webapp.setClassLoader(new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()));
|
//add in the servlet
|
||||||
|
webapp.getServletHandler().addServlet(fooHolder);
|
||||||
|
//add in the listener
|
||||||
|
webapp.getServletHandler().addListener(lholder);
|
||||||
|
|
||||||
server.setHandler(webapp);
|
server.setHandler(webapp);
|
||||||
|
|
||||||
server.setDryRun(false);
|
server.setDryRun(false);
|
||||||
server.start();
|
server.start();
|
||||||
server.dumpStdErr();
|
|
||||||
|
|
||||||
//verify that FooServlet is now mapped to / and not the DefaultServlet
|
//verify that FooServlet is now mapped to / and not the DefaultServlet
|
||||||
ServletHolder sh = webapp.getServletHandler().getMappedServlet("/").getServletHolder();
|
ServletHolder sh = webapp.getServletHandler().getMappedServlet("/").getServletHolder();
|
||||||
assertNotNull(sh);
|
assertNotNull(sh);
|
||||||
assertEquals("foo", sh.getName());
|
assertThat(sh.getClassName(), Matchers.equalTo("org.eclipse.jetty.quickstart.FooServlet"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultContextPath() throws Exception
|
public void testDefaultContextPath() throws Exception
|
||||||
{
|
{
|
||||||
|
File testDir = MavenTestingUtils.getTargetTestingDir("dfltcp");
|
||||||
|
FS.ensureEmpty(testDir);
|
||||||
|
File webInf = new File(testDir, "WEB-INF");
|
||||||
|
FS.ensureDirExists(webInf);
|
||||||
|
|
||||||
File quickstartXml = new File(webInf, "quickstart-web.xml");
|
File quickstartXml = new File(webInf, "quickstart-web.xml");
|
||||||
assertFalse(quickstartXml.exists());
|
assertFalse(quickstartXml.exists());
|
||||||
|
|
||||||
|
@ -132,7 +144,7 @@ public class TestQuickStart
|
||||||
webapp.addConfiguration(new QuickStartConfiguration());
|
webapp.addConfiguration(new QuickStartConfiguration());
|
||||||
quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART);
|
quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART);
|
||||||
webapp.setResourceBase(testDir.getAbsolutePath());
|
webapp.setResourceBase(testDir.getAbsolutePath());
|
||||||
webapp.setClassLoader(new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()));
|
webapp.getServerClassMatcher().exclude("org.eclipse.jetty.quickstart.");
|
||||||
server.setHandler(webapp);
|
server.setHandler(webapp);
|
||||||
|
|
||||||
server.setDryRun(false);
|
server.setDryRun(false);
|
||||||
|
@ -146,6 +158,11 @@ public class TestQuickStart
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultRequestAndResponseEncodings() throws Exception
|
public void testDefaultRequestAndResponseEncodings() throws Exception
|
||||||
{
|
{
|
||||||
|
File testDir = MavenTestingUtils.getTargetTestingDir("dfltenc");
|
||||||
|
FS.ensureEmpty(testDir);
|
||||||
|
File webInf = new File(testDir, "WEB-INF");
|
||||||
|
FS.ensureDirExists(webInf);
|
||||||
|
|
||||||
File quickstartXml = new File(webInf, "quickstart-web.xml");
|
File quickstartXml = new File(webInf, "quickstart-web.xml");
|
||||||
assertFalse(quickstartXml.exists());
|
assertFalse(quickstartXml.exists());
|
||||||
|
|
||||||
|
@ -168,7 +185,7 @@ public class TestQuickStart
|
||||||
webapp.addConfiguration(new QuickStartConfiguration());
|
webapp.addConfiguration(new QuickStartConfiguration());
|
||||||
quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART);
|
quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.QUICKSTART);
|
||||||
webapp.setResourceBase(testDir.getAbsolutePath());
|
webapp.setResourceBase(testDir.getAbsolutePath());
|
||||||
webapp.setClassLoader(new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader()));
|
webapp.getServerClassMatcher().exclude("org.eclipse.jetty.quickstart.");
|
||||||
server.setHandler(webapp);
|
server.setHandler(webapp);
|
||||||
|
|
||||||
server.setDryRun(false);
|
server.setDryRun(false);
|
||||||
|
@ -181,6 +198,11 @@ public class TestQuickStart
|
||||||
@Test
|
@Test
|
||||||
public void testListenersNotCalledInPreConfigure() throws Exception
|
public void testListenersNotCalledInPreConfigure() throws Exception
|
||||||
{
|
{
|
||||||
|
File testDir = MavenTestingUtils.getTargetTestingDir("listeners");
|
||||||
|
FS.ensureEmpty(testDir);
|
||||||
|
File webInf = new File(testDir, "WEB-INF");
|
||||||
|
FS.ensureDirExists(webInf);
|
||||||
|
|
||||||
File quickstartXml = new File(webInf, "quickstart-web.xml");
|
File quickstartXml = new File(webInf, "quickstart-web.xml");
|
||||||
assertFalse(quickstartXml.exists());
|
assertFalse(quickstartXml.exists());
|
||||||
|
|
||||||
|
@ -203,4 +225,69 @@ public class TestQuickStart
|
||||||
assertTrue(quickstartXml.exists());
|
assertTrue(quickstartXml.exists());
|
||||||
assertEquals(0, FooContextListener.___initialized);
|
assertEquals(0, FooContextListener.___initialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDuplicateGenerationFromContextXml() throws Exception
|
||||||
|
{
|
||||||
|
File testDir = MavenTestingUtils.getTargetTestingDir("dups");
|
||||||
|
FS.ensureEmpty(testDir);
|
||||||
|
File webInf = new File(testDir, "WEB-INF");
|
||||||
|
FS.ensureDirExists(webInf);
|
||||||
|
|
||||||
|
File quickstartXml = new File(webInf, "quickstart-web.xml");
|
||||||
|
assertFalse(quickstartXml.exists());
|
||||||
|
|
||||||
|
//no servlets, filters or listeners defined in web.xml
|
||||||
|
WebAppContext quickstart = new WebAppContext();
|
||||||
|
quickstart.addConfiguration(new QuickStartConfiguration());
|
||||||
|
quickstart.setWar(testDir.toURI().toURL().toExternalForm());
|
||||||
|
quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.GENERATE);
|
||||||
|
quickstart.setDescriptor(MavenTestingUtils.getTestResourceFile("web.xml").getAbsolutePath());
|
||||||
|
|
||||||
|
//apply the context xml file
|
||||||
|
XmlConfiguration xmlConfig = new XmlConfiguration(Resource.newResource(MavenTestingUtils.getTestResourceFile("context.xml")));
|
||||||
|
xmlConfig.configure(quickstart);
|
||||||
|
|
||||||
|
//generate the quickstart
|
||||||
|
server.setHandler(quickstart);
|
||||||
|
server.setDryRun(true);
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
assertTrue(quickstartXml.exists());
|
||||||
|
assertTrue(server.isStopped());
|
||||||
|
|
||||||
|
//Make a new webappcontext to mimic starting the server over again with
|
||||||
|
//a freshly applied context xml
|
||||||
|
quickstart = new WebAppContext();
|
||||||
|
//need visibility of FooServlet, FooFilter, FooContextListener when we quickstart
|
||||||
|
quickstart.getServerClassMatcher().exclude("org.eclipse.jetty.quickstart.");
|
||||||
|
quickstart.addConfiguration(new QuickStartConfiguration());
|
||||||
|
quickstart.setWar(testDir.toURI().toURL().toExternalForm());
|
||||||
|
quickstart.setDescriptor(MavenTestingUtils.getTestResourceFile("web.xml").getAbsolutePath());
|
||||||
|
quickstart.setAttribute(QuickStartConfiguration.MODE, QuickStartConfiguration.Mode.AUTO);
|
||||||
|
server.setHandler(quickstart);
|
||||||
|
|
||||||
|
//apply the context xml file like a restart would
|
||||||
|
xmlConfig.configure(quickstart);
|
||||||
|
server.setDryRun(false);
|
||||||
|
|
||||||
|
//restart the server
|
||||||
|
server.start();
|
||||||
|
|
||||||
|
//test that we only get 1 FoOServlet, FooFilter and FooContextListener
|
||||||
|
ServletHolder[] servlets = quickstart.getServletHandler().getServlets();
|
||||||
|
assertNotNull(servlets);
|
||||||
|
assertEquals(1,
|
||||||
|
Arrays.stream(servlets).filter(s -> "org.eclipse.jetty.quickstart.FooServlet".equals(s.getClassName())).count());
|
||||||
|
|
||||||
|
FilterHolder[] filters = quickstart.getServletHandler().getFilters();
|
||||||
|
assertNotNull(filters);
|
||||||
|
assertEquals(1,
|
||||||
|
Arrays.stream(filters).filter(f -> "org.eclipse.jetty.quickstart.FooFilter".equals(f.getClassName())).count());
|
||||||
|
|
||||||
|
ListenerHolder[] listeners = quickstart.getServletHandler().getListeners();
|
||||||
|
assertNotNull(listeners);
|
||||||
|
assertEquals(1,
|
||||||
|
Arrays.stream(listeners).filter(l -> "org.eclipse.jetty.quickstart.FooContextListener".equals(l.getClassName())).count());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
|
||||||
|
|
||||||
|
<!-- ==================================================================
|
||||||
|
Configure and deploy the test web application in $(jetty.home)/webapps/test
|
||||||
|
|
||||||
|
Note. If this file did not exist or used a context path other that /test
|
||||||
|
then the default configuration of jetty.xml would discover the test
|
||||||
|
webapplication with a WebAppDeployer. By specifying a context in this
|
||||||
|
directory, additional configuration may be specified and hot deployments
|
||||||
|
detected.
|
||||||
|
===================================================================== -->
|
||||||
|
|
||||||
|
<Configure id="testWebapp" class="org.eclipse.jetty.webapp.WebAppContext">
|
||||||
|
|
||||||
|
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||||
|
<!-- Required minimal context configuration : -->
|
||||||
|
<!-- + contextPath -->
|
||||||
|
<!-- + war OR resourceBase -->
|
||||||
|
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||||
|
<Set name="contextPath">/test</Set>
|
||||||
|
|
||||||
|
<Get name="servletHandler">
|
||||||
|
<Call name="addServletWithMapping">
|
||||||
|
<Arg>
|
||||||
|
<New class="org.eclipse.jetty.servlet.ServletHolder">
|
||||||
|
<Set name="name">FooServlet</Set>
|
||||||
|
<Set name="className">org.eclipse.jetty.quickstart.FooServlet</Set>
|
||||||
|
</New>
|
||||||
|
</Arg>
|
||||||
|
<Arg>/outer/*</Arg>
|
||||||
|
</Call>
|
||||||
|
|
||||||
|
<Call name="addFilterWithMapping">
|
||||||
|
<Arg>
|
||||||
|
<New class="org.eclipse.jetty.servlet.FilterHolder">
|
||||||
|
<Set name="className">org.eclipse.jetty.quickstart.FooFilter</Set>
|
||||||
|
<Set name="name">OuterFilter</Set>
|
||||||
|
</New>
|
||||||
|
</Arg>
|
||||||
|
<Arg>/outer/*</Arg>
|
||||||
|
<Arg type="java.lang.Integer">0</Arg>
|
||||||
|
</Call>
|
||||||
|
|
||||||
|
<Call name="addListener">
|
||||||
|
<Arg>
|
||||||
|
<New class="org.eclipse.jetty.servlet.ListenerHolder">
|
||||||
|
<Set name="listener">
|
||||||
|
<New class="org.eclipse.jetty.quickstart.FooContextListener"></New>
|
||||||
|
</Set>
|
||||||
|
</New>
|
||||||
|
</Arg>
|
||||||
|
</Call>
|
||||||
|
|
||||||
|
</Get>
|
||||||
|
|
||||||
|
</Configure>
|
|
@ -16,10 +16,16 @@
|
||||||
<Set name="checkGzExists" property="jetty.gzip.checkGzExists"/>
|
<Set name="checkGzExists" property="jetty.gzip.checkGzExists"/>
|
||||||
<Set name="compressionLevel" property="jetty.gzip.compressionLevel"/>
|
<Set name="compressionLevel" property="jetty.gzip.compressionLevel"/>
|
||||||
<Set name="inflateBufferSize" property="jetty.gzip.inflateBufferSize"/>
|
<Set name="inflateBufferSize" property="jetty.gzip.inflateBufferSize"/>
|
||||||
|
<Set name="inflaterPoolCapacity" property="jetty.gzip.inflaterPoolCapacity"/>
|
||||||
<Set name="deflaterPoolCapacity" property="jetty.gzip.deflaterPoolCapacity"/>
|
<Set name="deflaterPoolCapacity" property="jetty.gzip.deflaterPoolCapacity"/>
|
||||||
<Set name="syncFlush" property="jetty.gzip.syncFlush"/>
|
<Set name="syncFlush" property="jetty.gzip.syncFlush"/>
|
||||||
|
<Set name="dispatcherTypes" property="jetty.gzip.dispatcherTypes"/>
|
||||||
<Set name="includedMethodList" property="jetty.gzip.includedMethodList"/>
|
<Set name="includedMethodList" property="jetty.gzip.includedMethodList"/>
|
||||||
<Set name="excludedMethodList" property="jetty.gzip.excludedMethodList"/>
|
<Set name="excludedMethodList" property="jetty.gzip.excludedMethodList"/>
|
||||||
|
<Set name="includedMimeTypes" property="jetty.gzip.includedMimeTypeList"/>
|
||||||
|
<Set name="excludedMimeTypes" property="jetty.gzip.excludedMimeTypeList"/>
|
||||||
|
<Set name="includedPaths" property="jetty.gzip.includedPathList"/>
|
||||||
|
<Set name="excludedPaths" property="jetty.gzip.excludedPathList"/>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<Set name="includedMethods">
|
<Set name="includedMethods">
|
||||||
|
|
|
@ -27,11 +27,32 @@ etc/jetty-gzip.xml
|
||||||
## Inflate request buffer size, or 0 for no request inflation
|
## Inflate request buffer size, or 0 for no request inflation
|
||||||
# jetty.gzip.inflateBufferSize=0
|
# jetty.gzip.inflateBufferSize=0
|
||||||
|
|
||||||
## Deflater pool max size (-1 for unlimited, 0 for no pool)
|
## Deflater pool max size (-1 for unlimited, 0 for no pooling)
|
||||||
# jetty.gzip.deflaterPoolCapacity=-1
|
# jetty.gzip.deflaterPoolCapacity=-1
|
||||||
|
|
||||||
## Comma separated list of included methods
|
## Inflater pool max size (-1 for unlimited, 0 for no pooling)
|
||||||
|
# jetty.gzip.inflaterPoolCapacity=-1
|
||||||
|
|
||||||
|
## Set the {@link Deflater} flush mode to use.
|
||||||
|
# jetty.gzip.syncFlush=false
|
||||||
|
|
||||||
|
## The set of DispatcherType that this filter will operate on
|
||||||
|
# jetty.gzip.dispatcherTypes=REQUEST
|
||||||
|
|
||||||
|
## Comma separated list of included HTTP methods
|
||||||
# jetty.gzip.includedMethodList=GET,POST
|
# jetty.gzip.includedMethodList=GET,POST
|
||||||
|
|
||||||
## Comma separated list of excluded methods
|
## Comma separated list of excluded HTTP methods
|
||||||
# jetty.gzip.excludedMethodList=
|
# jetty.gzip.excludedMethodList=
|
||||||
|
|
||||||
|
## Comma separated list of included MIME types
|
||||||
|
# jetty.gzip.includedMimeTypeList=
|
||||||
|
|
||||||
|
## Comma separated list of excluded MIME types
|
||||||
|
# jetty.gzip.excludedMimeTypeList=
|
||||||
|
|
||||||
|
## Comma separated list of included Path specs
|
||||||
|
# jetty.gzip.includedPathList=
|
||||||
|
|
||||||
|
## Comma separated list of excluded Path specs
|
||||||
|
# jetty.gzip.excludedPathList=
|
||||||
|
|
|
@ -13,6 +13,7 @@ ssl
|
||||||
ssl
|
ssl
|
||||||
|
|
||||||
[optional]
|
[optional]
|
||||||
|
alpn
|
||||||
http2
|
http2
|
||||||
http-forwarded
|
http-forwarded
|
||||||
|
|
||||||
|
|
|
@ -59,9 +59,6 @@ etc/jetty-ssl-context.xml
|
||||||
## Connect Timeout in milliseconds
|
## Connect Timeout in milliseconds
|
||||||
# jetty.ssl.connectTimeout=15000
|
# jetty.ssl.connectTimeout=15000
|
||||||
|
|
||||||
## Whether SNI is required for all secure connections. Rejections are in TLS handshakes.
|
|
||||||
# jetty.sslContext.sniRequired=false
|
|
||||||
|
|
||||||
## Whether SNI is required for all secure connections. Rejections are in HTTP 400 response.
|
## Whether SNI is required for all secure connections. Rejections are in HTTP 400 response.
|
||||||
# jetty.ssl.sniRequired=false
|
# jetty.ssl.sniRequired=false
|
||||||
|
|
||||||
|
@ -78,6 +75,9 @@ etc/jetty-ssl-context.xml
|
||||||
## Note that OBF passwords are not secure, just protected from casual observation
|
## Note that OBF passwords are not secure, just protected from casual observation
|
||||||
## See http://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html
|
## See http://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html
|
||||||
|
|
||||||
|
## Whether SNI is required for all secure connections. Rejections are in TLS handshakes.
|
||||||
|
# jetty.sslContext.sniRequired=false
|
||||||
|
|
||||||
## The Endpoint Identification Algorithm
|
## The Endpoint Identification Algorithm
|
||||||
## Same as javax.net.ssl.SSLParameters#setEndpointIdentificationAlgorithm(String)
|
## Same as javax.net.ssl.SSLParameters#setEndpointIdentificationAlgorithm(String)
|
||||||
#jetty.sslContext.endpointIdentificationAlgorithm=
|
#jetty.sslContext.endpointIdentificationAlgorithm=
|
||||||
|
@ -86,10 +86,10 @@ etc/jetty-ssl-context.xml
|
||||||
# jetty.sslContext.provider=
|
# jetty.sslContext.provider=
|
||||||
|
|
||||||
## Keystore file path (relative to $jetty.base)
|
## Keystore file path (relative to $jetty.base)
|
||||||
# jetty.sslContext.keyStorePath=etc/keystore
|
# jetty.sslContext.keyStorePath=etc/keystore.p12
|
||||||
|
|
||||||
## Truststore file path (relative to $jetty.base)
|
## Truststore file path (relative to $jetty.base)
|
||||||
# jetty.sslContext.trustStorePath=etc/keystore
|
# jetty.sslContext.trustStorePath=etc/keystore.p12
|
||||||
|
|
||||||
## Keystore password
|
## Keystore password
|
||||||
# jetty.sslContext.keyStorePassword=
|
# jetty.sslContext.keyStorePassword=
|
||||||
|
|
|
@ -210,7 +210,7 @@ public class CachedContentFactory implements HttpContent.ContentFactory
|
||||||
return (len > 0 && (_useFileMappedBuffer || (len < _maxCachedFileSize && len < _maxCacheSize)));
|
return (len > 0 && (_useFileMappedBuffer || (len < _maxCachedFileSize && len < _maxCacheSize)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpContent load(String pathInContext, Resource resource, int maxBufferSize)
|
private HttpContent load(String pathInContext, Resource resource, int maxBufferSize) throws IOException
|
||||||
{
|
{
|
||||||
if (resource == null || !resource.exists())
|
if (resource == null || !resource.exists())
|
||||||
return null;
|
return null;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue