Jetty Start Mechanism

Make sure you have read the Jetty architecture section if you are not familiar with the terms used in this section.

The Jetty start mechanism is invoked by executing $JETTY_HOME/start.jar, from within a $JETTY_BASE directory, with zero or more command line options:

$ cd $JETTY_BASE
$ java -jar $JETTY_HOME/start.jar ...

The Jetty start mechanism has two main modes of operation:

  • The tool mode, detailed in this section, when it is used as a command line tool to configure the $JETTY_BASE directory by enabling modules, creating sub-directories and files, downloading files, etc. In this mode, the JVM started with java -jar $JETTY_HOME/start.jar performs the specified command and then exits.

  • The start mode, detailed in this section, when it is used to start the JVM that runs Jetty with the specified configuration. In this mode, the JVM started with java -jar $JETTY_HOME/start.jar starts Jetty and does not exit until stopped, for example by hitting Ctrl+C on the terminal.

Refer to the Jetty start mechanism reference section for the complete list of the available command line options.

You want to use the Jetty start mechanism to configure your $JETTY_BASE and then to start Jetty.

Configuring $JETTY_BASE

Within the Jetty start mechanism, the source of configurations is layered in this order, from higher priority to lower priority:

  • The command line options.

  • The $JETTY_BASE directory, and its files.

  • The directory specified with the --add-config-dir option, and its files.

  • The $JETTY_HOME directory, and its files.

Enabling Modules

You can enable Jetty modules persistently across restarts with the --add-modules command:

$ java -jar $JETTY_HOME/start.jar --add-modules=server,http

The Jetty start mechanism will look for the specified modules following the order specified above. In the common case (without a --add-config-dir directory), it will look in $JETTY_BASE/modules/ first and then in $JETTY_HOME/modules/.

Since the server and http modules are standard Jetty modules, they are present in $JETTY_HOME/modules/ and loaded from there.

