Jetty Logo
Version: 9.2.2-SNAPSHOT
Contact the core Jetty developers at www.webtide.com

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 from 1 day to full product delivery

Working with Annotations

Which Annotations Are Supported
Discovered vs Introspected Annotations
Which Jars Are Scanned For Discovered Annotations
Multi-threaded Annotation Scanning
ServletContainerInitializers

Which Annotations Are Supported

Jetty supports interpretation and application of the following annotations:

  • @Resource

  • @Resources

  • @PostConstruct

  • @PreDestroy

  • @DeclaredRoles

  • @RunAs

  • @MultipartConfig

  • @WebServlet

  • @WebFilter

  • @WebListener

  • @WebInitParam

  • @ServletSecurity, @HttpConstraint, @HttpMethodConstraint

  • @HandlesTypes (on ServletContainerInitializers)

Discovered vs Introspected Annotations

Some types of annotation can be placed on any classes, not necessarily just those with which the container interacts directly. We call these type of annotations "discovered" to indicate that the container must take proactive action to go out and find them. The other type of annotation we call "introspected", meaning that they occur on classes with which the container interacts during their lifecycle (eg javax.servlet.Servlet, javax.servlet.Filter etc), and hence can be found by simple inspection of the class at that point.

Some examples of discovered annotations are:

  • @WebServlet

  • @WebFilter

  • @WebListener

Some examples of introspected annotations are:

  • @PostConstruct

  • @PreDestroy

  • @Resource

Which Jars Are Scanned For Discovered Annotations

The web.xml file can contain the attribute metadata-complete. If this is set to true, then no scanning of discoverable annotations takes place. However, scanning of classes may still occur because of javax.servlet.ServletContainerInitializers. 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 in the container's path or in the webapp's WEB-INF/lib.

If scanning is to take place - because either metadata-complete is false or missing, or because there are one or more javax.servlet.ServletContainerIntializers with @HandlesTypes - then Jetty must consider both the container's classpath and the webapp's classpath.

By default, Jetty will not scan any classes that are on the container's classpath. If you need to cause jars and classes that are on the container's classpath to be scanned, then you can use the org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern context attribute to specify a pattern for jars and directories from the container's classpath to scan.

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 jars, you can significantly speed up deployment by omitting them from scanning. To do this, use the org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern context attribute to define the patterns of jars that you specifically want to be scanned.

Note that if you have configured an extraClasspath for the webapp, then it participates in the scanning process too. Any classes dirs are treated the same for scanning purposes as if they were in WEB-INF/classes and jars are treated as if they were in WEB-INF/lib.

See also the next section on ServletContainerInitializers if you need to control the order in which they are applied.

Multi-threaded Annotation Scanning

Since jetty-9.1.0.RC1, if annotation scanning is to be performed, by default Jetty will do it in a multi-threaded manner in order to complete it in the minimum amount of time.

If for some reason you don't want to do it multi-threaded, you can configure Jetty to revert to single-threaded scanning. You have several ways to configure this:

  1. set the context attribute org.eclipse.jetty.annotations.multiThreaded to false

  2. set the Server attribute org.eclipse.jetty.annotations.multiThreaded to false

  3. set the System property org.eclipse.jetty.annotations.multiThreaded to false

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:

  1. set the context attribute org.eclipse.jetty.annotations.maxWait

  2. set the Server attribute org.eclipse.jetty.annotations.maxWait

  3. set the System property org.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

javax.servlet.ServletContainerInitializers 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 Servlet Specification does not define any order in which these ServletContainerInitializers must be called when the webapp starts. Since jetty-9.1.0.RC1, by default Jetty will call them in the following order:

  1. ServletContainerInitializers from the container's classpath

  2. ServletContainerInitializers from WEB-INF/classes

  3. 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

As is the case with annotation scanning, the extraClasspath is fully considered for ServletContainerInitializer callbacks. ServletContainerInitializers derived from a classes dir on the extraClasspath and jars from an extraClasspath for the webapp are called in step 2 and 3 respectively.

Controlling the order of ServletContainerInitializer invocation

If you need ServletContainerInitializers called in a specific order that is different from that outlined above, then you can use the context attribute org.eclipse.jetty.containerInitializerOrder. Set it to a list of comma separated class names of ServletContainerInitializers in the order that you want them applied. You may optionally use the wildcard character "*" once in the list. It will match all ServletContainerInitializers not explicitly named in the list. Here's an example, setting the context attribute in code (although you can also do the same in xml):

In this example, we ensure that the WebSocketServerContainerInitializer is the very first ServletContainerInitializer that is called, followed by MySCI and then any other ServletContainerInitializers that were discovered but not yet called.

Excluding ServletContainerInitializers

By default, as according to the Servlet Specification, all ServletContainerInitializers that are discovered are invoked (see above for how to control the invocation order). Sometimes, 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, setting the context attribute in code, although you may do exactly the same in xml:

In this example we exclude all ServletContainerInitializers in the com.acme package, and the SlowContainerInitializer.

It is possible to use exclusion and ordering together to control ServletContainerInitializer invocation - the exclusions will be applied before the ordering.

See an error or something missing? Contribute to this documentation at Github!(Generated: 2014-09-22T01:00:25-07:00)