![]() Version: 9.3.9.v20160517 |
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
Web applications require a certain amount of processing before they can go into service: they may need to be unpacked, a special classloader created for their jars, web.xml and web-fragment.xml descriptors processed, and classes scanned for annotations amongst many other things. As web applications have become more complex, we have added ways to help you customize by either broadening or lessening the amount of processing that is done at deployment time. In this section we will look at this processing, and how you can tailor it.
If instead you’re looking for information on how to configure a specific WebAppContext - such as its context path, whether it should be unpacked or not - then you can find that in the section entitled Configuring a Specific WebApp Deployment.
As a webapp is being deployed, a series of org.eclipse.jetty.webapp.Configuration classes are applied to it, each one performing a specific function. The ordering of these Configurations is significant as subsequent Configurations tend to build on information extracted or setup in foregoing Configurations. These are the default list, in order, of Configurations that are applied to each org.eclipse.jetty.webapp.WebAppContext:
Table 4.1. Default Configuration classes
Extracts war, orders jars and defines classpath | |
Processes a WEB-INF/web.xml file | |
Looks in container and webapp jars for META-INF/resources and META-INF/web-fragment.xml | |
Processes all discovered META-INF/web-fragment.xml files | |
Processes a WEB-INF/jetty-web.xml file |
A Configuration class is called 5 times in different phases of the WebAppContext’s lifecycle:
Each phase is called on each Configuration class in the order in which the Configuration class is listed. So for example, using our default Configuration classes as an example, preConfigure() will be called on WebInfConfiguration, WebXmlConfiguration, MetaInfConfiguration, FragmentConfiguration and then JettyWebXmlConfiguration. The cycle begins again for the configure() phase and again for the postConfigure() phases. The cycle is repeated in reverse order for the deconfigure() and eventually the destroy() phases.
As we have seen, there is a default set of Configurations that support basic deployment of a webapp. You will notice that we have not mentioned JavaEE features such as JNDI, nor advanced servlet spec features such as annotations. That is because Jetty’s philosophy is to allow the user to tailor the container exactly to his needs. If you do not need these kind of features, then you do not pay the price of them - an important consideration because features such as annotations require extensive and time-consuming scanning of WEB-INF/lib jars. As modern webapps may have scores of these jars, it can be a source of significant deployment delay. We will see in the section Other Configuration another helpful webapp facility that Jetty provides for cutting down the time spent analysing jars.
Jetty makes use of the flexibility of Configurations to make JNDI and annotation support pluggable.
Firstly, lets look at how Configurations help enable JNDI.
JNDI lookups within web applications require the container to hookup resources defined in the container’s environment to that of the web application. To acheive that, we use 2 extra Configurations:
Table 4.2. JNDI Configuration classes
Creates java:comp/env for the webapp, applies a WEB-INF/jetty-env.xml file | |
Processes JNDI related aspects of WEB-INF/web.xml and hooks up naming entries |
These configurations must be added in exactly the order shown above and should be inserted immediately before the org.eclipse.jetty.webapp.JettyWebXmlConfiguration class in the list of configurations. To fully support JNDI, you need to do a couple of other things, full details of which you can find here.
We need just one extra Configuration class to help provide servlet annotation scanning:
Table 4.3. Annotation Configuration classes
Scan container and web app jars looking for @WebServlet, @WebFilter, @WebListener etc |
The above configuration class must be inserted immediately before the org.eclipse.jetty.webapp.JettyWebXmlConfiguration class in the list of configurations. To fully support annotations, you need to do a couple of other things, details of which can be found here.
You have a number of options for how to make Jetty use a different list of Configurations.
If you have only one webapp that you wish to affect, this may be the easiest option. You will, however, either need to have a context xml file that represents your web app, or you need to call the equivalent in code. Let’s see an example of how we would add in the Configurations for both JNDI and annotations:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/my-cool-webapp</Set>
<Set name="configurationClasses">
<Array type="java.lang.String">
<Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
<Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
<Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
<Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
<Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
<Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item>
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
</Array>
</Set>
</Configure>Of course, you can also use this method to reduce the Configurations applied to a specific WebAppContext.
If you use the deployer, you can set up the list of Configuration classes on the WebAppProvider. They will then be applied to each WebAppContext deployed by the deployer:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="addBean">
<Arg>
<New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
<Set name="contexts">
<Ref refid="Contexts" />
</Set>
<Call id="webappprovider" name="addAppProvider">
<Arg>
<New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
<Set name="monitoredDirName"><Property name="jetty.home" default="." />/webapps</Set>
<Set name="configurationClasses">
<Array type="java.lang.String">
<Item>org.eclipse.jetty.webapp.WebInfConfiguration</Item>
<Item>org.eclipse.jetty.webapp.WebXmlConfiguration</Item>
<Item>org.eclipse.jetty.webapp.MetaInfConfiguration</Item>
<Item>org.eclipse.jetty.webapp.FragmentConfiguration</Item>
<Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
<Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
<Item>org.eclipse.jetty.annotations.AnnotationConfiguration</Item>
<Item>org.eclipse.jetty.webapp.JettyWebXmlConfiguration</Item>
</Array>
</Set>
</New>
</Arg>
</Call>
</New>
</Arg>
</Call>
</Configure>Instead of having to enumerate the list in its entirety, you can simply nominate classes that you want to add, and indicate whereabouts in the list you want them inserted. Let’s look at an example of using this method to add in Configuration support for JNDI - as usual you can either do this in an xml file, or via equivalent code. This example uses an xml file, in fact it is the $JETTY_HOME/etc/jetty-plus.xml file from the Jetty distribution:
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Add plus Configuring classes to all webapps for this Server -->
<!-- =========================================================== -->
<Call class="org.eclipse.jetty.webapp.Configuration$ClassList" name="setServerDefault">
<Arg><Ref refid="Server" /></Arg>
<Call name="addAfter">
<Arg name="afterClass">org.eclipse.jetty.webapp.FragmentConfiguration</Arg>
<Arg>
<Array type="String">
<Item>org.eclipse.jetty.plus.webapp.EnvConfiguration</Item>
<Item>org.eclipse.jetty.plus.webapp.PlusConfiguration</Item>
</Array>
</Arg>
</Call>
</Call>
</Configure>The org.eclipse.jetty.webapp.Configuration.ClassList class provides these methods for insertion:
This is a context attribute that can be set onan org.eclipse.jetty.webapp.WebAppContext to control which parts of the container’s classpath should be processed for things like annotations, META-INF/resources, META-INF/web-fragment.xml and tlds inside META-INF.
Normally, nothing from the container classpath will be included for processing. However, sometimes you will need to include some. For example, you may have some libraries that are shared amongst your webapps and thus you have put them into a $JETTY_HOME/lib directory. The libraries contain annotations and therefore must be scanned.
The value of this attribute is a regexp that defines whichjars and class directories from the container’s classpath should be examined.
Here’s an example from a context xml file (although as always, you could have accomplished the same in code), which would match any jar whose name starts with "foo-" or "bar-", or a directory named "classes":
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Call name="setAttribute">
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
<Arg>.*/foo-[^/]*\.jar$|.*/bar-[^/]*\.jar$|.*/classes/.*</Arg>
</Call>
</Configure>Note that the order of the patterns defines the ordering of the scanning of the jars or class directories.
Similarly to the previous context attribute, this attribute controls which jars are processed for things like annotations, META-INF/resources, META-INF/web-fragment.xml and tlds in META-INF. However, this attribute controls which jars from the webapp’s classpath (usually WEB-INF/lib) are processed. This can be particularly useful when you have dozens of jars in WEB-INF/lib, but you know that only a few need to be scanned.
Here’s an example (in an xml file, but you can do the same in code) of a pattern that matches any jar that starts with "spring-":
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Call name="setAttribute">
<Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg>
<Arg>.*/spring-[^/]*\.jar$</Arg>
</Call>
</Configure>Note that the order of the patterns defines the ordering of the scanning of the jars.