In recent years, the typical WAR deployment has become bloated with third-party add-ons such as web frameworks, component libraries, content management tools, rendering toolkits, and more. These add-ons are standard services that typically require boilerplate declarations in the web.xml along with certain jar files that are put into WEB-INF/lib.
Adding these jars and web.xml declarations is a time consuming and error-prone process. It makes the WAR monolithic and difficult to maintain. Plus, it makes the WAR so large that it is difficult to send to support personnel or others for inspection.
Additionally, the typical WAR deployment is often coupled with services it might not need, such as JSP, JSF, and JSTL. For instance, you may not know it, but by default, JBoss 5 adds a JSP servlet instance to every WAR deployment. It also adds filters, context params, and context listeners that it may never use.
The classpath of a WAR deployed on JBoss 5 also includes jar files for access to JSP, JSTL, and JSF classes that it may or may not use. Besides having a bloated classpath, this sometimes causes problems when you want to use a different version of these classes than the ones that ship with the container.
The proposed solution is to create a WAR Add-On Deployer that adds only the services that the WAR requires. A WAR should be able to easily specify which services it needs without physically adding jars and without adding boilerplate declarations in web.xml. The WAR Add-On Deployer will be capable of adding and configuring these services at deploy time.
The WAR Add-On Deployer has three purposes:
- Automatically add web.xml configuration for each add-on
- Automatically download dependencies for each add-on
- Automatically add jars to the WAR classpath for each add-on
All jars in the classpath will be scanned for a /META-INF/war-addon-web.xml file. This file must use the web-app 2.5 schema found in a normal web.xml file. Any declaration for servlets, filters, listeners, security-constraint, etc. will be added to the deployment at deploy time. If a declaration already exists in /WEB-INF/web.xml then the one in the main web.xml will take precedence. That way, the application can override the default boilerplate declarations provided by the third party add-on.
It should also be noted that the automatic web.xml configuration allows you to package your WAR the old-fashioned way by simply placing the jars into WEB-INF/lib. The advantage is that the presence of the jar will add boilerplate web.xml declarations if they don't already exist.
Declaring A WAR Add-On
As mentioned in the previous section, you can still use an add-on the old fashioned way by placing its jar (or jars) in WEB-INF/lib. However, this can make the WAR become bloated and can make dependency management difficult because you have to make sure you package all the right dependencies for the add-on.
The WAR Add-On Deployer allows you to declare an add-on in the WAR without adding any jars. The WAR Add-On Deployer will read the file /META-INF/war-addon-jboss-beans.xml. In this file, you will specify add-ons using Maven groupId, artifactId, and version. If the add-on does not exist in the local Maven repository it will be downloaded automatically.
The add-on's jars and dependencies will be added to the WAR deployment at deploy time. The jars will physically remain in the local Maven repository. This way, you will never need more than one copy of the jar on your local machine.
The /META-INF/war-addon-jboss-beans.xml file will also allow dependency exclusions so that you can leave off dependencies if needed.
The WAR Add-On Deployer accepts a list of standard add-ons that are conditionally added to all WAR deployments. For instance, it would tell the WAR Add-On Deployer to add a standard version of JSF to all WAR deployments that declare the FacesServlet. It might also tell the WAR Add-On Deployer to add a standard version of JSP to all WAR deployments that contain JSP files.