![]() Version: 9.4.29.v20200521 |
private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ... scalability guidance for your apps and Ajax/Comet projects ... development services for sponsored feature development
Jetty modules also act as automatic JPMS modules via the Automatic-Module-Name
attribute in the jar’s MANIFEST.MF
file.
This makes possible to run Jetty from the module-path, rather than the class-path.
We recommend using JDK 11 or greater due to the fact that JDK 11 removed all the "enterprise" modules from the JDK, and therefore it guarantees a more stable platform to base your application’s dependencies on. The classes in these "enterprise" modules were bundled with JDK 8, and present in "enterprise" modules in JDK 9 and JDK 10. With JDK 11, these "enterprise" classes are either not available in the JDK (because their corresponding module was removed), or they are present in a different module.
Because some of these "enterprise" classes are required by Jetty or by applications running in Jetty, it is better to use a stable source for those classes - in this case by using JDK 11 or greater, and explicitly referencing the "enterprise" classes as dependencies, rather than assuming they are bundled with the JDK.
To start Jetty on the module-path rather than the class-path, it is enough to add the --jpms
option to the command line, for example:
$ mkdir my-jetty-base $ cd my-jetty-base $ java -jar $JETTY_HOME/start.jar --add-to-start=http INFO : server transitively enabled, ini template available with --add-to-start=server INFO : http initialized in ${jetty.base}/start.ini INFO : threadpool transitively enabled, ini template available with --add-to-start=threadpool INFO : Base directory was modified $ java -jar $JETTY_HOME/start.jar --jpms
The example above creates a Jetty base directory and enables the http
module using the --add-to-start
command.
The server then starts Jetty on the module-path using the --jpms
option.
[NOTE] When running on the module-path using the `--jpms` option, the Jetty start mechanism will fork a second JVM passing it the right JVM options to run on the module-path. You will have two JVMs running: one that runs `start.jar` and one that runs Jetty on the module-path.
If you are interested in the details of how the command line to run Jetty on the module-path looks like, you can add the --dry-run
option:
$ java -jar $JETTY_HOME/start.jar --jpms --dry-run
This will give an output looking something like this (broken in sections for clarity):
/opt/openjdk-11+28/bin/java --module-path /opt/jetty/lib/servlet-api-3.1.jar:/opt/jetty/lib/jetty-schemas-3.1.jar:/opt/jetty/lib/jetty-http-9.4.13-SNAPSHOT.jar:... --patch-module servlet.api=/opt/jetty/lib/jetty-schemas-3.1.jar --module org.eclipse.jetty.xml/org.eclipse.jetty.xml.XmlConfiguration /opt/jetty/etc/jetty-threadpool.xml /opt/jetty/etc/jetty.xml ...
The --module-path
option specifies the list of Jetty jars.
This list depends on the Jetty modules that have been enabled via the --add-to-start
command.
The --patch-module
option is necessary for Servlet and JSP Containers to find XML DTDs and XML Schemas required to validate the various XML files present in web applications (such as web.xml
and others).
The --module
option tells the JVM to run main class XmlConfiguration
from the org.eclipse.jetty.xml
module, with the given XML files as program arguments.
When the JVM starts, module org.eclipse.jetty.xml
is added to the set of JPMS root modules; all other Jetty modules, being automatic, will be resolved and added to the module graph.
JAR files that are not modules, such as servlet-api-3.1.jar
, are on the module-path and therefore will be made automatic modules by the JVM (hence the derived module name servlet.api
for this jar, referenced by the --patch-module
command line option above).
Web applications may need additional services from the Servlet Container, such as JDBC DataSource
references or JTA UserTransaction
references.
For example, for JDBC it is typical to store, in JNDI, a reference to the connection pool’s DataSource
(such as com.zaxxer.hikari.HikariDataSource
) or a reference directly to the JDBC driver’s DataSource
(com.mysql.jdbc.jdbc2.optional.MysqlDataSource
).
Jetty needs to be able to instantiate those classes and therefore needs to be able to load those classes and all their super-classes, among which includes javax.sql.DataSource
.
When Jetty runs on the class-path, this is easily achieved by using a custom module:
mysql.mod.
[description] MySQL module [lib] lib/mysql/mysql-connector-java-*.jar
However, when running on the module-path, things are quite different.
Class javax.sql.DataSource
is in a JDK bundled module named java.sql
, which is not automatic (it’s a proper JPMS module) and it is not in the root modules set.
Because it is not an automatic module, it is not added to the module graph, and therefore needs to be added explicitly using the JVM command line --add-modules
.
To add the JPMS module java.sql
to the module graph, you need to modify your custom module in the following way, using our mysql.mod
as an example:
mysql.mod.
[description] MySQL module [lib] lib/mysql/mysql-connector-java-*.jar [jpms] add-modules: java.sql
The new [jpms]
section is only used when Jetty is started on the module-path via the --jpms
command line option.
Assuming that mysql-connector-java-*.jar
is a non JPMS modular jar, or an automatic JPMS modular jar, the Jetty start mechanism will add mysql-connector-java-*.jar
to the module-path, and will add the JVM command line option --add-modules java.sql
.
If mysql-connector-java-*.jar
were a proper JPMS modular jar with name (for example) com.mysql.jdbc
, then it would need to be explicitly added to the module graph, in this way:
mysql.mod.
[description] MySQL module [lib] lib/mysql/mysql-connector-java-*.jar [jpms] add-modules: com.mysql.jdbc
The JPMS module java.sql
does not need to be explicitly added because it would be a dependency of the com.mysql.jdbc
module and therefore automatically added to the module graph.
The [jpms]
section has the following format:
[jpms] add-modules: <module name>(,<module name>)* patch-module: <module>=<file>(:<file>)* add-opens: <module>/<package>=<target-module>(,<target-module>)* add-exports: <module>/<package>=<target-module>(,<target-module>)* add-reads: <module>=<target-module>(,<target-module>)*
The section above uses the --jpms
command line option to start Jetty on the module-path.
An alternative way of achieving the same result is to use a Jetty module, $JETTY_BASE/modules/jpms.mod
,
that specifies that you want to run using JPMS (and possibly add some JPMS specific configuration).
jpms.mod.
[ini] --jpms [jpms] # Additional JPMS configuration.
The [ini]
section is equivalent to passing the --jpms
option to the command line.
The [jpms]
section (see also the advanced JPMS configuration section)
allows you specify additional JPMS configuration.
$ mkdir jetty-base-jpms $ cd jetty-base-jpms $ mkdir modules # Copy the jpms.mod file above into the $JETTY_BASE/modules/ directory. $ cp /tmp/jpms.mod modules/ # Add both the http and the jpms modules. $ java -jar $JETTY_HOME/start.jar --add-to-start=http,jpms # Jetty will start on the module-path. $ java -jar $JETTY_HOME/start.jar