//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

[[startup-modules]]
=== Managing Startup Modules

The standard Jetty Distribution ships with several modules defined in `${jetty.home}/modules/`.
Modules interact with Jetty XML files to configure options and parameters for the server and are the primary configuration method for Jetty distributions.
Modules allow flexibility for implementations and their plug-and-play nature makes adding or removing server functionality virtually painless.

[[enabling-modules]]
==== Enabling Modules
____
[TIP]
The default distribution has a co-mingled `${jetty.home}` and `${jetty.base}` where the directories for `${jetty.home}` and `${jetty.base}` point to the same location.
It is highly encouraged that you learn about the differences in link:#startup-base-and-home[Jetty Base vs Jetty Home] and take full advantage of this setup.
____

Enabling a module is a simple process: simply add the `--add-to-start=<module-name1>,<module-name2>,...etc.` syntax on the command line.
Doing this will enable the specified module and any dependent modules.

An example of this with a new, empty, base directory:

If we try to start the Jetty server with no configuration or modules enabled, it will promptly exit:

include::screen-empty-base.adoc[]

By using the `--list-config` parameter to our startup command, we can see that there are no modules enabled and no Jetty XML files are active:

include::screen-empty-base-listconfig.adoc[]

Let's try adding some basic support for webapps, with automatic deploy (hot deploy), and a single basic HTTP/1.1 connector.

include::screen-http-webapp-deploy.adoc[]

This creates the webapps directory in our `mybase` directory and appended the `start.ini` file with the ini template arguments from the associated module files.
Additionally, where needed, Jetty enabled any module dependencies.

Now that we have added some modules to our server, let's run `--list-config` again to review our new configuration.

include::screen-http-webapp-deploy-listconfig.adoc[]

You now have a configured and functional server, albeit with no webapps deployed.
At this point you can place a webapp (war file) in the `mybase/webapps/` directory and and start Jetty.

[[start-vs-startd]]

==== Start.ini vs. Start.d

In the above example, when a module is activated the contents of that module file are added in `${jetty.base}/start.ini`.
As additional modules are added, their contents are appended to this file.
This can be beneficial if you want all of your module configurations in a single file, but for large server instances with lots of modules it can pose a challenge to quickly find and make changes or to remove a module.

As an alternative to a single `start.ini` file you can opt to house modules in a `${jetty.base}/start.d` directory.
Modules activated when a `start.d` directory exists will be stored as a single file per module.
Below is an example of a fresh `${jetty.base}` that will create a `start.d` directory and activate several modules.

[source, screen, subs="{sub-order}"]
....
[jetty.home]$ mkdir mybase
[jetty.home]$ cd mybase/
[mybase]$ java -jar ../start.jar --create-startd
INFO : Base directory was modified
[mybase]$ ls -all
total 0
drwxr-xr-x   3 staff  staff  102 Aug 29 15:16 .
drwxr-xr-x@ 26 staff  staff  884 Aug 29 15:16 ..
drwxr-xr-x   6 staff  staff  204 Aug 29 15:19 start.d

[mybase]$ java -jar ../start.jar --add-to-start=server,client,webapp,websocket
INFO : webapp          initialised in ${jetty.base}/start.d/webapp.ini
INFO : server          initialised in ${jetty.base}/start.d/server.ini
INFO : websocket       initialised in ${jetty.base}/start.d/websocket.ini
INFO : client          initialised in ${jetty.base}/start.d/client.ini
INFO : Base directory was modified
[mybase]$ cd start.d/
[mybase]$ ls -all
total 32
drwxr-xr-x  6 staff  staff   204 Aug 29 15:19 .
drwxr-xr-x  3 staff  staff   102 Aug 29 15:16 ..
-rw-r--r--  1 staff  staff   175 Aug 29 15:19 client.ini
-rw-r--r--  1 staff  staff  2250 Aug 29 15:19 server.ini
-rw-r--r--  1 staff  staff   265 Aug 29 15:19 webapp.ini
-rw-r--r--  1 staff  staff   177 Aug 29 15:19 websocket.ini
....

In the example, we first create a new `${jetty.base}` and then create the `start.d` directory with the `--create-startd` command.
Next, we use the `--add-to-start` command which activates the modules and creates their respective ini files in the `start.d` directory.

If you have an existing `start.ini` file but would like to use the `start.d` structure for additional modules, you can use the `--create-startd` command as well.
Doing this will create the `start.d` directory and copy your existing `start.ini` file in to it.
Any new modules added to the server will have their own `<module name>.ini` file created in the `start.d` directory.

