Standard Modules
Module alpn
The alpn
module enables support for the ALPN negotiation mechanism of the TLS protocol.
You can configure the list of application protocols negotiated by the ALPN mechanism, as well as the default protocol to use if the ALPN negotiation fails (for example, the client does not support ALPN).
The module properties are:
## Specifies the ordered list of application protocols supported by the server. ## The default list is specified by the list of the protocol modules that have ## been enabled, and the order is specified by the module dependencies. # jetty.alpn.protocols=h2,http/1.1 ## Specifies the protocol to use when the ALPN negotiation fails. # jetty.alpn.defaultProtocol=http/1.1
Module bytebufferpool
The bytebufferpool
module allows you to configure the server-wide ByteBuffer
pool.
Pooling ByteBuffer
s results in less memory usage and less pressure on the Garbage Collector.
ByteBuffer
s are pooled in buckets; each bucket as a capacity that is a multiple of a capacity factor that you can configure.
For example, if a request for a ByteBuffer
of capacity 2000 is requested, and the capacity factor is 1024, then the pool will allocate a buffer from the second bucket, of capacity 2048 (1024 * 2).
Applications that need to sustain many concurrent requests — or load spikes — may require many buffers during peak load. These buffers will remain pooled once the system transitions to a lighter load (or becomes idle), and it may be undesirable to retain a lot of memory for an idle system.
It is possible to configure the max heap memory and the max direct memory that the pool retains. Excess buffers will not be pooled and will be eventually garbage collected.
The module file is $JETTY_HOME/modules/bytebufferpool.mod
:
[description] Configures the ByteBufferPool used by ServerConnectors. The bucket sizes increase linearly. Use module "bytebufferpool-quadratic" for a pool that holds more coarse sized buffers. [depends] logging [xml] etc/jetty-bytebufferpool.xml [ini-template] ## Minimum capacity of a single ByteBuffer. #jetty.byteBufferPool.minCapacity=0 ## Maximum capacity of a single ByteBuffer. ## Requests for ByteBuffers larger than this value results ## in the ByteBuffer being allocated but not pooled. #jetty.byteBufferPool.maxCapacity=65536 ## Bucket capacity factor. ## ByteBuffers are allocated out of buckets that have ## a capacity that is multiple of this factor. #jetty.byteBufferPool.factor=4096 ## Maximum size for each bucket (-1 for unbounded). #jetty.byteBufferPool.maxBucketSize=-1 ## Maximum heap memory held idle by the pool (0 for heuristic, -1 for unlimited). #jetty.byteBufferPool.maxHeapMemory=0 ## Maximum direct memory held idle by the pool (0 for heuristic, -1 for unlimited). #jetty.byteBufferPool.maxDirectMemory=0 ## Whether statistics are enabled. #jetty.byteBufferPool.statisticsEnabled=false
Among the configurable properties, the most relevant are:
jetty.byteBufferPool.maxHeapMemory
-
This property allows you to cap the max heap memory retained by the pool.
jetty.byteBufferPool.maxDirectMemory
-
This property allows you to cap the max direct memory retained by the pool.
Module connectionlimit
The connectionlimit
module limits the number of connections accepted by the server, across all connectors.
Once the configured maximum number of connections is reached, Jetty will not accept more connections. Existing, established connections will work normally. When existing connections are closed, accepting new connections will be resumed.
The number of connections seen at the JVM level may be different from the number of connections seen at the OS level. For more information, refer to this section. |
The module file is $JETTY_HOME/modules/connectionlimit.mod
:
The maximum number of TCP connections allowed across all connectors.
#jetty.connectionlimit.maxConnections=1000
The idle timeout to apply (in milliseconds) to existing connections when the connection limit is reached.
#jetty.connectionlimit.idleTimeout=1000
Module console-capture
The console-capture
module captures System.out
and System.err
output and appends it to a rolling file.
The file is rolled every day at the midnight of the configured timezone.
Old, rolled files are kept for the number of days specified by the jetty.console-capture.retainDays
property.
The module properties are:
## Logging directory (relative to $JETTY_BASE). # jetty.console-capture.dir=./logs ## Whether to append to existing file. # jetty.console-capture.append=true ## How many days to retain old log files. # jetty.console-capture.retainDays=90 ## Timezone ID of the log timestamps, as specified by java.time.ZoneId. # jetty.console-capture.timezone=GMT
Module core-deploy
This module enables webapp deployment from the $JETTY_BASE/webapps
directory.
Deployment is managed via a DeploymentManager
component that watches a directory for changes.
See how to deploy web applications for more information.
TODO
Module cross-origin
The cross-origin
module provides support for the CORS protocol implemented by browsers when performing cross-origin requests.
This module installs the CrossOriginHandler
in the Handler
tree; CrossOriginHandler
inspects cross-origin requests and adds the relevant CORS response headers.
CrossOriginHandler
should be used when an application performs cross-origin requests to your domain, to protect from cross-site request forgery attacks.
The module properties are:
## Whether cross-origin requests can include credentials such as cookies or authentication headers. # jetty.crossorigin.allowCredentials=false ## A comma-separated list of headers allowed in cross-origin requests. # jetty.crossorigin.allowedHeaders=Content-Type ## A comma-separated list of HTTP methods allowed in cross-origin requests. # jetty.crossorigin.allowedMethods=GET,POST,HEAD ## A comma-separated list of origins regex patterns allowed in cross-origin requests. # jetty.crossorigin.allowedOriginPatterns= ## A comma-separated list of timing origins regex patterns allowed in cross-origin requests. # jetty.crossorigin.allowedTimingOriginPatterns= ## Whether preflight requests are delivered to the child Handler of CrossOriginHandler. # jetty.crossorigin.deliverPreflightRequests=false ## Whether requests whose origin is not allowed are delivered to the child Handler of CrossOriginHandler. # jetty.crossorigin.deliverNonAllowedOriginRequests=true ## Whether WebSocket upgrade requests whose origin is not allowed are delivered to the child Handler of CrossOriginHandler. # jetty.crossorigin.deliverNonAllowedOriginWebSocketUpgradeRequests=false ## A comma-separated list of headers allowed in cross-origin responses. # jetty.crossorigin.exposedHeaders= ## How long the preflight results can be cached by browsers, in seconds. # jetty.crossorigin.preflightMaxAge=60
Module debuglog
The debuglog
module logs extra information about request processing.
This module installs the DebugHandler
into the handler tree and logs information into a rollover log file.
By default, the location of the log file is $JETTY_BASE/logs
, although this can be configured via the jetty.debuglog.dir
.
The name of the log file is of the form: yyyy_mm_dd.debug.log
, for example 2024-10-01.debug.log
.
All deployed contexts will write to the same log file.
Note that if a request uses asynchronous processing, the log event for the completion of handling may occur out of order with the log event for the continuation of processing.
If more precise logging of request processing is required - including well-ordered async processing events - or you wish to constrain request debug logging to particular contexts only, then configure an ee-specific DebugListener
for each context instead of using this module.
The module properties are:
## Logging directory (relative to $jetty.base) # jetty.debuglog.dir=logs ## Whether to append to existing file # jetty.debuglog.append=false ## How many days to retain old log files # jetty.debuglog.retainDays=90 ## Timezone of the log entries # jetty.debuglog.timezone=GMT ## Show Request/Response headers # jetty.debug.showHeaders=true
Module ee{8,9,10}-deploy
This module enables webapp deployment from the $JETTY_BASE/webapps
directory.
Deployment is managed via a DeploymentManager
component that watches a directory for changes.
See how to deploy web applications for more information.
Adding files or directories to this monitored directory will cause the DeploymentManager
to deploy them as web applications; updating files already existing in this monitored directory will cause the DeploymentManager
to re-deploy the corresponding web application; removing files in this monitored directory will cause the DeploymentManager
to "undeploy" the corresponding web application.
(You can find a more detailed discussion of these rules in the deployment rules section.)
Multiple versions of this module exist (ee{8,9,10}-deploy
) to support each Jakarta EE platform’s version of the Java Servlet specification.
Jetty’s configuration properties are nearly identical across these versions; the configuration properties for the ee10-deploy
Jetty module are:
## Monitored directory name (relative to $jetty.base) # jetty.deploy.monitoredDir=webapps ## Defaults Descriptor for all deployed webapps # jetty.deploy.defaultsDescriptorPath=${jetty.base}/etc/webdefault-ee10.xml ## Monitored directory scan period (seconds) # jetty.deploy.scanInterval=0 ## Whether to extract *.war files # jetty.deploy.extractWars=true ## Whether to give the parent classloader priority # jetty.deploy.parentLoaderPriority=true ## Comma separated list of configuration classes to set. # jetty.deploy.configurationClasses= ## Pattern to select jars from the container classloader to be scanned (or null to scan no jars) # jetty.deploy.containerScanJarPattern=.*/jakarta.servlet-api-[^/]*\.jar$|.*jakarta.servlet.jsp.jstl-.*\.jar$ ## Pattern to select jars from the container classloader to be scanned (or null to scan all jars). # jetty.deploy.webInfScanJarPattern= ## Pattern to exclude discovered ServletContainerInitializers # jetty.deploy.servletContainerInitializerExclusionPattern= ## Order of discovered ServletContainerInitializers # jetty.deploy.servletContainerInitializerOrder=
Among the configurable properties, the most relevant are:
jetty.deploy.monitoredDir
-
The name of the monitored directory.
jetty.deploy.scanInterval
-
The scan period in seconds, that is how frequently the
DeploymentManager
wakes up to scan the monitored directory for changes. Settingjetty.deploy.scanInterval=0
disabled hot deployment so that only static deployment will be possible (see also here for more information).
Module ee{8,9,10}-webapp
This module enables deployment of Java Servlet web applications.
Multiple versions of this module exist (ee{8,9,10}-webapp
) to support each Jakarta EE platform’s version of the Java Servlet specification.
Jetty’s configuration properties are identical across all versions of this module, and are as follows:
## Add to the environment wide default jars and packages protected or hidden from webapps. ## Protected (aka System) classes cannot be overridden by a webapp. ## Hidden (aka Server) classes cannot be seen by a webapp ## Lists of patterns are comma separated and may be either: ## + a qualified classname e.g. 'com.acme.Foo' ## + a package name e.g. 'net.example.' ## + a jar file e.g. '${jetty.base.uri}/lib/dependency.jar' ## + a directory of jars,resource or classes e.g. '${jetty.base.uri}/resources' ## + A pattern preceded with a '-' is an exclusion, all other patterns are inclusions ## ## The +=, operator appends to a CSV list with a comma as needed. ## #jetty.webapp.addProtectedClasses+=,org.example. #jetty.webapp.addHiddenClasses+=,org.example.
Module graceful
The graceful
module allows to shut down gracefully the Jetty server when it is stopped (see this section for more information about stopping Jetty).
The graceful
module installs the GracefulHandler
at the root of the Handler
tree; the GracefulHandler
rejects new requests, but allows current requests to terminate within a configurable timeout, as explained in this section.
The module properties are:
## The timeout, in milliseconds, to apply when stopping the server gracefully. # jetty.server.stopTimeout=5000
Module http
The http
module provides the clear-text connector and support for the clear-text HTTP/1.1 protocol, and depends on the server
module.
The module properties to configure the clear-text connector are:
### Clear-Text HTTP Connector Configuration ## The host/address to bind the connector to. # jetty.http.host=0.0.0.0 ## The port the connector listens on. # jetty.http.port=8080 ## The connector idle timeout, in milliseconds. # jetty.http.idleTimeout=30000 ## The number of acceptors (-1 picks a default value based on number of cores). # jetty.http.acceptors=1 ## The number of selectors (-1 picks a default value based on number of cores). # jetty.http.selectors=-1 ## The ServerSocketChannel accept queue backlog (0 picks the platform default). # jetty.http.acceptQueueSize=0 ## The thread priority delta to give to acceptor threads. # jetty.http.acceptorPriorityDelta=0 ## Whether to enable the SO_REUSEADDR socket option. # jetty.http.reuseAddress=true ## Whether to enable the SO_REUSEPORT socket option. # jetty.http.reusePort=false ## Whether to enable the TCP_NODELAY socket option on accepted sockets. # jetty.http.acceptedTcpNoDelay=true ## The SO_RCVBUF socket option to set on accepted sockets. ## A value of -1 indicates that the platform default is used. # jetty.http.acceptedReceiveBufferSize=-1 ## The SO_SNDBUF socket option to set on accepted sockets. ## A value of -1 indicates that the platform default is used. # jetty.http.acceptedSendBufferSize=-1
Among the configurable properties, the most relevant are:
jetty.http.port
-
The network port that Jetty listens to for clear-text HTTP/1.1 connections — default
8080
. jetty.http.idleTimeout
-
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 — default
30
seconds. jetty.http.acceptors
-
The number of threads that compete to accept connections — default 1. Use -1 to let the accept heuristic decides the value; the current heuristic calculates a value based on the number of cores). Refer to this section for more information about acceptor threads.
jetty.http.selectors
-
The number of NIO selectors (with an associated thread) that manage connections — default -1 (i.e. a select heuristic decides the value; the current heuristic calculates a value based on the number of cores).
Configuration of Acceptors
Accepting connections from remote clients may be configured as a blocking operation, or a non-blocking operation.
When accepting connections is configured as a blocking operation (the number of acceptors is greater than zero), a thread is blocked in the accept()
call until a connection is accepted, and other acceptor threads (if any) are blocked on the lock acquired by the accepting thread 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, so that when one acceptor thread processes a just accepted connection, another acceptor thread can immediately take over accepting connections.
When accepting connections is configured as a non-blocking operation (the number of acceptors is zero), then the server socket is set in non-blocking mode and added to a NIO selector. In this way, no dedicated acceptor threads exist: the work of accepting connections is performed by the selector thread.
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 TCP 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.
Module http2
The http2
module enables support for the secure HTTP/2 protocol.
The module properties are:
## Specifies the maximum number of concurrent requests per session. # jetty.http2.maxConcurrentStreams=128 ## Specifies the initial stream receive window (client to server) in bytes. # jetty.http2.initialStreamRecvWindow=524288 ## Specifies the initial session receive window (client to server) in bytes. # jetty.http2.initialSessionRecvWindow=1048576 ## Specifies the maximum number of keys in all SETTINGS frames received by a session. # jetty.http2.maxSettingsKeys=64 ## Specifies the maximum number of bad frames and pings per second, ## after which a session is closed to avoid denial of service attacks. # jetty.http2.rateControl.maxEventsPerSecond=50
The jetty.http2.rateControl.maxEventsPerSecond
property controls the number of "bad" or "unnecessary" frames that a client may send before the server closes the connection (with code ENHANCE_YOUR_CALM
) to avoid a denial of service.
For example, an attacker may send empty SETTINGS
frames to a server in a tight loop.
While the SETTINGS
frames don’t change the server configuration and each of them is somehow harmless, the server will be very busy processing them because they are sent by the attacker one after the other, causing a CPU spike and eventually a denial of service (as all CPUs will be busy processing empty SETTINGS
frames).
The same attack may be performed with PRIORITY
frames, empty DATA
frames, PING
frames, etc.
Module http2c
The http2c
module enables support for the clear-text HTTP/2 protocol.
The module properties are:
## Specifies the maximum number of concurrent requests per session. # jetty.http2c.maxConcurrentStreams=128 ## Specifies the initial stream receive window (client to server) in bytes. # jetty.http2c.initialStreamRecvWindow=524288 ## Specifies the initial session receive window (client to server) in bytes. # jetty.http2c.initialSessionRecvWindow=1232896 ## Specifies the maximum number of keys in all SETTINGS frames received by a session. # jetty.http2c.maxSettingsKeys=64 ## Specifies the maximum number of bad frames and pings per second, ## after which a session is closed to avoid denial of service attacks. # jetty.http2c.rateControl.maxEventsPerSecond=50
The jetty.http2.rateControl.maxEventsPerSecond
property controls the number of "bad" or "unnecessary" frames that a client may send before the server closes the connection (with code ENHANCE_YOUR_CALM
) to avoid a denial of service.
For example, an attacker may send empty SETTINGS
frames to a server in a tight loop.
While the SETTINGS
frames don’t change the server configuration and each of them is somehow harmless, the server will be very busy processing them because they are sent by the attacker one after the other, causing a CPU spike and eventually a denial of service (as all CPUs will be busy processing empty SETTINGS
frames).
The same attack may be performed with PRIORITY
frames, empty DATA
frames, PING
frames, etc.
Module http3
The http3
module enables support for the HTTP/3 protocol.
The module properties are:
## The host/address to bind the connector to. # jetty.quic.host=0.0.0.0 ## The port the connector listens on. # jetty.quic.port=8444 ## The connector idle timeout, in milliseconds. # jetty.quic.idleTimeout=30000 ## Specifies the maximum number of concurrent requests per session. # jetty.quic.maxBidirectionalRemoteStreams=128 ## Specifies the session receive window (client to server) in bytes. # jetty.quic.sessionRecvWindow=4194304 ## Specifies the stream receive window (client to server) in bytes. # jetty.quic.bidirectionalStreamRecvWindow=2097152 ## Specifies the stream idle timeout, in milliseconds. # jetty.http3.streamIdleTimeout=30000
Module http-forwarded
The http-forwarded
module provides support for processing the Forwarded
HTTP header (defined in RFC 7239) and the now obsoleted X-Forwarded-*
HTTP headers.
The module properties are:
### ForwardedRequestCustomizer Configuration ## Whether to process only the RFC7239 "Forwarded" header. ## "X-Forwarded-*" headers are not processed. # jetty.httpConfig.forwardedOnly=false ## Whether the address obtained from "Forwarded: by=" or ## "X-Forwarded-Server" is used in the request authority. # jetty.httpConfig.forwardedProxyAsAuthority=false ## Whether the "X-Forwarded-Port" header is used in the request authority, ## or else it is the remote client port. # jetty.httpConfig.forwardedPortAsAuthority=true ## The name of the RFC 7239 HTTP header. # jetty.httpConfig.forwardedHeader=Forwarded ## The name of the obsolete forwarded host HTTP header. # jetty.httpConfig.forwardedHostHeader=X-Forwarded-Host ## The name of the obsolete forwarded server HTTP header. # jetty.httpConfig.forwardedServerHeader=X-Forwarded-Server ## The name of the obsolete forwarded scheme HTTP header. # jetty.httpConfig.forwardedProtoHeader=X-Forwarded-Proto ## The name of the obsolete forwarded for HTTP header. # jetty.httpConfig.forwardedForHeader=X-Forwarded-For ## The name of the obsolete forwarded port HTTP header. # jetty.httpConfig.forwardedPortHeader=X-Forwarded-Port ## The name of the obsolete forwarded https HTTP header. # jetty.httpConfig.forwardedHttpsHeader=X-Proxied-Https ## The name of the obsolete forwarded SSL session ID HTTP header. # jetty.httpConfig.forwardedSslSessionIdHeader=Proxy-ssl-id ## The name of the obsolete forwarded SSL cipher HTTP header. # jetty.httpConfig.forwardedCipherSuiteHeader=Proxy-auth-cert
Module https
The https
module provides the HTTP/1.1 protocol to the ssl
module.
The module file is $JETTY_HOME/modules/https.mod
:
# DO NOT EDIT THIS FILE - See: https://jetty.org/docs/ [description] Adds HTTPS protocol support to the TLS(SSL) Connector. [tags] connector https http ssl [depend] ssl [after] alpn http2 http-forwarded [xml] etc/jetty-https.xml
Module jmx
This module enables deployment of Java Servlet web applications.
This configuration is useful for local development and testing.
If you need to enable remote access, use the jmx-remote
module.
Module jmx-remote
The jmx-remote
module provides remote access to JMX clients.
The module properties to configure remote JMX connector are:
## The host/address to bind the RMI server to. # jetty.jmxremote.rmiserverhost=localhost ## The port the RMI server listens to (0 means a random port is chosen). # jetty.jmxremote.rmiserverport=1099 ## The host/address to bind the RMI registry to. # jetty.jmxremote.rmiregistryhost=localhost ## The port the RMI registry listens to. # jetty.jmxremote.rmiregistryport=1099 ## The host name exported in the RMI stub. -Djava.rmi.server.hostname=localhost
The system property java.rmi.server.hostname
is specified with the usual notation, prepending a -D
in front of the system property name.
The system property java.rmi.server.hostname
is uncommented because it is necessary in the default configuration — most systems do not have the local name resolution configured properly for remote access.
As an example, in a Linux machine named beryl
, the /etc/hosts
file may contain these entries:
127.0.0.1 localhost 127.0.1.1 beryl
If the system property java.rmi.server.hostname
is not specified, the RMI implementation uses the host name beryl
to figure out the IP address to store in the RMI stub, in this case 127.0.1.1
.
However, we the RMI server is configured to bind to localhost
, i.e. 127.0.0.1
.
If the system property java.rmi.server.hostname
is not specified, the RMI client will try to connect to 127.0.1.1
(because that’s what in the RMI stub) and fail because nothing is listening on that address.
Module qos
The qos
module installs the QoSHandler
at the root of the Handler
tree; the QoSHandler
applies limits to the number of concurrent requests, as explained in this section.
The module properties are:
## The maximum number of concurrent requests allowed; use 0 for a default ## value calculated from the ThreadPool configuration or the number of CPU cores. # jetty.qos.maxRequestCount=0 ## The maximum number of requests that may be suspended. # jetty.qos.maxSuspendedRequestCount=1024 ## The maximum duration that a request may remain suspended, in milliseconds; use 0 for unlimited time. # jetty.qos.maxSuspendDuration=0 ## A comma-separated list of HTTP methods to include when matching a request. # jetty.qos.include.method= ## A comma-separated list of HTTP methods to exclude when matching a request. # jetty.qos.exclude.method= ## A comma-separated list of URI path patterns to include when matching a request. # jetty.qos.include.path= ## A comma-separated list of URI path patterns to exclude when matching a request. # jetty.qos.exclude.path= ## A comma-separated list of remote addresses patterns to include when matching a request. # jetty.qos.include.inet= ## A comma-separated list of remote addresses patterns to exclude when matching a request. # jetty.qos.exclude.inet=
Module requestlog
The requestlog
module provides HTTP request/response logging in the standard NCSA format, or in a custom format of your choice.
The module properties are:
## Format string # jetty.requestlog.formatString=%{client}a - %u %{dd/MMM/yyyy:HH:mm:ss ZZZ|GMT}t "%r" %s %O "%{Referer}i" "%{User-Agent}i" ## Logging directory (relative to $jetty.base) # jetty.requestlog.dir=logs ## File path # jetty.requestlog.filePath=${jetty.requestlog.dir}/yyyy_mm_dd.request.log ## Date format for rollovered files (uses SimpleDateFormat syntax) # jetty.requestlog.filenameDateFormat=yyyy_MM_dd ## How many days to retain old log files # jetty.requestlog.retainDays=90 ## Whether to append to existing file # jetty.requestlog.append=false ## Timezone of the log file rollover # jetty.requestlog.timezone=GMT
The property jetty.requestlog.formatString
can be customized using format codes.
Format codes are specified with the syntax %MODIFIERS{PARAM}CODE
as follows:
- MODIFIERS
- Optional list of comma separated HTTP status codes which may be preceded by a single "!" to indicate negation. If the status code is not in the list the literal string "-" will be logged instead of the resulting value from the percent code.
- {PARAM}
- Parameter string which may be optional depending on the percent code used.
- CODE
- A one or two character code specified by the table of format codes below.
Format String | Description |
---|---|
X |
The X character. |
%% |
The percent character. |
%{format}a |
The address or host name. Valid format values are: "server", "client", "local", "remote". The format parameter is optional and defaults to "server". Values "server" and "client" are the logical addresses which can be modified in the request headers, while "local" and "remote" are the physical addresses so may be the addresses of a proxy between the end-user and the server. |
%{format}p |
The port. Valid format values are: "server", "client", "local", "remote". The format parameter is optional and defaults to "server". Values "server" and "client" are the logical ports which can be modified in the request headers, while "local" and "remote" are the physical ports so may be the ports of a proxy between the end-user and the server. |
%{CLF}I |
The size of request in bytes, excluding HTTP headers. The parameter is optional. When the parameter value is "CLF" the Common Log Format is used, i.e. a {@code -} rather than a {@code 0} when no bytes are present. |
%{CLF}O |
The size of response in bytes, excluding HTTP headers. The parameter is optional. When the parameter value is "CLF" the Common Log Format is used, i.e. a {@code -} rather than a {@code 0} when no bytes are present. |
%{CLF}S |
The bytes transferred (received and sent). This is the combination of {@code %I} and {@code %O}. The parameter is optional. When the parameter value is "CLF" the Common Log Format is used, i.e. a {@code -} rather than a {@code 0} when no bytes are present. |
%{VARNAME}C |
The value of the request cookie VARNAME. The parameter is optional. Only version 0 cookies are fully supported. When the parameter is missing, all request cookies will be logged. |
%D |
The time taken to serve the request, in microseconds. |
%{VARNAME}e |
The value of the environment variable VARNAME. |
%f |
The file system path of the requested resource. |
%H |
The name and version of the request protocol, such as "HTTP/1.1". |
%{VARNAME}i |
The value of the VARNAME request header. |
%k |
The number of requests handled on a connection. The initial request on a connection yields a value 0, the first request after the initial on the same connection yields the value 1, the second request on the same connection yields the value 2, etc. |
%m |
The HTTP request method. |
%{VARNAME}o |
The value of the VARNAME response header. |
%q |
The query string, prepended with a ? if a query string exists, otherwise an empty string. |
%r |
First line of an HTTP/1.1 request (or equivalent information for HTTP/2 or later). |
%R |
The name of the Handler or Servlet generating the response (if any). |
%s |
The HTTP response status code. |
%{format|timeZone|locale}t |
The time at which the request was received. The parameter is optional and may have the following values: {format}, {format|timeZone} or {format|timeZone|locale}.
|
%{UNIT}T |
The time taken to serve the request. The parameter UNIT is optional and defaults to "s".
The parameter UNIT indicates the unit of time: "s" for seconds, "ms" for milliseconds, "us" for microseconds.
|
%{d}u |
The remote user if the request was authenticated with servlet authentication. May be an invalid value if response status code ({@code %s}) is 401 (unauthorized). The parameter is optional. When the parameter value is "d", deferred authentication will also be checked. |
%U |
The URL path requested, not including any query string. |
%X |
The connection status when response is completed:
|
%{VARNAME}ti |
The value of the VARNAME request trailer. |
%{VARNAME}to |
The value of the VARNAME response trailer. |
%{OPTION}uri |
The request URI. The parameter is optional and may have the be one of the following options:
|
%{attributeName}attr |
The value of the request attribute with the given name. |
Module resources
This module adds the $JETTY_BASE/resources
directory to the server’s classpath.
A common use-case for this module is to provide resources for third-party libraries via the server classpath. For instance, many logging libraries (including Log4j2 and Logback) look for their configuration files on the classpath.
Jetty provides a logging library implementation — enabled via the logging-jetty
module — whose configuration file is $JETTY_BASE/resources/jetty-logging.properties
.
Module rewrite
The rewrite
module inserts the RewriteHandler
at the beginning of the Handler
chain, providing URI-rewriting features similar to the Apache’s mod_rewrite or the Nginx rewrite module.
The module properties are:
## Request attribute name used to store the original request path. # jetty.rewrite.originalPathAttribute=jetty.rewrite.originalRequestPath
A common use of the rewrite
module is to redirect/rewrite old URI paths that have been renamed, for example from /old/*
to /new/*
; in this way, the old paths will not result in a 404
response, but rather be redirected/rewritten to the new paths.
RewriteHandler
matches incoming requests against a set of rules that you can specify in the $JETTY_BASE/etc/jetty-rewrite-rules.xml
file.
Rules can be matched against request data such as the request URI or the request headers; if there is a match, the rule is applied.
The rule file $JETTY_BASE/etc/jetty-rewrite-rules.xml
is initially empty, but contains commented examples of rules that you can add.
The list of available rules can be found here.
An example of jetty-rewrite-rules.xml
is the following:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
<Call name="addRule">
<!-- Redirect with a 301 from /old/* to /new/* -->
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.RedirectRegexRule">
<Set name="statusCode">301</Set>
<Set name="pattern">/old/(.*)</Set>
<Set name="location">/new/$1</Set>
</New>
</Arg>
</Call>
</Configure>
Rules can be scoped to a specific virtual host.
In the example below, the rule will only be evaluated if the virtual host matches example.com
:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure id="Rewrite" class="org.eclipse.jetty.rewrite.handler.RuleContainer">
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.VirtualHostRuleContainer">
<Call name="addVirtualHost">
<!-- Only match the example.com domain -->
<Arg>example.com</Arg>
</Call>
<Call name="addRule">
<Arg>
<New class="org.eclipse.jetty.rewrite.handler.RedirectPatternRule">
<Set name="pattern">/advice</Set>
<Set name="location">/support</Set>
</New>
</Arg>
</Call>
</New>
</Arg>
</Call>
</Configure>
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 threadpool
module, the bytebufferpool
module and the logging
module.
The See also the protocols section for more information about the supported protocols. |
HTTP Configuration Properties
The module properties to configure generic HTTP properties are listed below. Mostly they frequently apply to HTTP/1, HTTP/2 and HTTP/3, but some parameters are version specific:
### Common HTTP configuration ## Scheme to use to build URIs for secure redirects # jetty.httpConfig.secureScheme=https ## Port to use to build URIs for secure redirects # jetty.httpConfig.securePort=8443 ## Response content buffer size (in bytes) # jetty.httpConfig.outputBufferSize=32768 ## Max response content write length that is buffered (in bytes) # jetty.httpConfig.outputAggregationSize=8192 ## If HTTP/1.x persistent connections should be enabled # jetty.httpConfig.persistentConnectionsEnabled=true ## Max request headers size (in bytes) # jetty.httpConfig.requestHeaderSize=8192 ## Max response headers size (in bytes) # jetty.httpConfig.responseHeaderSize=8192 ## Whether to send the Server: header # jetty.httpConfig.sendServerVersion=true ## Whether to send the Date: header # jetty.httpConfig.sendDateHeader=false ## Max per-connection header cache size (in nodes) # jetty.httpConfig.headerCacheSize=1024 ## Whether, for requests with content, delay dispatch until some content has arrived # jetty.httpConfig.delayDispatchUntilContent=true ## Maximum number of error dispatches to prevent looping # jetty.httpConfig.maxErrorDispatches=10 ## Relative Redirect Locations allowed # jetty.httpConfig.relativeRedirectAllowed=true ## Whether to use direct ByteBuffers for reading or writing # jetty.httpConfig.useInputDirectByteBuffers=true # jetty.httpConfig.useOutputDirectByteBuffers=true
Among the configurable properties, the most relevant are:
jetty.httpConfig.headerCacheSize
-
The header cache is used when parsing HTTP/1 to more efficiently handle fields that are repeated in every request on a connection. If the server does not receive persistent connection or infrequent repeated fields, then there may be a performance gain in reducing the cache size. If large fields are frequently repeated, then a large cache may be beneficial.
jetty.httpConfig.delayDispatchUntilContent
-
It is not uncommon for the network packets containing a request header to arrive before packets that contain the data of any request body. In such cases it may be beneficial for overall performance to delay dispatching the request to be handled until the first data packet arrives, as this may avoid blocking the handling thread. However, if minimum latency for receiving the request without content is important, then this parameter can be set to false.
jetty.httpConfig.sendServerVersion
-
Whether you want to send the
Server
header in every HTTP response:HTTP/1.1 200 OK Content-Length: 0 Server: Jetty(12.0.16-SNAPSHOT)
Server Configuration Properties
The module properties to configure the Jetty server are:
### Server configuration ## Whether ctrl+c on the console gracefully stops the Jetty server # jetty.server.stopAtShutdown=true ## Dump the state of the Jetty server, components, and webapps after startup # jetty.server.dumpAfterStart=false ## The temporary directory used by the Jetty server and as a root for its contexts # jetty.server.tempDirectory= ## Dump the state of the Jetty server, components, and webapps before shutdown # jetty.server.dumpBeforeStop=false
Among the configurable properties, the most relevant are:
jetty.server.dumpAfterStart
-
Whether to perform a
Server.dump()
operation after theServer
has started. The output of the dump operation is sent toSystem.err
. See also the Jetty Server Dump section for more information. jetty.server.dumpBeforeStop
-
Whether to perform a
Server.dump()
operation before theServer
stops. The output of the dump operation is sent toSystem.err
. See also the Jetty Server Dump section for more information. jetty.server.stopAtShutdown
-
Whether to call
Server.stop()
through a JVM shutdown hook when the JVM exits.
Server Compliance Properties
The Jetty server strives to keep up with the latest IETF RFCs for compliance with internet specifications, which are periodically updated. When possible, Jetty will support backwards compatibility by providing compliance modes that can be configured to allow violations of the current specifications that may have been allowed in obsoleted specifications. The module properties to configure the Jetty server compliance are:
## HTTP Compliance: RFC7230, RFC7230_LEGACY, RFC2616, RFC2616_LEGACY, LEGACY # jetty.httpConfig.compliance=RFC7230 ## URI Compliance: DEFAULT, LEGACY, RFC3986, RFC3986_UNAMBIGUOUS, UNSAFE # jetty.httpConfig.uriCompliance=DEFAULT ## Cookie compliance mode for parsing request Cookie headers: RFC6265_STRICT, RFC6265, RFC6265_LEGACY, RFC2965, RFC2965_LEGACY # jetty.httpConfig.requestCookieCompliance=RFC6265 ## Cookie compliance mode for generating response Set-Cookie: RFC2965, RFC6265 # jetty.httpConfig.responseCookieCompliance=RFC6265
Among the configurable properties, the most relevant are:
jetty.httpConfig.compliance
-
Configures the compliance to HTTP specifications. The value could be:
-
One of the predefined
HttpCompliance
constants, such asRFC7230
orRFC2616
. For example:jetty.httpConfig.compliance=RFC2616
. -
A comma-separated list of violations to allow or forbid, as specified by the
HttpCompliance.from(String)
method. For example,jetty.httpConfig.compliance=RFC7230,MULTIPLE_CONTENT_LENGTHS
means that the HTTP compliance is that defined byRFC7230
, but also allows theHttpCompliance.Violation.MULTIPLE_CONTENT_LENGTHS
, so that requests that have multipleContent-Length
headers are accepted (they would be rejected when using justHttpCompliance.RFC7230
).For more information about
HttpCompliance
see also this section.
-
jetty.httpConfig.uriCompliance
-
Configures the compliance to URI specifications. The value could be:
-
One of the predefined
UriCompliance
constants, such asDEFAULT
orRFC3986
. For example:jetty.httpConfig.compliance=RFC3986
. -
A comma-separated list of violations to allow or forbid, as specified by the
UriCompliance.from(String)
method. For example,jetty.httpConfig.uriCompliance=RFC3986,-AMBIGUOUS_PATH_SEPARATOR
means that the URI compliance is that defined byRFC3986
, but also does not allow theUriCompliance.Violation.AMBIGUOUS_PATH_SEPARATOR
, so that requests that have URIs such as/foo/bar%2Fbaz
(where%2F
is the URL-encoded/
character) are rejected (they would be accepted when using justUriCompliance.RFC3986
).For more information about
UriCompliance
see also this section.
-
jetty.httpConfig.requestCookieCompliance
jetty.httpConfig.responseCookieCompliance
-
Configures the compliance to HTTP cookie specifications. The value could be:
-
One of the predefined
CookieCompliance
constants, such asRFC6265
. For example:jetty.httpConfig.compliance=RFC6265
. -
A comma-separated list of violations to allow or forbid, as specified by the
CookieCompliance.from(String)
method. For example,jetty.httpConfig.requestCookieCompliance=RFC6265,-RESERVED_NAMES_NOT_DOLLAR_PREFIXED
means that the cookie compliance is that defined byRFC6265
, but also does not allow theCookieCompliance.Violation.RESERVED_NAMES_NOT_DOLLAR_PREFIXED
, so that requests that have cookie headers such asCookie: $foo=bar
are rejected (they would be accepted when using justCookieCompliance.RFC6265
).For more information about
CookieCompliance
see also this section.
-
Server Scheduler Configuration Properties
The module properties to configure the Jetty server scheduler are:
### Server Scheduler Configuration ## The scheduler thread name, defaults to "Scheduler-{hashCode()}" if blank. # jetty.scheduler.name= ## Whether the server scheduler threads are daemon. # jetty.scheduler.daemon=false ## The number of server scheduler threads. # jetty.scheduler.threads=1
Module size-limit
The size-limit
module installs the SizeLimitHandler
at the root of the Handler
tree; the SizeLimitHandler
applies limits to the request content and the response content, as explained in this section.
The module properties are:
## The maximum request content size in bytes, or -1 for unlimited. # jetty.sizeLimit.maxRequestContentSize=-1 ## The maximum response content size in bytes, or -1 for unlimited. # jetty.sizeLimit.maxResponseContentSize=-1
Module ssl
The ssl
module provides the secure connector, and allows you to configure the KeyStore properties and the TLS parameters, and depends on the server
module.
Secure Connector Properties
The module properties to configure the secure connector are:
### TLS (SSL) Connector Configuration ## The host/address to bind the connector to. # jetty.ssl.host=0.0.0.0 ## The port the connector listens on. # jetty.ssl.port=8443 ## The connector idle timeout, in milliseconds. # jetty.ssl.idleTimeout=30000 ## The number of acceptors (-1 picks a default value based on number of cores). # jetty.ssl.acceptors=1 ## The number of selectors (-1 picks a default value based on number of cores). # jetty.ssl.selectors=-1 ## The ServerSocketChannel accept queue backlog (0 picks the platform default). # jetty.ssl.acceptQueueSize=0 ## The thread priority delta to give to acceptor threads. # jetty.ssl.acceptorPriorityDelta=0 ## Whether to enable the SO_REUSEADDR socket option. # jetty.ssl.reuseAddress=true ## Whether to enable the SO_REUSEPORT socket option. # jetty.ssl.reusePort=false ## Whether to enable the TCP_NODELAY socket option on accepted sockets. # jetty.ssl.acceptedTcpNoDelay=true ## The SO_RCVBUF socket option to set on accepted sockets. ## A value of -1 indicates that the platform default is used. # jetty.ssl.acceptedReceiveBufferSize=-1 ## The SO_SNDBUF socket option to set on accepted sockets. ## A value of -1 indicates that the platform default is used. # jetty.ssl.acceptedSendBufferSize=-1 ## Whether client SNI data is required for all secure connections. ## When SNI is required, clients that do not send SNI data are rejected with an HTTP 400 response. # jetty.ssl.sniRequired=false ## Whether client SNI data is checked to match CN and SAN in server certificates. ## When SNI is checked, if the match fails the connection is rejected with an HTTP 400 response. # jetty.ssl.sniHostCheck=true ## The max age, in seconds, for the Strict-Transport-Security response header. # jetty.ssl.stsMaxAgeSeconds=31536000 ## Whether to include the subdomain property in any Strict-Transport-Security header. # jetty.ssl.stsIncludeSubdomains=true
Among the configurable properties, the most relevant are:
jetty.ssl.port
-
The network port that Jetty listens to for secure connections — default
8443
. jetty.ssl.idleTimeout
-
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 — default
30000
milliseconds. jetty.ssl.acceptors
-
The number of threads that compete to accept connections — default 1. Use -1 to let the accept heuristic decides the value; the current heuristic calculates a value based on the number of cores). Refer to this section for more information about acceptor threads.
jetty.ssl.selectors
-
The number of NIO selectors (with an associated thread) that manage connections — default -1 (i.e. a select heuristic decides the value; the current heuristic calculates a value based on the number of cores). Refer to this section for more information about selector threads.
The module properties to configure the KeyStore and TLS parameters are:
### SslContextFactory Configuration ## Note that OBF passwords are not secure, just protected from casual observation. ## Whether client SNI data is required for all secure connections. ## When SNI is required, clients that do not send SNI data are rejected with a TLS handshake error. # jetty.sslContext.sniRequired=false ## The Endpoint Identification Algorithm. ## Same as javax.net.ssl.SSLParameters#setEndpointIdentificationAlgorithm(String). # jetty.sslContext.endpointIdentificationAlgorithm= ## The JSSE Provider. # jetty.sslContext.provider= ## The KeyStore file path, either an absolute path or a relative path to $JETTY_BASE. # jetty.sslContext.keyStorePath=etc/keystore.p12 ## The TrustStore file path, either an absolute path or a relative path to $JETTY_BASE. # jetty.sslContext.trustStorePath=etc/keystore.p12 ## The KeyStore password. # jetty.sslContext.keyStorePassword= ## The Keystore type. # jetty.sslContext.keyStoreType=PKCS12 ## The KeyStore provider. # jetty.sslContext.keyStoreProvider= ## The KeyManager password. # jetty.sslContext.keyManagerPassword= ## The TrustStore password. # jetty.sslContext.trustStorePassword= ## The TrustStore type. # jetty.sslContext.trustStoreType=PKCS12 ## The TrustStore provider. # jetty.sslContext.trustStoreProvider= ## Whether client certificate authentication is required. # jetty.sslContext.needClientAuth=false ## Whether client certificate authentication is desired, but not required. # jetty.sslContext.wantClientAuth=false ## Whether cipher order is significant. # jetty.sslContext.useCipherSuitesOrder=true ## The SSLSession cache size. # jetty.sslContext.sslSessionCacheSize=-1 ## The SSLSession cache timeout (in seconds). # jetty.sslContext.sslSessionTimeout=-1 ## Whether TLS renegotiation is allowed. # jetty.sslContext.renegotiationAllowed=true ## The max number of TLS renegotiations per connection. # jetty.sslContext.renegotiationLimit=5
KeyStore Properties and TLS Properties
The Jetty component that manages the KeyStore, that contains the cryptographic material and the TLS configuration is an instance of SslContextFactory.Server
.
You can configure the SslContextFactory.Server
by specifying properties, or by invoking its method for a more advanced configuration.
Among the configurable properties, the most relevant are:
jetty.sslContext.keyStorePath
-
The KeyStore path on the file system, either an absolute path or a relative path to
$JETTY_BASE
— defaults to$JETTY_BASE/etc/keystore.p12
. jetty.sslContext.keyStorePassword
-
The KeyStore password, which you want to explicitly configure. The password may be obfuscated with the Jetty Password tool.
If you need to configure client certificate authentication, you want to configure one of these properties (they are mutually exclusive):
jetty.sslContext.needClientAuth
-
Whether client certificate authentication should be required.
jetty.sslContext.wantClientAuth
-
Whether client certificate authentication should be requested.
If you configure client certificate authentication, you need to configure and distribute a client KeyStore as explained in this section.
Advanced TLS Configuration
Configuring SslContextFactory.Server
using properties as explained in this section is sufficient for most cases.
For the cases where Jetty module properties are not defined, or when you need more advanced configuration (for example the ability to include and/or exclude the TLS cipher suites), you can follow these steps:
-
Modify
$JETTY_BASE/start.d/ssl.ini
by adding a path to a custom XML file, for example:ssl.ini--module=ssl etc/ssl-config.xml (1) ...
1 The path to the custom XML file, relative to $JETTY_BASE
. -
Create the custom XML file, with your advanced configuration. For example, to exclude certain TLS ciphers you can use the following file:
ssl-config.xml<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://jetty.org/jetty/configure_10_0.dtd"> <Configure> <Ref refid="sslContextFactory"> (1) <!-- Example using the Set element --> <Set name="ExcludeCipherSuites"> (2) <Array type="String"> <Item>^TLS_RSA_.*$</Item> <Item>^.*_(MD5|SHA|SHA1)$</Item> </Array> </Set> <!-- Example using the Call element --> <Call name="addExcludeCipherSuites"> <Arg> <Array type="String"> <Item>^SSL_.*$</Item> </Array> </Arg> </Call> </Ref> </Configure>
1 Reference the existing sslContextFactory
object.2 Call the method setExcludeCipherSuites(String...)
to specify regular expressions of the TLS ciphers you want to exclude.
The syntax to use in the custom XML file is described in this section.
In the custom XML file you can call any SslContextFactory.Server
method.
Refer to the SslContextFactory.Server
javadocs for the comprehensive list of methods.
Module ssl-reload
The ssl-reload
module provides a periodic scanning of the directory where the KeyStore file resides.
When the scanning detects a change to the KeyStore file, the correspondent SslContextFactory.Server
component is reloaded with the new KeyStore configuration.
The module properties are:
# Monitored directory scan period, in seconds. # jetty.sslContext.reload.scanInterval=1
Module state-tracking
The state-tracking
Jetty module inserts the StateTrackingHandler
at the beginning of the Handler chain.
StateTrackingHandler
is a troubleshooting Handler
that tracks usages of Handler
/Request
/Response
asynchronous APIs, and logs at warning level invalid usages of the APIs that may lead to blockages, deadlocks, or missing completion of Callback
s.
This module can be enabled to troubleshoot web applications that do not behave as expected, for example:
-
That consume a lot of threads (possibly because they block).
-
That do not send responses (or send only partial responses) to clients.
-
That timeout when apparently they have received or have sent all data.
The module properties are:
## The timeout in ms for the completion of the handle() callback. # jetty.stateTracking.handlerCallbackTimeout=0 ## Whether the handle() callback is completed in case of timeout. # jetty.stateTracking.completeHandlerCallbackAtTimeout=false ## The timeout in ms for the execution of the demand callback. # jetty.stateTracking.demandCallbackTimeout=0 ## The timeout in ms for the execution of a response write. # jetty.stateTracking.writeTimeout=0 ## The timeout in ms for the execution of the response write callback. # jetty.stateTracking.writeCallbackTimeout=0
Module test-keystore
The test-keystore
module creates on-the-fly a KeyStore containing a self-signed certificate for domain localhost
.
The KeyStore file is automatically deleted when the JVM exits, and re-created when you restart Jetty, to enforce the fact that it is a test KeyStore that should not be reused if not for testing.
The module file is $JETTY_HOME/modules/test-keystore.mod
:
[description] Test keystore with self-signed SSL Certificate. DO NOT USE IN PRODUCTION!!! [tags] demo ssl [before] ssl [files] maven://org.bouncycastle/bcpkix-jdk15to18/${bouncycastle.version}|lib/bouncycastle/bcpkix-jdk15to18-${bouncycastle.version}.jar maven://org.bouncycastle/bcprov-jdk15to18/${bouncycastle.version}|lib/bouncycastle/bcprov-jdk15to18-${bouncycastle.version}.jar maven://org.bouncycastle/bcutil-jdk15to18/${bouncycastle.version}|lib/bouncycastle/bcutil-jdk15to18-${bouncycastle.version}.jar [lib] lib/jetty-keystore-${jetty.version}.jar lib/bouncycastle/bcpkix-jdk15to18-${bouncycastle.version}.jar lib/bouncycastle/bcprov-jdk15to18-${bouncycastle.version}.jar lib/bouncycastle/bcutil-jdk15to18-${bouncycastle.version}.jar [xml] etc/jetty-test-keystore.xml [ini] bouncycastle.version?=1.79 jetty.webapp.addHiddenClasses+=,${jetty.base.uri}/lib/bouncycastle/ jetty.sslContext.keyStorePath?=etc/test-keystore.p12 jetty.sslContext.keyStoreType?=PKCS12 jetty.sslContext.keyStorePassword?=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
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.
Module thread-limit
The thread-limit
module installs the ThreadLimitHandler
at the root of the Handler
tree; the ThreadLimitHandler
applies limits to the number of concurrent threads per remote IP address, as explained in this section.
The module properties are:
## Select style of reverse proxy forwarded header. # jetty.threadlimit.forwardedHeader=X-Forwarded-For # jetty.threadlimit.forwardedHeader=Forwarded ## Whether thread limiting is enabled. # jetty.threadlimit.enabled=true ## The thread limit per remote IP address. # jetty.threadlimit.threadLimit=10 ## A comma-separated list of HTTP methods to include when matching a request. # jetty.threadlimit.include.method= ## A comma-separated list of HTTP methods to exclude when matching a request. # jetty.threadlimit.exclude.method= ## A comma-separated list of URI path patterns to include when matching a request. # jetty.threadlimit.include.path= ## A comma-separated list of URI path patterns to exclude when matching a request. # jetty.threadlimit.exclude.path= ## A comma-separated list of remote addresses patterns to include when matching a request. # jetty.threadlimit.include.inet= ## A comma-separated list of remote addresses patterns to exclude when matching a request. # jetty.threadlimit.exclude.inet=
Module threadpool
The threadpool
module allows you to configure the server-wide thread pool.
The thread pool creates threads on demand up to maxThreads
, and idles them out if they are not used.
Since Jetty uses the thread pool internally to execute critical tasks, it is not recommended to constrain the thread pool to small values of maxThreads
with the purpose of limiting HTTP request concurrency, as this could very likely cause a server lockup when Jetty needs to run a critical task but there are no threads available.
Start with the default value of maxThreads
, and tune for larger values if needed.
The module properties to configure the thread pool are:
## Thread name prefix. #jetty.threadPool.namePrefix=qtp<hashCode> ## Minimum number of pooled threads. #jetty.threadPool.minThreads=10 ## Maximum number of pooled threads. #jetty.threadPool.maxThreads=200 ## Number of reserved threads (-1 for heuristic). #jetty.threadPool.reservedThreads=-1 ## Whether to use virtual threads, if the runtime supports them. ## Deprecated, use Jetty module 'threadpool-virtual' instead. #jetty.threadPool.useVirtualThreads=false ## Thread idle timeout (in milliseconds). #jetty.threadPool.idleTimeout=60000 ## The max number of idle threads that are evicted in one idleTimeout period. #jetty.threadPool.maxEvictCount=1 ## Whether to output a detailed dump. #jetty.threadPool.detailedDump=false
Among the configurable properties, the most relevant are:
jetty.threadPool.namePrefix
-
The name prefix to use for the thread names.
jetty.threadPool.detailedDump
-
Whether the thread pool should dump the whole stack trace of each thread, or just the topmost stack frame — defaults to
false
. jetty.threadPool.idleTimeout
-
The time, in milliseconds, after which an idle thread is released from the pool — defaults to 60000, i.e. 60 seconds.
jetty.threadPool.maxThreads
-
The max number of threads pooled by the thread pool — defaults to 200.
If you want to use virtual threads, introduced as a preview feature in Java 19 and Java 20, and become an official feature since Java 21, use the following modules:
-
The
threadpool-virtual
Jetty module for Java 21 or later. -
The
threadpool-virtual-preview
Jetty module for Java 19 and Java 20.
See also the section about configuring the thread pool.
Module threadpool-all-virtual
The threadpool-all-virtual
module allows you to configure the server-wide thread pool, similarly to what you can do with the threadpool
Jetty module, so that all threads are virtual threads, introduced as an official feature since Java 21.
Only use this module if you are using Java 21 or later. |
The module properties to configure the thread pool are:
## Virtual threads name prefix. #jetty.threadPool.namePrefix=vtp<hashCode> ## Maximum number of current virtual threads. #jetty.threadPool.maxThreads=200 ## Whether to track virtual threads so they appear ## in the dump even if they are unmounted. #jetty.threadPool.tracking=false ## Whether to output virtual thread's stack traces in the dump. #jetty.threadPool.detailedDump=false
The property jetty.threadpool.maxThreads
limits, using a Semaphore
, the number of current virtual threads in use.
Please refer to the virtual threads section of the Jetty Threading Architecture for more information about virtual threads and their pitfalls.
Module threadpool-virtual
The threadpool-virtual
module allows you to configure the server-wide thread pool, similarly to what you can do with the threadpool
Jetty module, but also specify to use virtual threads, introduced as an official feature since Java 21.
Only use this module if you are using Java 21 or later.
If you are using Java 19 or Java 20, use the threadpool-virtual-preview Jetty module instead.
|
Refer to the threadpool
Jetty module for the general features provided by that Jetty module that also this Jetty module provides.
The module properties to configure the thread pool are:
## Platform threads name prefix. #jetty.threadPool.namePrefix=qtp<hashCode> ## Minimum number of pooled threads. #jetty.threadPool.minThreads=10 ## Maximum number of pooled threads. #jetty.threadPool.maxThreads=200 ## Number of reserved threads (-1 for heuristic). #jetty.threadPool.reservedThreads=-1 ## Thread idle timeout (in milliseconds). #jetty.threadPool.idleTimeout=60000 ## The max number of idle threads that can be evicted in one idleTimeout period. #jetty.threadPool.maxEvictCount=1 ## Whether to output a detailed dump. #jetty.threadPool.detailedDump=false ## Virtual threads name prefix. #jetty.threadPool.virtual.namePrefix=qtp<hashCode>-virtual- ## Max number of current virtual threads. #jetty.threadPool.virtual.maxThreads=200 ## Whether to track virtual threads so they appear ## in the dump even if they are unmounted. #jetty.threadPool.virtual.tracking=false
The specific properties to configure virtual threads are:
jetty.threadPool.virtual.namePrefix
-
The name prefix to use for the virtual thread names.
jetty.threadPool.virtual.inheritInheritableThreadLocals
-
Whether virtual threads inherit the values of
InheritableThreadLocal
variables.
Module threadpool-virtual-preview
The threadpool-virtual-preview
module allows you to configure the server-wide thread pool, similarly to what you can do with the threadpool
Jetty module, but also specify to use virtual threads, introduced as a preview feature in Java 19 and in Java 20.
Only use this module if you are using Java 19 or Java 20.
If you are using Java 21 or later, use the threadpool-virtual Jetty module instead.
|
To enable preview features, this module needs to specify the --enable-preview command line option using the [exec] directive, and as such it will fork another JVM.
|
Refer to the threadpool
Jetty module for the general features provided by that Jetty module that also this Jetty module provides.
The module properties to configure the thread pool are:
## Platform threads name prefix. #jetty.threadPool.namePrefix=qtp<hashCode> ## Minimum number of pooled threads. #jetty.threadPool.minThreads=10 ## Maximum number of pooled threads. #jetty.threadPool.maxThreads=200 ## Number of reserved threads (-1 for heuristic). #jetty.threadPool.reservedThreads=-1 ## Thread idle timeout (in milliseconds). #jetty.threadPool.idleTimeout=60000 ## The max number of idle threads that can be evicted in one idleTimeout period. #jetty.threadPool.maxEvictCount=1 ## Whether to output a detailed dump. #jetty.threadPool.detailedDump=false ## Virtual threads name prefix. #jetty.threadPool.virtual.namePrefix=qtp<hashCode>-virtual- ## Whether virtual threads are allowed to set thread locals. #jetty.threadPool.virtual.allowSetThreadLocals=true ## Whether virtual threads inherits the values of inheritable thread locals. #jetty.threadPool.virtual.inheritInheritableThreadLocals=true
The specific properties to configure virtual threads are:
jetty.threadPool.virtual.namePrefix
-
The name prefix to use for the virtual thread names.
jetty.threadPool.virtual.allowSetThreadLocals
-
Whether virtual threads are allowed to set thread locals.
jetty.threadPool.virtual.inheritInheritableThreadLocals
-
Whether virtual threads inherit the values of
InheritableThreadLocal
variables.
Module well-known
The well-known
Jetty module creates a ResourceHandler
deployed at the /.well-known
context path which serves files from a directory.
By default, the directory created at $JETTY_BASE/.well-known
is used, but it can be configured from well-known.ini
to anywhere in the filesystem.
Note that the .well-known
directory may be seen as a hidden directory by the filesystem.
The concept of well-known URIs has been defined in RFC5785. This module can be used for things like the automatic renewal of Let’s Encrypt certificates. See IANA Well-Known URIs for more possible examples of how this can be used.
The module properties are:
## Well Known Directory (relative to $JETTY_BASE if relative path, otherwise it is an absolute path). # jetty.wellknown.dir=.well-known ## Allow contents of the well-known directory to be listed. # jetty.wellknown.listDirectories=false