Annotations
Enable the ee{8,9,10}-annotations
module if your webapp - or any of its third party libraries - uses any of the following:
-
Annotations:
-
@Resource
-
@Resources
-
@PostConstruct
-
@PreDestroy
-
@DeclaredRoles
-
@RunAs
-
@MultipartConfig
-
@WebServlet
-
@WebFilter
-
@WebListener
-
@WebInitParam
-
@ServletSecurity, @HttpConstraint, @HttpMethodConstraint
-
@HandlesTypes
-
-
javax.servlet.ServletContainerInitializers or jakarta.servlet.ServletContainerInitializers
-
JSP
Annotation Scanning
According to more recent versions of the Jakarta Servlet Specification, the web.xml
file can contain the attribute metadata-complete
.
If this is set to true
, then no annotation scanning takes place, and your descriptor must contain the equivalent xml statements of any annotations.
If it is metadata-complete=false
, or your web.xml
predates the inclusion of this attribute, annotation scanning is required to take place.
To prevent annotation scanning you can use the WebAppContext.setConfigurationDiscovered(false)
method.
Here’s an example context XML file that calls this method:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee10.webapp.WebAppContext"> (1)
<Set name="configurationDiscovered">false</Set> (2)
</Configure>
1 | Configures a WebAppContext , which is the Jetty component that represents a standard Servlet web application. |
2 | Specifies that scanning should not take place. |
However, despite metadata-complete=true
, scanning of classes may still occur because of ServletContainerInitializer
.
Classes implementing this interface are found by Jetty using the javax.util.ServiceLoader mechanism, and if one is present and it includes the @HandlesTypes
annotation, then Jetty must scan the class hierarchy of the web application.
This may be very time-consuming if you have many jars.
Jetty can reduce the time taken by limiting the jars that are scanned.
The container classpath
By default, Jetty will not scan any classes that are on the container’s classpath.
Sometimes, you may have third party libraries on the container’s classpath that you need to be scanned.
In this case, use the org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern
context attribute to define which container jars and class directories to scan.
The value of this attribute is a regular expression.
Here’s an example from a context XML file that includes any jar whose name starts with foo-
or bar-
, or a directory named classes
:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee10.webapp.WebAppContext"> (1)
<Call name="setAttribute"> (2)
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg> (3)
<Arg>.*/foo-[^/]*\.jar$|.*/bar-[^/]*\.jar$|.*/classes/.*</Arg> (4)
</Call>
</Configure>
1 | Configures a WebAppContext , which is the Jetty component that represents a standard Servlet web application. |
2 | Specifies a context attribute. |
3 | Specifies the name of the context attribute. |
4 | Specifies the value of the context attribute. |
Note that the order of the patterns defines the ordering of the scanning of the jars or class directories.
The webapp classpath
By default, Jetty will scan all classes from WEB-INF/classes
and all jars from WEB-INF/lib
according to the order, if any, established by absolute or relative ordering clauses in web.xml
.
If your webapp contains many jar files that you know do not contain any annotations, you can significantly speed up deployment by omitting them from scanning.
However, be careful if your webapp uses a ServletContainerInitializer
with a @HandlesTypes
annotation that you don’t exclude jars that contain classes matching the annotation.
Use the org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern
context attribute to define a regular expression for jars and class directories to select for scanning.
Here’s an example of a context XML file that sets a pattern that matches any jar on the webapp’s classpath that starts with "spring-"
:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee10.webapp.WebAppContext"> (1)
<Call name="setAttribute"> (2)
<Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg> (3)
<Arg>.*/spring-[^/]*\.jar$</Arg> (4)
</Call>
</Configure>
1 | Configures a WebAppContext , which is the Jetty component that represents a standard Servlet web application. |
2 | Specifies a context attribute. |
3 | Specifies the name of the context attribute. |
4 | Specifies the value of the context attribute. |
Multi-threading
By default, Jetty performs annotation scanning in a multi-threaded manner in order to complete it in the minimum amount of time.
If you don’t want multi-threaded scanning, you can configure Jetty to revert to single-threaded scanning. There are several options to configure this:
-
Set the context attribute
org.eclipse.jetty.annotations.multiThreaded
tofalse
-
Set the
Server
attributeorg.eclipse.jetty.annotations.multiThreaded
tofalse
-
Set the
System
propertyorg.eclipse.jetty.annotations.multiThreaded
tofalse
Method 1 will only affect the current webapp. Method 2 will affect all webapps deployed to the same Server instance. Method 3 will affect all webapps deployed in the same JVM.
By default, Jetty will wait a maximum of 60 seconds for all of the scanning threads to complete. You can set this to a higher or lower number of seconds by doing one of the following:
-
Set the context attribute
org.eclipse.jetty.annotations.maxWait
-
Set the
Server
attributeorg.eclipse.jetty.annotations.maxWait
-
Set the
System
propertyorg.eclipse.jetty.annotations.maxWait
Method 1 will only affect the current webapp. Method 2 will affect all webapps deployed to the same Server instance. Method 3 will affect all webapps deployed in the same JVM.
ServletContainerInitializers
The ServletContainerInitializer
class can exist in: the container’s classpath, the webapp’s WEB-INF/classes
directory, the webapp’s WEB-INF/lib
jars, or any external extraClasspath that you have configured on the webapp.
The Jakarta Servlet Specification does not define any order in which a ServletContainerInitializer
must be called when the webapp starts.
By default, Jetty will call them in the following order:
-
ServletContainerInitializers from the container’s classpath
-
ServletContainerInitializers from
WEB-INF/classes
-
ServletContainerInitializers from
WEB-INF/lib
jars in the order established in web.xml, or in the order that the SCI is returned by the javax.util.ServiceLoader if there is no ordering.
Exclusions
By default, as according to the Jakarta Servlet Specification, all ServletContainerInitializer
instances that are discovered are invoked.
Sometimes, depending on your requirements, you may need to prevent some being called at all.
In this case, you can define the org.eclipse.jetty.containerInitializerExclusionPattern
context attribute.
This is a regular expression that defines patterns of classnames that you want to exclude. Here’s an example of setting the context attribute in a context XML file:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee10.webapp.WebAppContext"> (1)
<Call name="setAttribute"> (2)
<Arg>org.eclipse.jetty.containerInitializerExclusionPattern</Arg> (3)
<Arg>com.acme.*|com.corp.SlowContainerInitializer</Arg> (4)
</Call>
</Configure>
1 | Configures a WebAppContext , which is the Jetty component that represents a standard Servlet web application. |
2 | Specifies a context attribute. |
3 | Specifies the name of the context attribute. |
4 | Specifies the value of the context attribute. |
In this example we exclude all ServletContainerInitializer
instances in the com.acme package
, and the specific class com.corp.SlowContainerInitializer
.
It is possible to use exclusion and ordering together to control ServletContainerInitializer
invocation - the exclusions will be applied before the ordering.
Ordering
If you need ServletContainerInitializer
classes called in a specific order, you can use the context attribute org.eclipse.jetty.containerInitializerOrder
.
Set it to a list of comma separated ServletContainerInitializer
class names in the order that you want them applied.
You may optionally use the wildcard character *
once in the list.
It will match all ServletContainerInitializer
classes not explicitly named in the list.
Here is an example context XML file that ensures the com.example.PrioritySCI
will be called first, followed by the com.acme.FooSCI
, then all other SCIs:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://jetty.org/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.ee10.webapp.WebAppContext"> (1)
<Call name="setAttribute"> (2)
<Arg>org.eclipse.jetty.containerInitializerOrder</Arg> (3)
<Arg>org.eclipse.jetty.websocket.javax.server.JavaxWebSocketServletContainerInitializer, com.acme.FooSCI, *</Arg> (4)
</Call>
</Configure>
1 | Configures a WebAppContext , which is the Jetty component that represents a standard Servlet web application. |
2 | Specifies a context attribute. |
3 | Specifies the name of the context attribute. |
4 | Specifies the value of the context attribute. |