Issue #2191 - JPMS Support.

JPMS documentation.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2018-09-28 13:23:43 +02:00
parent 02eccd55ae
commit 5cac3376c6
2 changed files with 191 additions and 0 deletions

View File

@ -28,3 +28,4 @@ include::custom-modules.adoc[]
include::startup-xml-config.adoc[]
include::startup-unix-service.adoc[]
include::startup-windows-service.adoc[]
include::startup-jpms.adoc[]

View File

@ -0,0 +1,190 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ========================================================================
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
[[startup-overview]]
=== Startup using the Java Platform Module System (JPMS)
Jetty modules are also automatic https://en.wikipedia.org/wiki/Java_Platform_Module_System[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 to use JDK 11 or greater due to the fact that JDK 11 removed all the
"enterprise" modules from the JDK.
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.
Some of these "enterprise" classes are required by Jetty or by applications running
in Jetty, so it is better to use a stable source for those classes by using JDK 11
or greater.
==== Starting Jetty on the module-path
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:
[source, screen, subs="{sub-order}"]
....
$ 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 link:#startup-base-and-home[Jetty base directory] and
enables the `http` module using `--add-to-start`.
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:
[source, screen, subs="{sub-order}"]
....
$ java -jar $JETTY_HOME/start.jar --jpms --dry-run
....
You will see something like this (broken in sections for clarity):
[source, screen, subs="{sub-order}"]
....
/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 `--add-to-start`.
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; jars 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).
==== Advanced JPMS Configuration
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` (for example `com.zaxxer.hikari.HikariDataSource`) or a
reference directly to the JDBC driver's `DataSource` (for example
`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 `javax.sql.DataSource`.
When Jetty runs on the class-path, this is easily achieved by using a
link:#custom-modules[custom module]:
[source, screen, subs="{sub-order}"]
.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
`mysql.mod` in the following way:
[source, screen, subs="{sub-order}"]
.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:
[source, screen, subs="{sub-order}"]
.mysql.mod
....
[description]
MySQL module
[lib]
lib/mysql/mysql-connector-java-*.jar
[jpms]
add-modules: com.mysql.jdbc
....
Now we don't need to add JPMS module `java.sql` explicitly 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:
[source, screen, subs="{sub-order}"]
....
[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>)*
....