When you enable a Jetty module, the Jetty start mechanism:

  • Creates the correspondent $JETTY_BASE/start.d/*.ini module configuration file. The content of these *.ini files is copied from the [ini-template] section of the correspondent *.mod file.

  • Executes the directives specified in [files] section (if present) of the *.mod file. This may simply create a file or a directory, or download files from the Internet. This step is performed transitively for all module dependencies.

For example, enabling the server and http modules results in the $JETTY_BASE directory to have the following structure:

$JETTY_BASE
├── resources
│   └── jetty-logging.properties
└── start.d
    ├── http.ini
    └── server.ini

The $JETTY_BASE/resources/jetty-logging.properties is created by the [files] directives of the logging-jetty module, which is a transitive dependency of the server module.

Disabling Modules

A module is enabled because the correspondent $JETTY_BASE/start.d/*.ini file contains a --module=<name> directive.

Commenting out the --module=<name> directive effectively disables the module.

Deleting the correspondent $JETTY_BASE/start.d/*.ini file also disables the module.

Editing *.ini Files

You can now edit the $JETTY_BASE/start.d/*.ini configuration files, typically by uncommenting properties to change their default value.

The $JETTY_BASE/start.d/*.ini configuration file may be missing, if the correspondent module is a transitive dependency. You can easily generate the configuration file by explicitly enabling the module, for example to generate the $JETTY_BASE/start.d/logging-jetty.ini configuration file you would issue the following command (the module order does not matter):

$ java -jar $JETTY_HOME/start.jar --add-modules=server,http,logging-jetty

The $JETTY_BASE directory structure is now:

$JETTY_BASE
├── resources
│   └── jetty-logging.properties
└── start.d
    ├── http.ini
    ├── logging-jetty.ini
    └── server.ini

You want to edit the $JETTY_BASE/start.d/*.ini configuration files so that the configuration is applied every time Jetty is started (or re-started).

For example, $JETTY_BASE/start.d/http.ini contains the following property, commented out:

http.ini
# jetty.http.port=8080

You can change the clear-text HTTP port Jetty listens to by uncommenting that property and changing its value:

http.ini
jetty.http.port=9876

When Jetty is started (or re-started) this configuration is applied and Jetty will listen for clear-text HTTP/1.1 on port 9876.

Enabling Modules on Command Line

You can also enable a module transiently, only for the current execution of the java -jar $JETTY_HOME/start.jar command.

If you have an empty $JETTY_BASE, the following command enables the server and http modules, but does not create any $JETTY_BASE/start.d/*.ini files.

$ java -jar $JETTY_HOME/start.jar --module=server,http

Since there are no $JETTY_BASE/start.d/*.ini files, you can only customize the properties via the command line, for example:

$ java -jar $JETTY_HOME/start.jar --module=server,http jetty.http.port=9876

Enabling modules on the command line is useful to verify that the modules work as expected, or to try different configurations.

It is possible to enable some module persistently via --add-modules and some other module transiently via --module.

Remember that once the current execution terminates, the modules enabled transiently on the command line via --module and their configuration are not saved and will not be enabled on the next execution (unless you specify them again on the command line).

Adding Your Own Modules

Refer to the custom module section for the details about how to create your own modules.

You can add your own modules by adding a $JETTY_BASE/modules/*.mod file.

For example, you may want to add a Postgres JDBC driver to the server class-path, to avoid that each deployed web application bring its own version. This allows you to control the exact Postgres JDBC driver version for all web applications.

Create the $JETTY_BASE/modules/postgresql.mod file:

postgresql.mod
[description]
Postgres JDBC Driver Module

[lib]
lib/postgresql-${postgresql-version}.jar

[files]
maven://org.postgresql/postgresql/${postgresql-version}|lib/postgresql-${postgresql-version}.jar

[ini]
postgresql-version?=42.6.0

[ini-template]
## Postgres JDBC version.
# postgresql-version=42.6.0

Then enable it:

$ java -jar $JETTY_HOME/start.jar --add-modules=postgresql

Enabling the postgresql module will execute the [files] directive (downloading the *.jar file from Maven Central if not already present) and create the $JETTY_BASE/start.d/postgresql.ini with the content of the [ini-template] section.

The [lib] section ensures that the specified file is in the server class-path when Jetty is started.

You can display the Jetty configuration to verify that the server class-path is correct.

Custom Module with JVM Options

Using a custom Jetty module, you can customize the JVM startup options.

This is useful if you need to start Jetty and want to specify JVM options such as:

  • -Xmx, to specify the max heap size

  • -Xlog:gc, to specify the GC log file and options

  • -javaagent, to specify Java agents

  • -XX: options, for example to specify the GC implementation

  • --enable-preview, to enable Java preview features

Start by creating $JETTY_BASE/modules/jvm.mod:

jvm.mod
[description]
JVM Options Module

[exec]
-Xmx1g
-Xlog:gc*,gc+stats=off:file=logs/gc.log:time,level,tags

Enable it:

$ java -jar $JETTY_HOME/start.jar --add-modules=jvm

Since the module defines an [exec] section, it will fork another JVM when Jetty is started.

This means that when you start Jetty, there will be two JVMs running: one created by you when you run java -jar $JETTY_HOME/start.jar, and another forked by the Jetty start mechanism with the JVM options you specified (that cannot be applied to an already running JVM).

Again, you can display the JVM command line to verify that it is correct.

The second JVM forked by the Jetty start mechanism when one of the modules requires forking, for example a module that contains an [exec] section, may not be desirable, and may be avoided as explained in this section.

Displaying the Configuration

Once you have enabled and configured the $JETTY_BASE, you can display the configuration to verify that it is correct.

Using the standard server and http Jetty modules, and the postgresql and jvm custom Jetty module defined above, you obtain:

$ java -jar $JETTY_HOME/start.jar --list-config
Enabled Modules:
----------------
  0) resources                 transitive provider of resources for logging-jetty
  1) logging/slf4j             transitive provider of logging/slf4j for logging-jetty
                               dynamic dependency of logging-jetty
  2) logging-jetty             transitive provider of logging for threadpool
                               transitive provider of logging for bytebufferpool
                               transitive provider of logging for server
  3) bytebufferpool            transitive provider of bytebufferpool for server
                               ini template available with --add-modules=bytebufferpool
  4) threadpool                transitive provider of threadpool for server
                               ini template available with --add-modules=threadpool
  5) jvm                       ${jetty.base}/start.d/jvm.ini
  6) server                    ${jetty.base}/start.d/server.ini
  7) http                      ${jetty.base}/start.d/http.ini
  8) postgresql                ${jetty.base}/start.d/postgresql.ini

JVM Version & Properties:
-------------------------
 java.home = /path/to/java.home
 java.vm.vendor = Eclipse Adoptium
 java.vm.version = 23+37
 java.vm.name = OpenJDK 64-Bit Server VM
 java.vm.info = mixed mode, sharing
 java.runtime.name = OpenJDK Runtime Environment
 java.runtime.version = 23+37
 java.io.tmpdir = /path/to/jetty.home-base/work
 user.dir = /path/to/jetty.home-base
 user.language = en
 user.country = US

Jetty Version & Properties:
---------------------------
 jetty.version = 12.0.15-SNAPSHOT
 jetty.tag.version = jetty-12.0.15-SNAPSHOT
 jetty.build = e9d61a16862f18d4c20f422e490e27e66c38d684
 jetty.home = /path/to/jetty.home
 jetty.base = /path/to/jetty.home-base

Config Search Order:
--------------------
 <command-line>
 ${jetty.base} -> /path/to/jetty.home-base
 ${jetty.home} -> /path/to/jetty.home

Forked JVM Arguments:
---------------------
 -Xmx1g
 -Xlog:gc*,gc+stats=off:file=logs/gc.log:time,level,tags

System Properties:
------------------
 (no system properties specified)

Properties: Jetty
-----------------
 java.version = 23
 java.version.major = 23
 java.version.micro = 0
 java.version.minor = 0
 java.version.platform = 23
 jetty.base = /path/to/jetty.home-base
 jetty.base.uri = file:///path/to/jetty.home-base
 jetty.home = /path/to/jetty.home
 jetty.home.uri = file:///path/to/jetty.home
 jetty.webapp.addHiddenClasses = org.eclipse.jetty.logging.,${jetty.home.uri}/lib/logging/,org.slf4j.
 postgresql-version = 42.6.0
 runtime.feature.alpn = true
 slf4j.version = 2.0.13

Classpath: Jetty
----------------
Version Information on 9 entries in the classpath.
Note: order presented here is how they would appear on the classpath.
      changes to the --module=name command line options will be reflected here.
 0:                    (dir) | ${jetty.base}/resources
 1:                   2.0.13 | ${jetty.home}/lib/logging/slf4j-api-2.0.13.jar | http://www.opensource.org/licenses/mit-license.php
 2:         12.0.15-SNAPSHOT | ${jetty.home}/lib/logging/jetty-slf4j-impl-12.0.15-SNAPSHOT.jar | EPL-2.0 OR Apache-2.0
 3:         12.0.15-SNAPSHOT | ${jetty.home}/lib/jetty-http-12.0.15-SNAPSHOT.jar | EPL-2.0 OR Apache-2.0
 4:         12.0.15-SNAPSHOT | ${jetty.home}/lib/jetty-server-12.0.15-SNAPSHOT.jar | EPL-2.0 OR Apache-2.0
 5:         12.0.15-SNAPSHOT | ${jetty.home}/lib/jetty-xml-12.0.15-SNAPSHOT.jar | EPL-2.0 OR Apache-2.0
 6:         12.0.15-SNAPSHOT | ${jetty.home}/lib/jetty-util-12.0.15-SNAPSHOT.jar | EPL-2.0 OR Apache-2.0
 7:         12.0.15-SNAPSHOT | ${jetty.home}/lib/jetty-io-12.0.15-SNAPSHOT.jar | EPL-2.0 OR Apache-2.0
 8:                   42.6.0 | ${jetty.base}/lib/postgresql-42.6.0.jar | BSD-2-Clause

Active XMLs: Jetty
------------------
 ${jetty.home}/etc/jetty-bytebufferpool.xml
 ${jetty.home}/etc/jetty-threadpool.xml
 ${jetty.home}/etc/jetty.xml
 ${jetty.home}/etc/jetty-http.xml

Note how the configuration displayed above includes:

  • In the list of enabled modules, the postgresql and jvm modules

  • In the list of JVM arguments, those specified by the jvm module

  • In the server class-path, the *.jar file specified by the postgresql module

Displaying the JVM Command Line

The Jetty start mechanism can display a full JVM command line that will start Jetty with the configuration you specified, with the --dry-run option:

$ java -jar $JETTY_HOME/start.jar --dry-run

The full JVM command line generated by --dry-run can be split in various parts that can be used individually, for example in scripts.

Furthermore, Jetty modules may specify the --exec option that will fork a second JVM to start Jetty, which may not be desirable. Some option, such as --jpms, imply --exec, as it won’t be possible to modify the module-path in the already started JVM.

To start Jetty without forking a second JVM, the --dry-run option can be used to generate a command line that is then executed so that starting Jetty only spawns one JVM.

You can use the --dry-run option as explained below to avoid forking a second JVM when using modules that have the [exec] section, or the --exec option, or when using the --jpms option.

For example, using the --dry-run option with the jvm.mod introduced in this section produces the following command line:

$ java -jar $JETTY_HOME/start.jar --dry-run
/path/to/java.home/bin/java \
-Djava.io.tmpdir='/path/to/jetty.home-base/work' \
-Djetty.home='/path/to/jetty.home' \
-Djetty.base='/path/to/jetty.home-base' \
-Xmx1g \
'-Xlog:gc*,gc+stats=off:file=logs/gc.log:time,level,tags' \
--class-path \
'/path/to/jetty.home-base/resources:/path/to/jetty.home/lib/logging/slf4j-api-2.0.13.jar:/path/to/jetty.home/lib/logging/jetty-slf4j-impl-12.0.15-SNAPSHOT.jar:/path/to/jetty.home/lib/jetty-http-12.0.15-SNAPSHOT.jar:/path/to/jetty.home/lib/jetty-server-12.0.15-SNAPSHOT.jar:/path/to/jetty.home/lib/jetty-xml-12.0.15-SNAPSHOT.jar:/path/to/jetty.home/lib/jetty-util-12.0.15-SNAPSHOT.jar:/path/to/jetty.home/lib/jetty-io-12.0.15-SNAPSHOT.jar' \
org.eclipse.jetty.xml.XmlConfiguration \
java.version=23 \
jetty.base='/path/to/jetty.home-base' \
jetty.base.uri='file:///path/to/jetty.home-base' \
jetty.home='/path/to/jetty.home' \
jetty.home.uri='file:///path/to/jetty.home' \
jetty.webapp.addHiddenClasses='org.eclipse.jetty.logging.,file:///path/to/jetty.home/lib/logging/,org.slf4j.' \
runtime.feature.alpn=true \
slf4j.version=2.0.13 \
'/path/to/jetty.home/etc/jetty-bytebufferpool.xml' \
'/path/to/jetty.home/etc/jetty-threadpool.xml' \
'/path/to/jetty.home/etc/jetty.xml' \
'/path/to/jetty.home/etc/jetty-http.xml''

You can then run the generated command line.

For example, in the Linux bash shell you can run it by wrapping it into $(...):

$ $(java -jar $JETTY_HOME/start.jar --dry-run)

The --dry-run option is quite flexible and below you can find a few examples of how to use it to avoid forking a second JVM, or generating scripts or creating an arguments file that can be passed to (a possibly alternative) java executable.

To display the java executable used to start Jetty:

$ java -jar $JETTY_HOME/start.jar --dry-run=java
/path/to/java.home/bin/java

To display the JVM options:

$ java -jar $JETTY_HOME/start.jar --dry-run=opts
-Djava.io.tmpdir='/path/to/jetty.home-base/work' \
-Djetty.home='/path/to/jetty.home' \
-Djetty.base='/path/to/jetty.home-base' \
-Xmx1g \
'-Xlog:gc*,gc+stats=off:file=logs/gc.log:time,level,tags'

To display the JVM class-path:

$ java -jar $JETTY_HOME/start.jar --dry-run=path
--class-path \
'/path/to/jetty.home-base/resources:\
/path/to/jetty.home/lib/logging/slf4j-api-2.0.13.jar:\
/path/to/jetty.home/lib/logging/jetty-slf4j-impl-12.0.15-SNAPSHOT.jar:\
/path/to/jetty.home/lib/jetty-http-12.0.15-SNAPSHOT.jar:\
/path/to/jetty.home/lib/jetty-server-12.0.15-SNAPSHOT.jar:\
/path/to/jetty.home/lib/jetty-xml-12.0.15-SNAPSHOT.jar:\
/path/to/jetty.home/lib/jetty-util-12.0.15-SNAPSHOT.jar:\
/path/to/jetty.home/lib/jetty-io-12.0.15-SNAPSHOT.jar'

To display the JVM class-path and module-path, if you want to start Jetty using JPMS with the --jpms option:

$ java -jar $JETTY_HOME/start.jar --jpms --dry-run=path
--module-path \
'/path/to/jetty.home/lib/jetty-server-12.0.15-SNAPSHOT.jar:\
/path/to/jetty.home/lib/logging/slf4j-api-2.0.13.jar:\
/path/to/jetty.home/lib/logging/jetty-slf4j-impl-12.0.15-SNAPSHOT.jar:\
/path/to/jetty.home/lib/jetty-io-12.0.15-SNAPSHOT.jar:\
/path/to/jetty.home/lib/jetty-util-12.0.15-SNAPSHOT.jar:\
/path/to/jetty.home/lib/jetty-xml-12.0.15-SNAPSHOT.jar:\
/path/to/jetty.home/lib/jetty-http-12.0.15-SNAPSHOT.jar' \
--class-path \
'/path/to/jetty.home-base/resources' \
--add-modules \
ALL-MODULE-PATH

To display the JVM main class:

$ java -jar $JETTY_HOME/start.jar --dry-run=main
org.eclipse.jetty.xml.XmlConfiguration

To display the JVM main class when starting Jetty using JPMS:

$ java -jar $JETTY_HOME/start.jar --jpms --dry-run=main
--module org.eclipse.jetty.xml/org.eclipse.jetty.xml.XmlConfiguration

The main class is typically Jetty’s XmlConfiguration class that accepts, as program arguments, a list of properties and a list of Jetty XML files to process. The Jetty XML files compose together the Jetty components that are then configured with the values from the command line properties.

To display the program arguments passed to the main class:

$ java -jar $JETTY_HOME/start.jar --dry-run=args
java.version=23 \
jetty.base='/path/to/jetty.home-base' \
jetty.base.uri='file:///path/to/jetty.home-base' \
jetty.home='/path/to/jetty.home' \
jetty.home.uri='file:///path/to/jetty.home' \
jetty.webapp.addHiddenClasses='org.eclipse.jetty.logging.,file:///path/to/jetty.home/lib/logging/,org.slf4j.' \
runtime.feature.alpn=true \
slf4j.version=2.0.13 \
'/path/to/jetty.home/etc/jetty-bytebufferpool.xml' \
'/path/to/jetty.home/etc/jetty-threadpool.xml' \
'/path/to/jetty.home/etc/jetty.xml' \
'/path/to/jetty.home/etc/jetty-http.xml''

Note how the program arguments are a list of properties in the form <name>=<value> and a list of Jetty XML files.

The various parts of the full JVM command line can be combined to leverage the arguments file feature (that is, specify the JVM options in a file rather than on the command line) that is built-in in the java executable:

$ java -jar $JETTY_HOME/start.jar --dry-run=opts,path,main,args > /tmp/jvm_cmd_line.txt
$ /some/other/java @/tmp/jvm_cmd_line.txt

Using --dry-run=opts,path,main,args can be used to avoid that the Jetty start mechanism forks a second JVM when using modules that require forking:

$ java $(java -jar $JETTY_HOME/start.jar --dry-run=opts,path,main,args)

The output of different --dry-run executions can be creatively combined in a shell script:

$ OPTS=$(java -jar start.jar --dry-run=opts,path)
$ MAIN=$(java -jar start.jar --dry-run=main)
$ ARGS=$(java -jar start.jar --dry-run=args)
$ java $OPTS -Dextra=opt $MAIN $ARGS extraProp=value extra.xml

Starting Jetty

After you have configured the $JETTY_BASE directory, as explained in this section, you can start Jetty as a standalone server.

In the start mode, the Jetty start mechanism computes a JVM command line with JVM options, system properties, class-path, module-path, main class and program arguments, and then executes it, forking a new JVM if necessary.

The Jetty start mechanism performs these steps:

  1. Loads all the Jetty modules files (that have extension *.mod) from the modules/ subdirectory of each configuration source directory (see this section for the list of configuration sources). In this way, a Jetty module graph can be built in memory, where the module dependencies form the edges of the graph and each node contains the metadata information declared by each module (for example, the libraries that it needs, the XML files to process, and so on), in preparation for the next step.

  2. Reads the Jetty module configuration files (that have extension *.ini) from the start.d/ subdirectory of each configuration source directory and from the command line. This step produces a list of enabled modules; for each enabled module all its dependencies are transitively resolved by navigating the graph built in the previous steps.

  3. Processes the list of enabled (explicitly and transitively) modules, gathering the list of libraries to add to the class-path, the JPMS directives to add to the command line, the properties and XML files to add as program arguments, etc., so that a full JVM command line can be generated.

  4. Executes the command line, either in-JVM or by forking a second JVM (if the --exec option is present or implied by other options such as --jpms), and waits for the JVM, or the forked JVM, to exit.

Server Class-Path

When the Jetty server is started in-JVM, the server class-path gathered by processing the enabled modules is organized in a URLClassLoader, the Jetty Start ClassLoader, that is a child of the System ClassLoader:

Diagram

The System ClassLoader only has $JETTY_HOME/start.jar in its class-path, since the JVM was started with java -jar $JETTY_HOME/start.jar. The Jetty Start ClassLoader has in its class-path the *.jar files gathered by processing the enabled modules, typically from $JETTY_HOME/lib/jetty-*.jar, but possibly also from $JETTY_BASE/lib/*.jar if custom modules extend the server class-path with their own *.jar files.

When the Jetty server is started in a forked JVM, there will be two JVMs: one started by you with java -jar $JETTY_HOME/start.jar and one forked by the Jetty start mechanism. In the forked JVM, the System ClassLoader has the server class-path and/or module-path in its class-path, since the forked JVM is started with java --class-path $JETTY_HOME/lib/jetty-server-<version>.jar:...:

Diagram

It is worth mentioning that there are two standard Jetty modules that allow you to easily add entries to the Jetty server class-path:

  • The resources module, which adds the $JETTY_BASE/resources directory to the server class-path. This is useful if you have third party libraries that lookup resources from the class-path: just put those resources in the $JETTY_BASE/resources/ directory.
    Logging libraries often perform class-path lookup of their configuration files (for example, log4j.properties, log4j.xml, logging.properties, and logback.xml), so $JETTY_BASE/resources/ is the ideal place to add those files.

  • The the ext module, that adds all the *.jar files under the $JETTY_BASE/lib/ext/ directory, and subdirectories recursively, to the server class-path.

    On one hand, the ext module provides a handy place to put third party libraries and their dependencies; on the other hand, the $JETTY_BASE/lib/ext/ directory may become a confused mixture of many *.jar files from different third party libraries.

    Prefer to group third party libraries and their dependencies into their own directories using custom modules, or at least group them into $JETTY_BASE/lib/ext/ subdirectories such as $JETTY_BASE/lib/ext/util/ or $JETTY_BASE/lib/ext/acme/.

Assembling Jetty Components

The Jetty start mechanism eventually invokes, by default, main class org.eclipse.jetty.xml.XmlConfiguration, passing properties and Jetty XML files as program arguments.

The Jetty XML files are nothing more than Java code in XML format.

The XML files are processed to instantiate Jetty components such as org.eclipse.jetty.server.Server or org.eclipse.jetty.util.ssl.SslContextFactory$Server. The components are then assembled together to provide the configured Jetty features.

The Jetty XML files are parametrized using properties, and a property is just a name/value pair.

This parametrization of the XML files allows an XML file that resides in $JETTY_HOME/etc/ to declare a property such as jetty.http.port, and allow this property to be set in a $JETTY_BASE/start.d/http.ini file, so that you don’t need to change the XML files in $JETTY_HOME, but only change files in your $JETTY_BASE.

You can write your own custom modules with your own Jetty XML files, and your own properties, to further customize Jetty.

Stopping Jetty

When Jetty is started, the Jetty components that you have configured by enabling Jetty modules are assembled and started.

If you have started Jetty from a terminal, you can exit the Jetty JVM by hitting Ctrl+C on the same terminal.

Similarly, from a different terminal, you can exit the Jetty JVM using kill -INT <pid> or kill -TERM <pid>.

In the three cases above, the JVM is exited, but by default Jetty components are not stopped. If you want to stop the Jetty components, to stop Jetty more gracefully, you can start Jetty with this property:

$ java -jar $JETTY_HOME/start.jar jetty.server.stopAtShutdown=true

This property can also be set in $JETTY_BASE/start.d/server.ini so that it is persistently configured across Jetty restarts (see also the server module).

The jetty.server.stopAtShutdown property configures a JVM shutdown hook that is run, stopping the Server instance, when the JVM exits.

Obviously, the JVM can also be stopped with kill -KILL <pid> that exits the process abruptly without running the JVM shutdown hooks.

Stopping Jetty from Remote

You can configure a Jetty server so that it can be stopped by remote clients using a command sent through a TCP socket.

You can start Jetty with the following properties:

  • stop.host, the host name Jetty will bind to listen for stop commands. Defaults to 127.0.0.1 which means that the stop command can be issued only clients that run on the same host as Jetty.

  • stop.port, the port number Jetty will listen to for stop commands. Defaults to -1, which means that Jetty will not listen to any port.

  • stop.key, the password to verify when a stop command is received. Defaults to a password that is randomly generated and printed when Jetty starts.

$ java -jar $JETTY_HOME/start.jar stop.port=8181
Error binding ShutdownMonitor to port 8181: java.net.BindException: Address already in use
2024-10-01 18:02:06.488:INFO :oejs.Server:main: jetty-12.0.15-SNAPSHOT; built: 2024-10-01T17:53:16.597Z; git: e9d61a16862f18d4c20f422e490e27e66c38d684; jvm 23+37
2024-10-01 18:02:06.553:INFO :oejs.AbstractConnector:main: Started ServerConnector@11fc564b{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2024-10-01 18:02:06.581:INFO :oejs.Server:main: Started oejs.Server@6150c3ec{STARTING}[12.0.15-SNAPSHOT,sto=5000] @1953ms

In the example above, Jetty is started with just the stop.port property, and the stop.key is printed on the terminal when Jetty starts.

You can choose your own stop.key, but make sure it’s a strong password.

A remote client can now use the Jetty start mechanism to stop the remote Jetty server:

$ java -jar $JETTY_HOME/start.jar --stop stop.port=8181 stop.key=<stop.key>

Note the --stop command along with the stop.port and stop.key properties. The stop.key must be the same as the one of remote Jetty server, either the one you chose, or the one printed on the terminal when Jetty starts.

Remote clients can wait for the remote Jetty server to shut down by specifying the stop.wait property with the number of seconds to wait:

$ java -jar $JETTY_HOME/start.jar --stop stop.port=8181 stop.key=<stop.key> stop.wait=15

If the time specified elapses, without the confirmation that the remote Jetty server stopped, then the --stop command exits with a non-zero return code.

Start Mechanism Logging

The steps performed by the Jetty start mechanism are logged by the StartLog class, that outputs directly, by default, to System.err.

This is necessary to avoid that the Jetty start mechanism depend on logging libraries that may clash with those defined by Jetty logging modules, when Jetty is started in-VM.

This section is about the logging performed by the Jetty start mechanism before it configures and starts Jetty. See the logging section for information about logging when Jetty starts.

You can enable DEBUG level logging with the --debug command line option, for both the tool and start modes:

$ java -jar $JETTY_HOME/start.jar --debug ...

You can send the start log output to a file, by default relative to $JETTY_BASE, with the --start-log-file=<file> option:

$ java -jar $JETTY_HOME/start.jar --debug --start-log-file=start.log ...

This is useful for capturing startup issues where the Jetty-specific logger has not yet kicked in due to a possible startup configuration error.

Usage Reference

Usage:

$ java -jar $JETTY_HOME/start.jar [command] [options...]

Commands can be of two types: report commands or configuration commands.
Commands execute and then exit the JVM.
Options can be specified with or without commands.
When no command is specified, Jetty is started with the given options.

Report Commands:
----------------

  --help
                   Prints this help / usage information.

  --version
                   Prints the version information for Jetty and
                   dependent jars, then exits.

  --list-classpath
                   Prints the class-path (or module-path) information that
                   will be used to start Jetty.

  --list-config
                   Lists the resolved configuration that will be used to
                   start Jetty.
                   Output includes:
                     o  Enabled Jetty modules
                     o  Java environment
                     o  Jetty environment
                     o  Config file search order
                     o  JVM arguments
                     o  System properties
                     o  Properties
                     o  Java class-path or module-path
                     o  XML configuration files

  --list-modules
                   Lists the modules defined in ${jetty.base}/modules/*.mod
                   and then in ${jetty.home}/modules/*.mod.

  --list-modules=<tag>(,<tag>)*
                   Lists the modules by tag. Use '*' for all tags.
                   Prefix a tag with '-' to exclude the tag.
                   The special tag "internal" is always excluded unless it is
                   explicitly included.

  --list-all-modules
                   Lists all modules.

  --show-modules=<module>(,<module>)*
                   Shows the detail of the listed modules, including
                   dependencies, tags, libraries and XMLs.

  --stop
                   Sends a stop signal to the running Jetty instance.
                   The running Jetty instance must have been started with a
                   stop.port=<port> property and the --stop command must
                   be executed with the same property.

  --dry-run
                   Prints the command line that start.jar generates,
                   in a format usable by a POSIX compliant shell, then exits.
                   This may be used to generate command lines into scripts:
                     $ java -jar start.jar --dry-run > jetty.sh

  --dry-run=<part>(,<part>)*
                   Prints specific parts of the command line in a format usable by
                   a POSIX compliant shell. The parts are:
                     o  "java" - the JVM to run
                     o  "opts" - the JVM options (e.g. -D, -X and -XX flags)
                     o  "path" - the JVM class-path and/or the JPMS module-path
                     o  "main" - the main class to run
                     o  "args" - the arguments passed to the main class
                     o  "envs" - the generated XML files to create the environments

Configure Commands:
-------------------

  --add-modules=<moduleName>(,<moduleName>)*
                   Adds the given modules to the list of modules enabled at
                   when Jetty starts.
                   Transitive dependencies are followed and dependent
                   modules may also explicitly added.
                   Modules are added by creating an *.ini file in the
                   ${jetty.base}/start.d/ directory.
                   The *.ini file contains the --module option that enables
                   the module, and any other option defined in the module's
                   [ini-template] section.
                   If the *.ini file specifies properties, these may be
                   overridden by specifying the same properties on the
                   command line.

                   If a module is transitively enabled, its *.ini file will
                   not be generated.
                   To generate the *.ini file, the module must be explicitly
                   listed in the --add-modules=... command.

                   This option replaces the deprecated --add-to-start and
                   --add-to-startd commands.

  --create-start-d
                   Creates a ${jetty.base}/start.d directory.
                   If the ${jetty.base}/start.ini file exists, then it is
                   moved into the ${jetty.base}/start.d/ directory.
                   Using a ${jetty.base}/start.d/ directory is the default and
                   this option is only needed to either force the creation of
                   the ${jetty.base}/start.d/ directory, or to move a
                   ${jetty.base}/start.ini file to ${jetty.base}/start.d/.

  --create-start-ini
                   Creates a ${jetty.base}/start.ini file.
                   If a ${jetty.base}/start.d/ directory exists, then all
                   the contained *.ini files are concatenated into the
                   ${jetty.base}/start.ini file.

  --update-ini
                   Scans all the ${jetty.base}/start.d/*.ini files and updates
                   any property with values specified on the command line.
                   For example:
                     $ java -jar ${jetty.host}/start.jar --update-ini jetty.http.port=8888

  --create-files
                   Creates any missing files that are required by enabled
                   modules, as specified in their [files] section.
                   This may download a file from the network if a HTTP URI
                   is specified in the [files] section.

  --write-module-graph=<filename>
                   Creates a graphviz *.dot file of the module graph as it
                   is configured for the current ${jetty.base}.
                   See https://graphviz.org/ for details on how to post-process
                   this file into the output best suited for your needs.

Options:
--------

  --modules=<moduleName>(,<moduleName>)*
                   Enables a module for this execution.
                   To enable a module for all future executions, use the
                   --add-modules command.
                   Note: this option is used in the ${jetty.base}/start.ini
                   file or in ${jetty.base}/start.d/*.ini files created by
                   the --add-modules command.

  --libs=<classpath>
                   Adds the specified class-path entries to the the server
                   class-path (or module-path).

  --files=<uri>|<location>
  --download=<uri>|<location>
                   Downloads a file from the given URI, if it does
                   not already exist at the given location.
                   Note: the location is always relative to ${jetty.base}.
                   You might need to escape the pipe "\|" to use it in
                   some shell environments.
                   Supported schemes:
                     http:     download from http (unsecure) website
                     https:    download from https (secure) website
                     maven:    download from maven repository system
                               first checking local repository
                               see `maven.local.repo` field below
                               then global repository
                               see `maven.repo.uri` field below

                     basehome: download relative path from active
                               configured jetty dirs (eg: `${jetty.base}`
                               and any `--include-jetty-dir` and finally
                               checking the `${jetty.home}`)


  --exec
                   Executes the generated command line in a forked JVM
                   (see the --dry-run command).
                   This can be used when ${jetty.base}/start.d/*.ini files
                   contain -D, -X or -XX arguments, but creates an extra
                   JVM process.

  --exec-properties=<filename>
                   Assigns a fixed name to the file used to transfer
                   properties to the sub process. This allows the
                   generated properties file to be saved and reused.
                   Without this option, a temporary file is used.

  --commands=<filename>
                   Uses each line of the specified file as arguments on the
                   JVM command line.

  --jpms
                   Starts Jetty in JPMS mode in a forked JVM (see also the
                   --dry-run command).
                   The library *.jar files are set on the forked JVM module-path
                   (rather than the forked JVM class-path), while directories
                   are set on the forked JVM class-path.
                   The main class is specified with the JPMS option
                   --module <moduleName>/<mainClassName>.

  --debug
                   Enables debug output of the startup execution.
                   Note: this does not setup debug logging for Jetty itself,
                   only for the startup execution.
                   If you want debug logging for Jetty, configure one of the
                   available logging modules using the --add-modules command.

  --start-log-file=<filename>
                   A filename, relative to ${jetty.base}, where all startup
                   output will be sent.  This is useful for capturing startup
                   issues when the Jetty logging module has not yet started
                   due to configuration errors.

  --allow-insecure-http-downloads
                   Allow the use of insecure `http://` scheme for content download.

  --approve-all-licenses
                   Approves all license questions from modules that have
                   particular license requirements.
                   Useful for enabling modules from a script, so that it
                   does not require user interaction.

  --skip-create-files=<moduleName>(,<moduleName>)*
  --skip-file-validation=<moduleName>(,<moduleName>)*
                   Disables the creation of files as specified by the
                   [files] section of the specified modules.
                   Useful if a logging module specifies a *.properties
                   config file, but you want to use that module with an
                   *.xml config file instead.

  --add-config-dir=<path>
  --include-jetty-dir=<path>
                   Includes the specified directory as a configuration source.
                   This directory behaves similarly to ${jetty.base} but sits
                   at a layer between ${jetty.home} and ${jetty.base}.
                   Useful when you want to apply a common "corporate"
                   configuration to all specific ${jetty.base} directories
                   without having to modify ${jetty.home}.

  jetty.home=<directory>
                   Sets the ${jetty.home} directory.
                   By default it is resolved from the start.jar file path.

  jetty.base=<directory>
                   Sets the ${jetty.base} directory.
                   By default it is resolved from the current directory path.

  stop.host=<string>
                   Used with the --stop command.
                   Specifies the host where the Jetty server to stop is
                   running (defaults to 127.0.0.1).

  stop.port=<number>
                   Used with the --stop command.
                   Specifies the port to use to contact the Jetty server
                   to stop.

  stop.key=<alphanumeric>
                   Used with the --stop command.
                   The passphrase required to stop the Jetty server.

  stop.wait=<number>
                   Used with the --stop command.
                   The time, in seconds, to wait for confirmation that the
                   running Jetty server has stopped.
                   If not specified, the stopper will not wait.

  maven.local.repo=<dir>
                   The maven local repository directory to find
                   and store maven artifacts.
                   Defaults to:
                     1. Environment variable `JETTY_MAVEN_LOCAL_REPO`
                     2. Environment variable `MAVEN_LOCAL_REPO`
                     3. Directory ${home}/.m2/repository

  maven.repo.uri=<url>
                   The base URL to use to download Maven dependencies.
                   Defaults to: https://repo1.maven.org/maven2/.

  <name>=<value>
                  Specifies a property value that overrides the same
                  property defined in a ${jetty.base}/start.d/*.ini file,
                  or in the [ini] section of a *.mod file.

                  <name>=<value>
                    Sets the property value unconditionally.
                  <name>+=<value>
                    Appends the given value to the existing value.
                  <name>?=<value>
                    Sets the property value only if it is not already set.

  -D<name>=<value>
                  Specifies a system property, as well as a start property.
                  Note: this is a program argument that is interpreted and
                  added to the existing JVM system properties.

  <xml-file>
                  Specifies a Jetty XML file relative to ${jetty.base}.
                  This file is in addition to the Jetty XML files resolved
                  from the [xml] sections of the enabled modules.