[source, screen, subs="{sub-order}"]
....
[mybase]$ java -jar ../start.jar --add-to-start=server,client,webapp,websocket
INFO : webapp          initialised in ${jetty.base}/start.ini
INFO : server          initialised in ${jetty.base}/start.ini
INFO : websocket       initialised in ${jetty.base}/start.ini
INFO : client          initialised in ${jetty.base}/start.ini
INFO : Base directory was modified

[mybase]$ java -jar ../start.jar --create-startd
INFO : Base directory was modified
[mybase]$ tree
.
└── start.d
    └── start.ini

[mybase]$ java -jar ../start.jar --add-to-start=ssl
INFO : ssl             initialised in ${jetty.base}/start.d/ssl.ini
INFO : Base directory was modified
[mybase]$ tree
.
├── etc
│   └── keystore
└── start.d
    ├── ssl.ini
    └── start.ini
....

[NOTE]
--
It is *not* recommended to use both a `${jetty.base}/start.ini` file and a `${jetty.base}/start.d` directory at the same time and doing so can cause issues.
--

[[startup-configuring-modules]]

==== Configuring Modules

Once a module has been enabled for the server, it can be further configured to meet your needs.
This is done by editing the associated ini file for the module.
If your server setup is using a centralized ini configuration, you will edit the `${jetty.base}/server.ini` file.
If you have elected to manage each module within it's own ini file, you can find these files in the `${jetty.base}/start.d` directory.

____
[IMPORTANT]
It is important that you *do not* modify the module files in the `$JETTY_HOME/modules` directory.
$JETTY_HOME should always remain a standard of truth.
If you want to make a change to an actual module file (not the values in its `ini-template`), either edit its associated `ini` file in the `$JETTY_BASE/start.d` directory or make a copy of the desired module file and copy it to the `$JETTY_BASE` directory and edit it there.
The start.jar reads local `$JETTY_BASE/modules` files (if they exist) before scanning `$JETTY_HOME`.
____

When a module is activated, a number of properties are set by default.
To view these defaults, open up the associated ini file.
Listed in the ini file is the associated module file and any properties that can be set.

Below is an example of the `requestlog.ini` file:

[source, screen, subs="{sub-order}"]
....
# ---------------------------------------
# Module: requestlog
--module=requestlog

## 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=true

## Whether to use the extended log output
# jetty.requestlog.extended=true

## Whether to log http cookie information
# jetty.requestlog.cookies=true

## Timezone of the log entries
# jetty.requestlog.timezone=GMT

## Whether to log LogLatency
# jetty.requestlog.loglatency=false
....

The first lines name the module file being called (located in `{$jetty.home/modules}`).
Subsequent lines list properties that can be changed as well as a description for each property.
To edit a property, first un-comment the line by deleting the `#` at the start of the line, then make the change after `=` sign (such as changing a `true` value to `false`).

[[startup-disable-module]]
==== Disabling Modules

Disabling a module is an easy process.
To disable a module, comment out the `--module=` line in the associated ini file.
Deleting the ini file associated with module is another option, but may not be practical in all situations.

[[startup-listing-modules]]
==== Listing Available and Active Modules

To see which modules are __available__, use the `--list-modules` command line argument.
This command will also show you which modules are __enabled__.
Modules are sorted by the value in the `[tags]` section of the associated `.mod` file.
If there are multiple entries in the `[tags]` section, it sorts by the first tag in the list.

____
[NOTE]
By default, the `--list-modules` command line argument shows all modules that do not include `internal` in the `[tags]` section of the associated `.mod` file.
If you would like to see *all* modules, use `--list-all-modules`
____

Here's an example of the `--list-modules` command:

include::screen-list-modules.adoc[]

===== Searching Modules

Since the introduction of the module system, many new modules have been added.
As a result, looking at the module list as a whole can be somewhat overwhelming.
To narrow down which modules you would like to choose from, you can search by values listed under the `[tags]` section.
Note that when you search this way, all modules that include your criteria in it's `[tags]` section, including internal modules, will be shown.
To filter out internal modules when searching a specific module tag, simply add `-internal` to the command line.
For example, if you wanted to look at only the logging modules (excluding the internal implementation modules), you would use `--list-modules=logging,-internal`.

include::screen-list-logging-modules.adoc[]
