参考路径:http://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html#get-up-and-running
Configuring the Jetty Maven Plugin
-
Quick Start: Get Up and Running
Supported Goals
Configuring the Jetty Container
Configuring Your WebApp
jetty:run
jetty:run-war
jetty:run-exploded
jetty:deploy-war
jetty:run-forked
jetty:start
jetty:stop
jetty:effective-web-xml
Using Overlaid wars
Configuring Security Settings
Using Multiple Webapp Root Directories
Running More than One Webapp
Setting System Properties
The Jetty Maven plugin is useful for rapid development and testing. You can add it to any webapp project that is structured according to the usual Maven defaults. The plugin can then periodically scan your project for changes and automatically redeploy the webapp if any are found. This makes the development cycle more productive by eliminating the build and deploy steps: you use your IDE to make changes to the project, and the running web container automatically picks them up, allowing you to test them straight away.
Important
You need to use Maven 3 and Java 1.8 for this plugin.
First, add jetty-maven-plugin
to your pom.xml
definition:
1
2
3
4
5
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
</
plugin
>
|
Then, from the same directory as your root pom.xml
, type:
mvn jetty:run
This starts Jetty and serves up your project on http://localhost:8080/.
Jetty continues to run until you stop it. While it runs, it periodically scans for changes to your project files, so if you save changes and recompile your class files, Jetty redeploys your webapp, and you can instantly test the changes you just made.
You can terminate the plugin with a ctrl-c
in the terminal window where it is running.
Note
The classpath of the running Jetty and its deployed webapp are managed by Maven, and may not be exactly what you expect. For example: webapp's dependant jars might be referenced via the local repository, not the WEB-INF/lib
directory.
The Jetty Maven plugin has a number of distinct Maven goals. Arguably the most useful is the run
goal that we saw in the Quick Start section which runs Jetty on your unassembled webapp. There are other goals which help you accomplish different tasks. For example, you might need to run your webapp in a forked instance of Jetty, rather than within the process running Maven; or you may need finer grained control over the maven lifecycle stage in which you wish to deploy your webapp. There are different goals to accomplish these tasks, as well as several others.
To see a list of all goals supported by the Jetty Maven plugin, do:
mvn jetty:help
To see the detailed list of parameters that can be configured for a particular goal, in addition to its description, do:
mvn jetty:help -Ddetail=true -Dgoal= goal-name
These configuration elements set up the Jetty environment in which your webapp executes. They are common to most goals:
-
httpConnector
-
Optional. If not specified, Jetty will create a ServerConnector instance listening on port 8080. You can change this default port number by using the system property
jetty.http.port
on the command line, for example,mvn -Djetty.http.port=9999 jetty:run
. Alternatively, you can use this configuration element to set up the information for the ServerConnector. The following are the valid configuration sub-elements:-
port
-
The port number for the connector to listen on. By default it is 8080.
host
-
The particular interface for the connector to listen on. By default, all interfaces.
name
-
The name of the connector, which is useful for configuring contexts to respond only on particular connectors.
idleTimeout
-
Maximum idle time for a connection.
soLinger
-
The socket linger time.
You could instead configure the connectors in a standard jetty xml config file and put its location into the
jettyXml
parameter. Note that since jetty-9.0 it is no longer possible to configure a https connector directly in the pom.xml: you need to use jetty xml config files to do it.
jettyXml
-
-
Optional. A comma separated list of locations of
jetty xml
files to apply in addition to any plugin configuration parameters. You might use it if you have other webapps, handlers, specific types of connectors etc., to deploy, or if you have other Jetty objects that you cannot configure from the plugin.
scanIntervalSeconds
-
The pause in seconds between sweeps of the webapp to check for changes and automatically hot redeploy if any are detected. By default this is 0, which disables hot deployment scanning. A number greater than 0 enables it.
reload
-
Default value is "automatic", used in conjunction with a non-zero
scanIntervalSeconds
causes automatic hot redeploy when changes are detected. Set to "manual" instead to trigger scanning by typing a linefeed in the console running the plugin. This might be useful when you are doing a series of changes that you want to ignore until you're done. In that use, use thereload
parameter.
dumpOnStart
-
Optional. Default value is false. If true, then jetty will dump out the server structure on start.
loginServices
-
Optional. A list of
org.eclipse.jetty.security.LoginService
implementations. Note that there is no default realm. If you use a realm in yourweb.xml
you can specify a corresponding realm here. You could instead configure the login services in a jetty xml file and add its location to thejettyXml
parameter.
requestLog
-
Optional. An implementation of the
org.eclipse.jetty.server.RequestLog
request log interface. An implementation that respects the NCSA format is available asorg.eclipse.jetty.server.NCSARequestLog
. There are three other ways to configure the RequestLog:-
In a jetty xml config file, as specified in the
jettyXml
parameter. -
In a context xml config file, as specified in the
contextXml
parameter. -
In the
webApp
element.
See Configuring Request Logs for more information.
server
-
-
Optional since jetty-9.3.1. This would configure an instance of the
org.eclipse.jetty.server.Server
for the plugin to use, however it is usually NOT necessary to configure this, as the plugin will automatically configure one for you. In particular, if you use the jettyXml element, then you generally DON'T want to define this element, as you are probably using the jettyXml file to configure up a Server with a special constructor argument, such as a custom threadpool. If you define both a server element AND use a jettyXml element which points to a config file that has a line like "<Configure id="Server" class="org.eclipse.jetty.server.Server">" then the the xml configuration will override what you configure for the server in the pom.
stopPort
-
Optional. Port to listen on for stop commands. Useful to use in conjunction with the stop or run-forked goals.
stopKey
-
Optional. Used in conjunction with stopPort for stopping jetty. Useful when used in conjunction with the stop or run-forked goals.
systemProperties
-
Optional.Allows you to configure System properties for the execution of the plugin. For more information, see Setting System Properties.
systemPropertiesFile
-
Optional. A file containing System properties to set for the execution of the plugin. By default, settings that you make here do notoverride any system properties already set on the command line, by the JVM, or in the POM via
systemProperties
. Read Setting System Properties for how to force overrides.
skip
-
Default is false. If true, the execution of the plugin exits. Same as setting the SystemProperty
-Djetty.skip
on the command line. This is most useful when configuring Jetty for execution during integration testing and you want to skip the tests
useProvidedScope
-
Default value is
false
. If true, the dependencies with<scope>provided</scope>
are placed onto the container classpath. Be aware that this is NOT the webapp classpath, as "provided" indicates that these dependencies would normally be expected to be provided by the container. You should very rarely ever need to use this. Instead, you should copy the provided dependencies as explicit dependencies of theplugin
instead.
excludedGoals
-
Optional. A list of jetty plugin goal names that will cause the plugin to print an informative message and exit. Useful if you want to prevent users from executing goals that you know cannot work with your project.
In order to configure a https connector, you need to use jetty xml configuration files. This example uses files copied directly from the jetty distribution etc/ directory, although you can of course make up your own xml file or files. We will use the following files:
-
jetty.xml
-
Sets up various characteristics of the
org.eclipse.jetty.server.Server
instance for the plugin to use. Importantly, it sets up theorg.eclipse.jetty.server.HttpConfiguration
element that we can refer to in subsequent xml files that configure the connectors. Here's the relevant section:12345678910111213141516<
New
id
=
"httpConfig"
class
=
"org.eclipse.jetty.server.HttpConfiguration"
>
<
Set
name
=
"secureScheme"
>https</
Set
>
<
Set
name
=
"securePort"
><
Property
name
=
"jetty.secure.port"
default
=
"8443"
/></
Set
>
<
Set
name
=
"outputBufferSize"
>32768</
Set
>
<
Set
name
=
"requestHeaderSize"
>8192</
Set
>
<
Set
name
=
"responseHeaderSize"
>8192</
Set
>
<
Set
name
=
"sendServerVersion"
>true</
Set
>
<
Set
name
=
"sendDateHeader"
>false</
Set
>
<
Set
name
=
"headerCacheSize"
>512</
Set
>
<!-- Uncomment to enable handling of X-Forwarded- style headers
<Call name="addCustomizer">
<Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
</Call>
-->
</
New
>
jetty-ssl.xml
-
Set up ssl which will be used by the https connector. Here's the
jetty-ssl.xml
file from the jetty-distribution:12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758<?
xml
version
=
"1.0"
?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= -->
<!-- Base SSL configuration -->
<!-- This configuration needs to be used together with 1 or more -->
<!-- of jetty-https.xml or jetty-http2.xml -->
<!-- ============================================================= -->
<
Configure
id
=
"Server"
class
=
"org.eclipse.jetty.server.Server"
>
<!-- =========================================================== -->
<!-- Add a SSL Connector with no protocol factories -->
<!-- =========================================================== -->
<
Call
name
=
"addConnector"
>
<
Arg
>
<
New
id
=
"sslConnector"
class
=
"org.eclipse.jetty.server.ServerConnector"
>
<
Arg
name
=
"server"
><
Ref
refid
=
"Server"
/></
Arg
>
<
Arg
name
=
"acceptors"
type
=
"int"
><
Property
name
=
"jetty.ssl.acceptors"
deprecated
=
"ssl.acceptors"
default
=
"-1"
/></
Arg
>
<
Arg
name
=
"selectors"
type
=
"int"
><
Property
name
=
"jetty.ssl.selectors"
deprecated
=
"ssl.selectors"
default
=
"-1"
/></
Arg
>
<
Arg
name
=
"factories"
>
<
Array
type
=
"org.eclipse.jetty.server.ConnectionFactory"
>
<!-- uncomment to support proxy protocol
<Item>
<New class="org.eclipse.jetty.server.ProxyConnectionFactory"/>
</Item>-->
</
Array
>
</
Arg
>
<
Set
name
=
"host"
><
Property
name
=
"jetty.ssl.host"
deprecated
=
"jetty.host"
/></
Set
>
<
Set
name
=
"port"
><
Property
name
=
"jetty.ssl.port"
deprecated
=
"ssl.port"
default
=
"8443"
/></
Set
>
<
Set
name
=
"idleTimeout"
><
Property
name
=
"jetty.ssl.idleTimeout"
deprecated
=
"ssl.timeout"
default
=
"30000"
/></
Set
>
<
Set
name
=
"soLingerTime"
><
Property
name
=
"jetty.ssl.soLingerTime"
deprecated
=
"ssl.soLingerTime"
default
=
"-1"
/></
Set
>
<
Set
name
=
"acceptorPriorityDelta"
><
Property
name
=
"jetty.ssl.acceptorPriorityDelta"
deprecated
=
"ssl.acceptorPriorityDelta"
default
=
"0"
/></
Set
>
<
Set
name
=
"acceptQueueSize"
><
Property
name
=
"jetty.ssl.acceptQueueSize"
deprecated
=
"ssl.acceptQueueSize"
default
=
"0"
/></
Set
>
</
New
>
</
Arg
>
</
Call
>
<!-- =========================================================== -->
<!-- Create a TLS specific HttpConfiguration based on the -->
<!-- common HttpConfiguration defined in jetty.xml -->
<!-- Add a SecureRequestCustomizer to extract certificate and -->
<!-- session information -->
<!-- =========================================================== -->
<
New
id
=
"sslHttpConfig"
class
=
"org.eclipse.jetty.server.HttpConfiguration"
>
<
Arg
><
Ref
refid
=
"httpConfig"
/></
Arg
>
<
Call
name
=
"addCustomizer"
>
<
Arg
>
<
New
class
=
"org.eclipse.jetty.server.SecureRequestCustomizer"
>
<
Arg
name
=
"sniHostCheck"
type
=
"boolean"
><
Property
name
=
"jetty.ssl.sniHostCheck"
default
=
"true"
/></
Arg
>
<
Arg
name
=
"stsMaxAgeSeconds"
type
=
"int"
><
Property
name
=
"jetty.ssl.stsMaxAgeSeconds"
default
=
"-1"
/></
Arg
>
<
Arg
name
=
"stsIncludeSubdomains"
type
=
"boolean"
><
Property
name
=
"jetty.ssl.stsIncludeSubdomains"
default
=
"false"
/></
Arg
>
</
New
>
</
Arg
>
</
Call
>
</
New
>
</
Configure
>
jetty-https.xml
-
Set up the https connector using the HttpConfiguration from
jetty.xml
and the ssl configuration fromjetty-ssl.xml
:1234567891011121314151617181920212223242526272829<?
xml
version
=
"1.0"
?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= -->
<!-- Configure a HTTPS connector. -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- and jetty-ssl.xml. -->
<!-- ============================================================= -->
<
Configure
id
=
"sslConnector"
class
=
"org.eclipse.jetty.server.ServerConnector"
>
<
Call
name
=
"addIfAbsentConnectionFactory"
>
<
Arg
>
<
New
class
=
"org.eclipse.jetty.server.SslConnectionFactory"
>
<
Arg
name
=
"next"
>http/1.1</
Arg
>
<
Arg
name
=
"sslContextFactory"
><
Ref
refid
=
"sslContextFactory"
/></
Arg
>
</
New
>
</
Arg
>
</
Call
>
<
Call
name
=
"addConnectionFactory"
>
<
Arg
>
<
New
class
=
"org.eclipse.jetty.server.HttpConnectionFactory"
>
<
Arg
name
=
"config"
><
Ref
refid
=
"sslHttpConfig"
/></
Arg
>
<
Arg
name
=
"compliance"
><
Call
class
=
"org.eclipse.jetty.http.HttpCompliance"
name
=
"valueOf"
><
Arg
><
Property
name
=
"jetty.http.compliance"
default
=
"RFC7230"
/></
Arg
></
Call
></
Arg
>
</
New
>
</
Arg
>
</
Call
>
</
Configure
>
Now you need to let the plugin know to apply the files above:
1
2
3
4
5
6
7
8
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
jettyXml
>jetty.xml,jetty-ssl.xml,jetty-https.xml</
jettyXml
>
</
configuration
>
</
plugin
>
|
Caution
Just like with an installed distribution of Jetty, the ordering of the xml files is significant.
You can also use jetty xml files to configure a http connector for the plugin to use. Here we use the same jetty-http.xml
file from the Jetty distribution:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
<?
xml
version
=
"1.0"
?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<!-- ============================================================= -->
<!-- Configure the Jetty Server instance with an ID "Server" -->
<!-- by adding a HTTP connector. -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- ============================================================= -->
<
Configure
id
=
"Server"
class
=
"org.eclipse.jetty.server.Server"
>
<!-- =========================================================== -->
<!-- Add a HTTP Connector. -->
<!-- Configure an o.e.j.server.ServerConnector with a single -->
<!-- HttpConnectionFactory instance using the common httpConfig -->
<!-- instance defined in jetty.xml -->
<!-- -->
<!-- Consult the javadoc of o.e.j.server.ServerConnector and -->
<!-- o.e.j.server.HttpConnectionFactory for all configuration -->
<!-- that may be set here. -->
<!-- =========================================================== -->
<
Call
name
=
"addConnector"
>
<
Arg
>
<
New
id
=
"httpConnector"
class
=
"org.eclipse.jetty.server.ServerConnector"
>
<
Arg
name
=
"server"
><
Ref
refid
=
"Server"
/></
Arg
>
<
Arg
name
=
"acceptors"
type
=
"int"
><
Property
name
=
"jetty.http.acceptors"
deprecated
=
"http.acceptors"
default
=
"-1"
/></
Arg
>
<
Arg
name
=
"selectors"
type
=
"int"
><
Property
name
=
"jetty.http.selectors"
deprecated
=
"http.selectors"
default
=
"-1"
/></
Arg
>
<
Arg
name
=
"factories"
>
<
Array
type
=
"org.eclipse.jetty.server.ConnectionFactory"
>
<
Item
>
<
New
class
=
"org.eclipse.jetty.server.HttpConnectionFactory"
>
<
Arg
name
=
"config"
><
Ref
refid
=
"httpConfig"
/></
Arg
>
<
Arg
name
=
"compliance"
><
Call
class
=
"org.eclipse.jetty.http.HttpCompliance"
name
=
"valueOf"
><
Arg
><
Property
name
=
"jetty.http.compliance"
default
=
"RFC7230"
/></
Arg
></
Call
></
Arg
>
</
New
>
</
Item
>
</
Array
>
</
Arg
>
<
Set
name
=
"host"
><
Property
name
=
"jetty.http.host"
deprecated
=
"jetty.host"
/></
Set
>
<
Set
name
=
"port"
><
Property
name
=
"jetty.http.port"
deprecated
=
"jetty.port"
default
=
"8080"
/></
Set
>
<
Set
name
=
"idleTimeout"
><
Property
name
=
"jetty.http.idleTimeout"
deprecated
=
"http.timeout"
default
=
"30000"
/></
Set
>
<
Set
name
=
"soLingerTime"
><
Property
name
=
"jetty.http.soLingerTime"
deprecated
=
"http.soLingerTime"
default
=
"-1"
/></
Set
>
<
Set
name
=
"acceptorPriorityDelta"
><
Property
name
=
"jetty.http.acceptorPriorityDelta"
deprecated
=
"http.acceptorPriorityDelta"
default
=
"0"
/></
Set
>
<
Set
name
=
"acceptQueueSize"
><
Property
name
=
"jetty.http.acceptQueueSize"
deprecated
=
"http.acceptQueueSize"
default
=
"0"
/></
Set
>
</
New
>
</
Arg
>
</
Call
>
</
Configure
>
|
Now we add it to the list of configs for the plugin to apply:
1
2
3
4
5
6
7
8
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
jettyXml
>jetty.xml,jetty-http.xml,jetty-ssl.xml,jetty-https.xml</
jettyXml
>
</
configuration
>
</
plugin
>
|
Alternatively, you can use the httpConnector configuration element inside the pom instead as described above.
These configuration parameters apply to your webapp. They are common to almost all goals.
-
webApp
-
This is an instance of org.eclipse.jetty.maven.plugin.JettyWebAppContext, which is an extension to the class
org.eclipse.jetty.webapp.WebAppContext
. You can use any of the setter methods on this object to configure your webapp. Here are a few of the most useful ones:-
contextPath
-
The context path for your webapp. By default, this is set to
/
. If using a custom value for this parameter, you probably want to include the leading/
, example/mycontext
.
descriptor
-
The path to the
web.xml
file for your webapp.
defaultsDescriptor
-
The path to a
webdefault.xml
file that will be applied to your webapp before theweb.xml
. If you don't supply one, Jetty uses a default file baked into thejetty-webapp.jar
.
overrideDescriptor
-
The path to a
web.xml
file that Jetty applies after reading yourweb.xml
. You can use this to replace or add configuration.
tempDirectory
-
The path to a dir that Jetty can use to expand or copy jars and jsp compiles when your webapp is running. The default is
${project.build.outputDirectory}/tmp
.
baseResource
-
The path from which Jetty serves static resources. Defaults to
src/main/webapp
.
resourceBases
-
Use instead of
baseResource
if you have multiple dirs from which you want to serve static content. This is an array of dir names.
baseAppFirst
-
Defaults to "true". Controls whether any overlaid wars are added before or after the original base resource(s) of the webapp. See the section on overlaid wars for more information.
containerIncludeJarPattern
-
Defaults to ".*/javax.servlet-[^/]*\.jar$|.*/servlet-api-[^/]*\.jar$|.*javax.servlet.jsp.jstl-[^/]*\.jar|.*taglibs-standard-impl-.*\.jar". This is a pattern that is applied to the names of the jars on the container's classpath (ie the classpath of the plugin, not that of the webapp) that should be scanned for fragments, tlds, annotations etc. This is analogous to the context attribute org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern that is documented here. You can define extra patterns of jars that will be included in the scan.
webInfIncludeJarPattern
-
Defaults to matching all of the dependency jars for the webapp (ie the equivalent of WEB-INF/lib). You can make this pattern more restrictive to only match certain jars by using this setter. This is analogous to the context attributeorg.eclipse.jetty.server.webapp.WebInfIncludeJarPattern that is documented here.
contextXml
-
-
The path to a context xml file that is applied to your webapp AFTER the
webApp
element.
The run
goal runs on a webapp that does not have to be built into a WAR. Instead, Jetty deploys the webapp from its sources. It looks for the constituent parts of a webapp in the Maven default project locations, although you can override these in the plugin configuration. For example, by default it looks for:
-
resources in
${project.basedir}/src/main/webapp
-
classes in
${project.build.outputDirectory}
-
web.xml
in${project.basedir}/src/main/webapp/WEB-INF/
The plugin automatically ensures the classes are rebuilt and up-to-date before deployment. If you change the source of a class and your IDE automatically compiles it in the background, the plugin picks up the changed class.
You do not need to assemble the webapp into a WAR, saving time during the development cycle. Once invoked, you can configure the plugin to run continuously, scanning for changes in the project and automatically performing a hot redeploy when necessary. Any changes you make are immediately reflected in the running instance of Jetty, letting you quickly jump from coding to testing, rather than going through the cycle of: code, compile, reassemble, redeploy, test.
Here is a small example, which turns on scanning for changes every ten seconds, and sets the webapp context path to /test
:
1
2
3
4
5
6
7
8
9
10
11
12
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
scanIntervalSeconds
>10</
scanIntervalSeconds
>
<
webApp
>
<
contextPath
>/test</
contextPath
>
</
webApp
>
</
configuration
>
</
plugin
>
|
In addition to the webApp
element that is common to most goals, the jetty:run
goal supports:
-
classesDirectory
-
Location of your compiled classes for the webapp. You should rarely need to set this parameter. Instead, you should set
build outputDirectory
in yourpom.xml
.
testClassesDirectory
-
Location of the compiled test classes for your webapp. By default this is
${project.build.testOutputDirectory}
.
useTestScope
-
If true, the classes from
testClassesDirectory
and dependencies of scope "test" are placed first on the classpath. By default this is false.
webAppSourceDirectory
-
By default, this is set to
${project.basedir}/src/main/webapp
. If your static sources are in a different location, set this parameter accordingly.
jettyEnvXml
-
Optional. Location of a
jetty-env.xml
file, which allows you to make JNDI bindings that satisfyenv-entry
,resource-env-ref
, andresource-ref
linkages in theweb.xml
that are scoped only to the webapp and not shared with other webapps that you might be deploying at the same time (for example, by using ajettyConfig
file).
scanTargets
-
Optional. A list of files and directories to periodically scan in addition to those the plugin automatically scans.
scanTargetPatterns
-
Optional. If you have a long list of extra files you want scanned, it is more convenient to use pattern matching expressions to specify them instead of enumerating them with the
scanTargetsList
ofscanTargetPatterns
, each consisting of a directory, and including and/or excluding parameters to specify the file matching patterns.
scanClassesPattern
-
Since 9.3.0. Optional. Include and exclude patterns that can be applied to the classesDirectory for the purposes of scanning, it does not affect the classpath. If a file or directory is excluded by the patterns then a change in that file (or subtree in the case of a directory) is ignored and will not cause the webapp to redeploy. Patterns are specified as a relative path using a glob-like syntax as described in the javadoc for FileSystem.getPathMatcher.
scanTestClassesPattern
-
Since 9.3.0. Optional. Include and exclude patterns that can be applied to the testClassesDirectory for the purposes of scanning, it does not affect the classpath. If a file or directory is excluded by the patterns then a change in that file (or subtree in the case of a directory) is ignored and will not cause the webapp to redeploy. Patterns are specified as a relative path using a glob-like syntax as described in the javadoc for FileSystem.getPathMatcher.
Here's an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
<
project
>
...
<
plugins
>
...
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
webAppSourceDirectory
>${project.basedir}/src/staticfiles</
webAppSourceDirectory
>
<
webApp
>
<
contextPath
>/</
contextPath
>
<
descriptor
>${project.basedir}/src/over/here/web.xml</
descriptor
>
<
jettyEnvXml
>${project.basedir}/src/over/here/jetty-env.xml</
jettyEnvXml
>
</
webApp
>
<
classesDirectory
>${project.basedir}/somewhere/else</
classesDirectory
>
<
scanClassesPattern
>
<
excludes
>
<
exclude
>**/Foo.class</
exclude
>
</
excludes
>
</
scanClassesPattern
>
<
scanTargets
>
<
scanTarget
>src/mydir</
scanTarget
>
<
scanTarget
>src/myfile.txt</
scanTarget
>
</
scanTargets
>
<
scanTargetPatterns
>
<
scanTargetPattern
>
<
directory
>src/other-resources</
directory
>
<
includes
>
<
include
>**/*.xml</
include
>
<
include
>**/*.properties</
include
>
</
includes
>
<
excludes
>
<
exclude
>**/myspecial.xml</
exclude
>
<
exclude
>**/myspecial.properties</
exclude
>
</
excludes
>
</
scanTargetPattern
>
</
scanTargetPatterns
>
</
configuration
>
</
plugin
>
</
plugins
>
</
project
>
|
If, for whatever reason, you cannot run on an unassembled webapp, the goals run-war
and run-exploded
work on unassembled webapps.
This goal first packages your webapp as a WAR file and then deploys it to Jetty. If you set a non-zero scanInterval
, Jetty watches your pom.xml
and the WAR file; if either changes, it redeploys the war.
-
war
-
The location of the built WAR file. This defaults to
${project.build.directory}/${project.build.finalName}.war
. If this is not sufficient, set it to your custom location.
Here's how to set it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<
project
>
...
<
plugins
>
...
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
war
>${project.basedir}/target/mycustom.war</
war
>
</
configuration
>
</
plugin
>
</
plugins
>
</
project
>
|
The run-exploded goal first assembles your webapp into an exploded WAR file and then deploys it to Jetty. If you set a non-zero scanInterval
, Jetty watches your pom.xml, WEB-INF/lib, WEB-INF/
classes and WEB-INF/web.xml
for changes and redeploys when necessary.
-
war
-
The location of the exploded WAR. This defaults to
${project.build.directory}/${project.build.finalName}
, but you can override the default by setting this parameter.
Here's how to set it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<
project
>
...
<
plugins
>
...
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>maven-jetty-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
war
>${project.basedir}/target/myfunkywebapp</
war
>
</
configuration
>
</
plugin
>
</
plugins
>
</
project
>
|
This is basically the same as jetty:run-war
, but without assembling the WAR of the current module - you can nominate the location of any war to run. Unlike run-war
, the phase in which this plugin executes is not bound to the "package" phase - you may bind it to any phase to use it.
-
war
-
The location of the WAR file. This defaults to
${project.build.directory}/${project.build.finalName}
, but you can override the default by setting this parameter.
daemon
-
If true, this plugin will start jetty but let the build continue. This is useful if you want to start jetty as an execution binding in a particular phase and then stop it in another. Alternatively, you can set this parameter to false, in which case jetty will block and you will need to use a cntrl-c to stop it.
Here's the configuration:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<
project
>
...
<
plugins
>
...
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
war
>/opt/special/some-app.war</
war
>
<
stopKey
>alpha</
stopKey
>
<
stopPort
>9099</
stopPort
>
</
configuration
>
<
executions
>
<
execution
>
<
id
>start-jetty</
id
>
<
phase
>test-compile</
phase
>
<
goals
>
<
goal
>deploy-war</
goal
>
</
goals
>
</
execution
>
<
execution
>
<
id
>stop-jetty</
id
>
<
phase
>test</
phase
>
<
goals
>
<
goal
>stop</
goal
>
</
goals
>
</
execution
>
</
executions
>
</
plugin
>
</
plugins
>
</
project
>
|
This goal allows you to start the webapp in a new JVM, optionally passing arguments to that new JVM. This goal supports the same configuration parameters as the jetty:run
goal with a couple of extras to help configure the forked process.
The available configuration parameters - in addition to those for the jetty:run
goal - are:
-
jvmArgs
-
Optional. A string representing arbitrary arguments to pass to the forked JVM.
waitForChild
-
Default is
true
. This causes the parent process to wait for the forked process to exit. In this case you can usecntrl-c
to terminate both processes. It is more useful to set it tofalse
, in which case the parent process terminates whilst leaving the child process running. You use thejetty:stop
goal to stop the child process.
maxStartupLines
-
Default is
50
. This is maximum number of lines the parent process reads from the child process to receive an indication that the child has started. If the child process produces an excessive amount of output on stdout you may need to increase this number.
Some of the container configuration parameters are NOT available with this goal:
-
scanIntervalSeconds
-
Not supported. The forked jetty will not monitor and redeploy the webapp.
reload
-
Not supported. The forked jetty will not redeploy the webapp.
httpConnector
-
Not supported. To define custom connectors use a jetty xml file instead.
loginServices
-
Not supported. To define LoginServices use a jetty xml or context xml file instead.
requestLog
-
Not supported. To define a RequestLog setup, use a jetty xml or context xml file instead.
systemProperties
-
Not supported. Use the
jvmArgs
parameter to pass system properties to the forked process.
To deploy your unassembled web app to Jetty running in a new JVM:
mvn jetty:run-forked
Jetty continues to execute until you either:
-
Press
cntrl-c
in the terminal window to stop the plugin, which also stops the forked JVM (only if you started withwaitForChild=true
) -
Use jetty:stop to stop the forked JVM, which also stops the plugin.
Note
If you want to set a custom port for the jetty connector you need to specify it in a jetty xml
file rather than setting the connector and port tags. You can specify the location of the jetty.xml
using the jettyXml
parameter.
This goal is for use with an execution binding in your pom.xml
. It is similar to the jetty:run
goal, however it does NOT first execute the build up until the "test-compile" phase to ensure that all necessary classes and files of the webapp have been generated. This is most useful when you want to control the start and stop of Jetty via execution bindings in your pom.xml
.
For example, you can configure the plugin to start your webapp at the beginning of your unit tests and stop at the end. To do this, you need to set up a couple of execution
scenarios for the Jetty plugin. You use the pre-integration-test
and post-integration-test
Maven build phases to trigger the execution and termination of Jetty:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
scanIntervalSeconds
>10</
scanIntervalSeconds
>
<
stopKey
>foo</
stopKey
>
<
stopPort
>9999</
stopPort
>
</
configuration
>
<
executions
>
<
execution
>
<
id
>start-jetty</
id
>
<
phase
>pre-integration-test</
phase
>
<
goals
>
<
goal
>start</
goal
>
</
goals
>
<
configuration
>
<
scanIntervalSeconds
>0</
scanIntervalSeconds
>
</
configuration
>
</
execution
>
<
execution
>
<
id
>stop-jetty</
id
>
<
phase
>post-integration-test</
phase
>
<
goals
>
<
goal
>stop</
goal
>
</
goals
>
</
execution
>
</
executions
>
</
plugin
>
|
The stop goal stops a running instance of jetty. To use it, you need to configure the plugin with a special port number and key. That same port number and key will also be used by the other goals that start jetty.
-
stopPort
-
A port number for jetty to listen on to receive a stop command to cause it to shutdown.
stopKey
-
A string value sent to the
stopPort
to validate the stop command.
stopWait
-
The maximum time in seconds that the plugin will wait for confirmation that jetty has stopped. If false or not specified, the plugin does not wait for confirmation but exits after issuing the stop command.
Here's a configuration example:
1
2
3
4
5
6
7
8
9
10
11
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
stopPort
>9966</
stopPort
>
<
stopKey
>foo</
stopKey
>
<
stopWait
>10</
stopWait
>
</
configuration
>
</
plugin
>
|
Then, while Jetty is running (in another window), type:
mvn jetty:stop
The stopPort
must be free on the machine you are running on. If this is not the case, you get an "Address already in use" error message after the "Started SelectedChannelConnector ..." message.
This goal calculates a synthetic web.xml (the "effective web.xml") according to the rules of the Servlet Specification taking into account all sources of discoverable configuration of web components in your application: descriptors (webdefault.xml, web.xml, web-fragment.xmls, web-override.xml) and discovered annotations (@WebServlet, @WebFilter, @WebListener). The effective web.xml from these combined sources is generated and displayed as maven log output. Other useful information about your webapp that is produced as part of the analysis is also stored as context parameters in the effective-web.xml. The effective-web.xml can be used in conjunction with the Quickstart feature to quickly start your webapp (note that Quickstart is not appropriate for the mvn jetty goals).
The following configuration parameters allow you to save the file:
-
deleteOnExit
-
By default this is
true
. If set tofalse
, the effective web.xml is generated into a file calledeffective-web.xml
in the buildtarget
directory.
effectiveWebXml
-
The full path name of a file into which you would like the effective web xml generated.
Note that no programmatic declarations of servlets, filters and listeners will be taken into account.
If your webapp depends on other war files, thejetty:run and jetty:run-forked goals are able to merge resources from all of them. It can do so based on the settings of the maven-war-plugin, or if your project does not use the maven-war-plugin to handle the overlays, it can fall back to a simple algorithm to determine the ordering of resources.
The maven-war-plugin has a rich set of capabilities for merging resources. The jetty:run and jetty:run-forked goals are able to interpret most of them and apply them during execution of your unassembled webapp. This is probably best seen by looking at a concrete example.
Suppose your webapp depends on the following wars:
1
2
3
4
5
6
7
8
9
10
11
|
<
dependency
>
<
groupId
>com.acme</
groupId
>
<
artifactId
>X</
artifactId
>
<
type
>war</
type
>
</
dependency
>
<
dependency
>
<
groupId
>com.acme</
groupId
>
<
artifactId
>Y</
artifactId
>
<
type
>war</
type
>
</
dependency
>
|
Containing:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
WebAppX:
/foo.jsp
/bar.jsp
/WEB-INF/web.xml
WebAppY:
/bar.jsp
/baz.jsp
/WEB-INF/web.xml
/WEB-INF/special.xml
|
They are configured for the maven-war-plugin:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<
plugin
>
<
groupId
>org.apache.maven.plugins</
groupId
>
<
artifactId
>maven-war-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
overlays
>
<
overlay
>
<
groupId
>com.acme</
groupId
>
<
artifactId
>X</
artifactId
>
<
excludes
>
<
exclude
>bar.jsp</
exclude
>
</
excludes
>
</
overlay
>
<
overlay
>
<
groupId
>com.acme</
groupId
>
<
artifactId
>Y</
artifactId
>
<
excludes
>
<
exclude
>baz.jsp</
exclude
>
</
excludes
>
</
overlay
>
<
overlay
>
</
overlay
>
</
overlays
>
</
configuration
>
</
plugin
>
|
Then executing jetty:run would yield the following ordering of resources: com.acme.X.war : com.acme.Y.war: ${project.basedir}/src/main/webapp
. Note that the current project's resources are placed last in the ordering due to the empty <overlay/> element in the maven-war-plugin. You can either use that, or specify the <baseAppFirst>false</baseAppFirst>
parameter to the jetty-maven-plugin.
Moreover, due to the exclusions
specified above, a request for the resource bar.jsp
would only be satisfied from com.acme.Y.war.
Similarly asbaz.jsp
is excluded, a request for it would result in a 404 error.
The algorithm is fairly simple, is based on the ordering of declaration of the dependent wars, and does not support exclusions. The configuration parameter <baseAppFirst>
(see the section on Configuring Your Webapp for more information) can be used to control whether your webapp's resources are placed first or last on the resource path at runtime.
For example, suppose our webapp depends on these two wars:
1
2
3
4
5
6
7
8
9
10
|
<
dependency
>
<
groupId
>com.acme</
groupId
>
<
artifactId
>X</
artifactId
>
<
type
>war</
type
>
</
dependency
>
<
dependency
>
<
groupId
>com.acme</
groupId
>
<
artifactId
>Y</
artifactId
>
<
type
>war</
type
>
</
dependency
>
|
Suppose the webapps contain:
1
2
3
4
5
6
7
8
9
10
11
12
|
WebAppX:
/foo.jsp
/bar.jsp
/WEB-INF/web.xml
WebAppY:
/bar.jsp
/baz.jsp
/WEB-INF/web.xml
/WEB-INF/special.xml
|
Then our webapp has available these additional resources:
1
2
3
4
5
|
/foo.jsp (X)
/bar.jsp (X)
/baz.jsp (Y)
/WEB-INF/web.xml (X)
/WEB-INF/special.xml (Y)
|
You can configure LoginServices in the plugin. Here's an example of setting up the HashLoginService for a webapp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
scanIntervalSeconds
>10</
scanIntervalSeconds
>
<
webApp
>
<
contextPath
>/test</
contextPath
>
</
webApp
>
<
loginServices
>
<
loginService
implementation
=
"org.eclipse.jetty.security.HashLoginService"
>
<
name
>Test Realm</
name
>
<
config
>${project.basedir}/src/etc/realm.properties</
config
>
</
loginService
>
</
loginServices
>
</
configuration
>
</
plugin
>
|
If you have external resources that you want to incorporate in the execution of a webapp, but which are not assembled into WARs, you can't use the overlaid wars method described above, but you can tell Jetty the directories in which these external resources are located. At runtime, when Jetty receives a request for a resource, it searches all the locations to retrieve the resource. It's a lot like the overlaid war situation, but without the war. Here's a configuration example:
1
2
3
4
5
6
7
8
|
<
configuration
>
<
webApp
>
<
contextPath
>/${build.finalName}</
contextPath
>
<
baseResource
implementation
=
"org.eclipse.jetty.util.resource.ResourceCollection"
>
<
resourcesAsCSV
>src/main/webapp,/home/johndoe/path/to/my/other/source,/yet/another/folder</
resourcesAsCSV
>
</
baseResource
>
</
webApp
>
</
configuration
>
|
You can use either a jetty.xml
file to configure extra (pre-compiled) webapps that you want to deploy, or you can use the <contextHandlers>
configuration element to do so. If you want to deploy webapp A, and webapps B and C in the same Jetty instance:
Putting the configuration in webapp A's pom.xml
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
scanIntervalSeconds
>10</
scanIntervalSeconds
>
<
webApp
>
<
contextPath
>/test</
contextPath
>
</
webApp
>
<
contextHandlers
>
<
contextHandler
implementation
=
"org.eclipse.jetty.maven.plugin.JettyWebAppContext"
>
<
war
>${project.basedir}../../B.war</
war
>
<
contextPath
>/B</
contextPath
>
</
contextHandler
>
<
contextHandler
implementation
=
"org.eclipse.jetty.maven.plugin.JettyWebAppContext"
>
<
war
>${project.basedir}../../C.war</
war
>
<
contextPath
>/C</
contextPath
>
</
contextHandler
>
</
contextHandlers
>
</
configuration
>
</
plugin
>
|
Important
If the ContextHandler you are deploying is a webapp, it is essential that you use anorg.eclipse.jetty.maven.plugin.JettyWebAppContext
instance rather than a standard org.eclipse.jetty.webapp.WebAppContext
instance. Only the former will allow the webapp to function correctly in the maven environment.
Alternatively, add a jetty.xml
file to webapp A. Copy the jetty.xml
file from the jetty distribution, and then add WebAppContexts for the other 2 webapps:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<
Ref
refid
=
"Contexts"
>
<
Call
name
=
"addHandler"
>
<
Arg
>
<
New
class
=
"org.eclipse.jetty.maven.plugin.JettyWebAppContext"
>
<
Set
name
=
"contextPath"
>/B</
Set
>
<
Set
name
=
"war"
>../../B.war</
Set
>
</
New
>
</
Arg
>
</
Call
>
<
Call
>
<
Arg
>
<
New
class
=
"org.eclipse.jetty.maven.plugin.JettyWebAppContext"
>
<
Set
name
=
"contextPath"
>/C</
Set
>
<
Set
name
=
"war"
>../../C.war</
Set
>
</
New
>
</
Arg
>
</
Call
>
</
Ref
>
|
Then configure the location of this jetty.xml
file into webapp A's jetty plugin:
1
2
3
4
5
6
7
8
9
10
11
12
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
version
>9.3.7.v20160115</
version
>
<
configuration
>
<
scanIntervalSeconds
>10</
scanIntervalSeconds
>
<
webApp
>
<
contextPath
>/test</
contextPath
>
</
webApp
>
<
jettyXml
>src/main/etc/jetty.xml</
jettyXml
>
</
configuration
>
</
plugin
>
|
For either of these solutions, the other webapps must already have been built, and they are not automatically monitored for changes. You can refer either to the packed WAR file of the pre-built webapps or to their expanded equivalents.
You can specify property name/value pairs that Jetty sets as System properties for the execution of the plugin. This feature is useful to tidy up the command line and save a lot of typing.
However, sometimes it is not possible to use this feature to set System properties - sometimes the software component using the System property is already initialized by the time that maven runs (in which case you will need to provide the System property on the command line), or by the time that jetty runs. In the latter case, you can use the maven properties plugin to define the system properties instead. Here's an example that configures the logback logging system as the jetty logger:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<
plugin
>
<
groupId
>org.codehaus.mojo</
groupId
>
<
artifactId
>properties-maven-plugin</
artifactId
>
<
version
>1.0-alpha-2</
version
>
<
executions
>
<
execution
>
<
goals
>
<
goal
>set-system-properties</
goal
>
</
goals
>
<
configuration
>
<
properties
>
<
property
>
<
name
>logback.configurationFile</
name
>
<
value
>${project.baseUri}/resources/logback.xml</
value
>
</
property
>
</
properties
>
</
configuration
>
</
execution
>
</
executions
>
</
plugin
>
|
Note that if a System property is already set (for example, from the command line or by the JVM itself), then by default these configured properties DO NOT override them (see below for use of the <force> parameter).
Here's an example of how to specify System properties in the POM:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
configuration
>
<
systemProperties
>
<
systemProperty
>
<
name
>fooprop</
name
>
<
value
>222</
value
>
</
systemProperty
>
</
systemProperties
>
<
webApp
>
<
contextPath
>/test</
contextPath
>
</
webApp
>
</
configuration
>
</
plugin
>
|
To change the default behaviour so that these system properties override those on the command line, use the <force>
parameter:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
configuration
>
<
systemProperties
>
<
force
>true</
force
>
<
systemProperty
>
<
name
>fooprop</
name
>
<
value
>222</
value
>
</
systemProperty
>
</
systemProperties
>
<
webApp
>
<
contextPath
>/test</
contextPath
>
</
webApp
>
</
configuration
>
</
plugin
>
|
You can also specify your System properties in a file. System properties you specify in this way DO NOT override System properties that set on the command line, by the JVM, or directly in the POM via systemProperties
.
Suppose we have a file called mysys.props
which contains the following:
1
|
fooprop=222
|
This can be configured on the plugin like so:
1
2
3
4
5
6
7
8
9
10
|
<
plugin
>
<
groupId
>org.eclipse.jetty</
groupId
>
<
artifactId
>jetty-maven-plugin</
artifactId
>
<
configuration
>
<
systemPropertiesFile
>${project.basedir}/mysys.props</
systemPropertiesFile
>
<
webApp
>
<
contextPath
>/test</
contextPath
>
</
webApp
>
</
configuration
>
</
plugin
>
|
You can instead specify the file by setting the System property (!) jetty.systemPropertiesFile
on the command line.