Skip to main content

Servlet 3.0 pluggability

Posted by mode on May 13, 2008 at 11:08 PM PDT

In my earlier post I gave an overview of the things that are being worked upon in Servlet 3.0. This post focuses on one of the areas that the expert group has been working on - pluggability.

Pluggability

There are a lot of frameworks / libraries that are built on top of the servlet container. Most frameworks today require you to configure a servlet, filter or listener in the application's web.xml in addition to including it as a dependency in the WEB-INF/lib directory. Today in a servlet container the application has one monolithic web.xml that defines all the deployment artifacts for the application, including the dependencies of the application on the framework components. In it's current state, a developer must go through the documentation of each framework that it depends on and declare the appropriate servlets, filters, Listeners, etc. The goal is to make it possible to use frameworks without having to worry about any additional configuration.

To overcome this issue in servlet 3.0 we are adding a new feature that allows having more than one web.xml, or as it is being referred in the specification as web fragments. A framework can define it's own web.xml that declares the necessary components for the framework that is then included for use in the web applicaton. At deployment the container is responsible for discovering the web.xml fragments and processing them. A new element is being added to the schema for web applications - web-fragment that can define servlets, filters listeners. Below is a simple example of such a fragment.

<web-fragment>
  <servlet>
    <servlet-name>welcome</servlet-name>
    <servlet-class>
      WelcomeServlet
    </servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>welcome</servlet-name>
    <url-pattern>/Welcome</url-pattern>
  </servlet-mapping>
...
</web-fragment>



The above fragment would be included in the META-INF directory of the framework jar file.

In addition to changes to modularize the web.xml there are also annotations being defined to declare servlets (@Servlet), filters (@ServletFilter) and the annotations have all the attributes defined to make web.xml optional. These attributes contain information like url-mapping, init-params and other information that would typically be defined in the deployment descriptor. This way Servlets, filters etc can be defined entirely using annotations and would be picked up from the WEB-INF/classes or WEB-INF/lib directory.

Along with the changes mentioned above there are few new APIs to also allow programmatic addition of Servlets and Filters at start up time of an application. API changes for adding configuration are added to the ServletContext class and are listed here below:

ServletContext: 
    addServlet
    addServletMapping
    addFilter
    addFilterMapping

Below is an example that shows how the APIs defined in ServletContext can be used.

@ServletContextListener
public class MyListener {
    public void contextInitialized (ServletContextEvent sce) {
        ServletContext sc = sce.getServletContext();
        sc.addServlet("myServlet",
                      "Sample servlet",
                      "foo.bar.MyServlet",
                       null, -1);

        sc.addServletMapping("myServlet",
                             new String[] {"/urlpattern/*"});
    }
}
@ServletContextListener
public class MyListener {
    public void contextInitialized (ServletContextEvent sce) {
        ServletContext sc = sce.getServletContext();
        sc.addFilter("myFilter",
                     "Sample Filter",
                     "foo.bar.MyFilter",
                      null);

        sc.addFilterMapping("myFilter",
                             new String[] {"/urlpattern/*"},                        
                            “myServlet”,
                             DispatcherType.REQUEST, false);
    }
}

As you can see with the changes above now the onus is on the framework authors to make sure that they declare and make available the components and be self sufficient. As for the developers / users of the frameworks they now just need to include these libraries in their application and start using it.

Related Topics >>

Comments

siderean: Yes you are right - the expectation is for some reasonable defaults and then the application's web.xml can provide any parameter values to override the defaults. Same for the mapping question that you ask. The application can specify a url mapping for a particular servlet.

arikk: The expectation is that the framework will provide the parameters or at least some reasonable default in the web-fragment.

netsql: You really shouldn't be using a framework that you think may be doing things like randomly opening ports. Using a framework by including a Servlet in your application manually could still be doing that if you really didn't know about it.

arikk, I'm assuming the answer is that web fragments are meant to bootstrap web frameworks with sensible defaults provided by the framework authors. I guess if you need to provide parameters to the framework, that will need to be done in the application web.xml. Rajiv, would configurations in the main web.xml take precedence over configurations in the web-fragments? IE, if the authors of a JSF framework servlet mapping to a url like *.jsf, would I simply put a servlet mapping in my web.xml to override that? Thanks, Don

So... now when I install a jar in lib, it may open up a listening port for remote user to get in?

Often one needs to provide initialization parameters to framework-defined servlets and filters - how would you accomplish that with web fragments?

stephenconnolly: The method signatures require the url-mappings to be specified in them. Sorry if that wasn't clear from the sample. Also like you mention in the specification we will probably end up specifying that an appropriate action like throwing an exception for the case where the url-mapping is not valid or is a duplicate for example.

You loose the ability for validators to check e.g. the filter mapping urls, with the programmatic annotations based examples you give.... but I suppose as long as exceptions are thrown for those cases, that won't matter as much