5.2 Packaging

The SpringSource dm Server supports two OSGi-oriented ways of packaging applications: the PAR format and application modules (including personality-specific modules). The dm Server also supports three distinct WAR deployment and packaging formats: standard Java EE WAR, Shared Libraries WAR, Shared Services WAR.

5.2.1 PARs

An OSGi application is packaged as a JAR file, with extension .par. A PAR artifact offers several benefits:

  • A PAR file has an application name, version, symbolic name, and description.
  • The modules of a PAR file are scoped so that they cannot be shared accidentally by other applications. The scope forms a boundary for automatic propagation of load time weaving and bundle refresh.
  • The modules of a PAR have their exported packages imported by the synthetic context bundle which is used for thread context class loading. So, for example, hibernate will be able to load classes of any of the exported packages of the modules in a PAR file using Class.forName() (or equivalent).
  • The PAR file is visible to management interfaces.
  • The PAR file can be undeployed and redeployed as a unit.

A PAR includes one or more application bundles and its manifest specifies the following manifest headers:

Table 5.1. PAR file headers

HeaderDescription
Application-SymbolicNameIdentifier for the application which, in combination with Application-Version, uniquely identifies an application
Application-NameHuman readable name of the application
Application-VersionVersion of the application
Application-DescriptionShort description of the application


The following code shows an example MANIFEST.MF in a PAR file:

Application-SymbolicName: com.example.shop
Application-Version: 1.0
Application-Name: Online Shop
Application-Description: Example.com's Online Shopping Application
			

5.2.2 Module

A module offers OSGi-oriented packaging that supports specific application personalities. In this release, the only supported application personality is "Web ".

5.2.3 Web Modules

The most common type of application deployed in the SpringSource dm Server is, not surprisingly, the web application. The dm Server, therefore, supports the concept of a Web Module. A Web module is an OSGi bundle whose manifest includes directives to support various options pertinent to a web application.

Web modules have the following advantages over standard Java EE WAR files:

  • Dependencies can be referenced rather than bundled in WEB-INF/lib.

  • Dependencies are accessed via an export signature and so their internals can be controlled.

  • External dependencies can be installed once, thus reducing the overall footprint and deployment overhead of the web module.

  • Web modules have explicit identifying metadata and so can be handled straightforwardly as exploded directories.

  • Web modules are OSGi bundles and so can benefit from dynamic updates, fragment attachment for I18N, etc.

  • Web modules are Spring-DM powered.

Web modules are standard OSGi bundles with the following characteristics:

  • Packaged as an OSGi bundle with a .jar extension, either stand-alone or within a PAR.

  • Required bundle manifest headers: Module-Type: Web.

  • Optional bundle manifest headers (see Web Module Manifest Headers).

  • ApplicationContext:

    • A web module must publish an ApplicationContext configured via standard Spring-DM extender semantics (e.g., /META-INF/spring/*.xml).

    • This application context will actually be an OSGi-aware implementation of ConfigurableWebApplicationContext.

    • In addition, this application context will be used as the WebApplicationContext for a DispatcherServlet which will be automatically configured. Thus, the context configuration files loaded by Spring-DM must contain all web related components (e.g., Spring MVC Controllers, Filters, SWF, Spring Security, etc.).

    • There is no need for a WEB-INF/applicationContext.xml or WEB-INF/<dispatcher servlet name>-servlet.xml, because:

      1. A web module will not have a root WebApplicationContext
      2. A DispatcherServlet will be automatically configured to use the WebApplicationContext created by Spring-DM for the web module

  • Web modules are not required to contain a web.xml deployment descriptor, since an appropriate web.xml will be automatically generated for the web module based on the supplied web module manifest headers. When manifest headers alone do not suffice, however, a web module may be configured via a web.xmlfragment which will be merged with any automatically generated elements. For further details, consult the discussion on web.xml fragments later in this chapter.
  • New OSGi-centric web application directory structure.

    Web Module - Directory Structure

    • MODULE-INF directory: For web modules, any artifacts which would typically reside in the root of a standard WAR are placed in a special directory called MODULE-INF, which resides in the root of the bundle. This directory serves as the root of the ServletContext and thus provides a central location for artifacts which should be publicly accessible via standard HTTP requests (e.g., images, CSS files JavaScript files, etc.). Similar to a standard WAR, MODULE-INF is also the directory in which you should place WEB-INF and related subdirectories (e.g., lib and classes).

    • Public web resources: Web resources which are intended to be publicly visible via HTTP requests should be packaged underneath /MODULE-INF. This is analogous to the root of a standard Java EE WAR and excludes anything packaged underneath /MODULE-INF/WEB-INF.

    • Private web resources: Consistent with standard Java EE WAR deployments, web resources which are not intended to be publicly visible via HTTP requests should be packaged underneath /MODULE-INF/WEB-INF, for example: JSP fragments, templates, configuration files, etc.

    • Classes: For consistency with raw OSGi bundles, Java classes (i.e., .class files) and packages should typically be packaged in the root of the bundle.

      [Note]Note

      For backwards compatibility with the standard WAR format, Java classes may be packaged underneath /MODULE-INF/WEB-INF/classes; however, this is not recommended for web modules, since doing so diverges from OSGi conventions.

    • Class-path resources: Class-path resources such as properties files, XML configuration files, etc. should also be packaged in the root of the bundle.

    • Libraries: Any third-party libraries (i.e., JARs) used by your web application which are not referenced via the dm Server's repository using Import-Package, Import-Library, Import-Bundle, etc. should be packaged in root of the bundle and added to the Bundle-ClassPath accordingly.

      [Note]Note

      For backwards compatibility with the standard WAR format, third-party libraries may be packaged in /MODULE-INF/WEB-INF/lib. Note, however, that the use of /MODULE-INF/WEB-INF/lib in a web module is strongly discouraged.

[Note]Note

For Web Modules, the SpringSource dm Server introspects the contents of the deployed artifact and automatically adds /MODULE-INF/WEB-INF/classes (if present) to the Bundle-ClassPath. Similarly, if there are any JARs present in /MODULE-INF/WEB-INF/lib, each JAR will be added to the Bundle-ClassPath. For WARs, the dm Server performs the same logic for /WEB-INF/classes and any JARs present in /WEB-INF/lib.

5.2.3.1 Web Module Manifest Headers

Web modules support the following manifest headers for configuring the bundle's web application.

Table 5.2. Web module manifest headers

HeaderDescriptionDefault
Web-ContextPath

Used to configure the unique context path under which the web module or WAR is deployed in the Servlet Container.

Syntax: standard Servlet syntax rules for context paths apply.

To deploy a web application as the root context, supply a context path consisting of a single forward slash, /.

The module's file name minus the extension.
Web-FilterMappings

Used to declare a Filter with a given filter-name. The filter-class will be set to DelegatingFilterProxy or a subclass thereof. Thus the supplied name must map to the bean name of the corresponding Filter in the web module's ApplicationContext. For each Filter, you must configure corresponding mappings via the url-patterns directive. Dispatcher mappings may optionally be configured as well.

Syntax: comma-separated list of (note: white space added for legibility): <name>; targetFilterLifecycle:=<target filter lifecycle>; url-patterns:="<patterns>"; dispatcher:="<dispatcher mappings>"

  • <name> is the filter bean name

  • <target filter lifecycle> is a boolean value of true or false, which enables or disables delegation of filter lifecycle events to the underlying Filter bean. The default value is true. Thus, the targetFilterLifecycle directive may optionally be omitted.

  • <patterns> is a comma-separated list of url-pattern values. The syntax of each individual value is as defined in the Servlet specification.

  • <dispatcher> is a comma-separated list of dispatcher mapping values (e.g., REQUEST, FORWARD, INCLUDE, ERROR).

N/A
Web-DispatcherServletUrlPatterns

Used for mapping request URLs to the auto-configured DispatcherServlet for the web module.

Syntax: comma-separated list of url-pattern values. The syntax of each individual value is as defined in the Servlet specification.

*.htm

Let's take a look at the use of these headers in an example:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.springframework.showcase.formtags
Bundle-Version: 2.0.8
Bundle-Name: Spring Form Tags - Sample Web Application
Bundle-Description: Sample web application which demonstrates the use of Spring 2.0's
 custom form tag library
Import-Package: org.springframework.osgi.web.context,
 org.springframework.osgi.web.servlet,
 org.springframework.showcase.formtags.domain;version="2.0.8",
 org.springframework.showcase.formtags.service;version="2.0.8",
 org.springframework.showcase.formtags.validation;version="2.0.8",
 org.springframework.showcase.formtags.web;version="2.0.8"
Import-Library: org.springframework.spring;version="2.5.4"
Module-Type: Web
Web-ContextPath: formtags
Web-DispatcherServletUrlPatterns: *.htm
Web-FilterMappings: securityFilter;url-patterns:="*.htm,*.jsp",
 imageFilter;url-patterns:="/image/*"

5.2.3.2 Web Module web.xml Fragments

In addition to the aforementioned Web-* manifest headers, the SpringSource dm Server also supports configuration of web modules via web.xml fragments. If necessary, a web module may contain an existing /MODULE-INF/WEB-INF/web.xml fragment which will be merged with the automatically generated elements. Such fragments allow developers to configure web.xml in ways that are not supported by web manifest headers alone, thus providing greater flexibility as well as the full feature set of web.xml configuration options.

To use a web.xml fragment, simply configure /MODULE-INF/WEB-INF/web.xml as you normally would for a standard Java EE WAR. Then, if there are elements that you wish to be auto-configured for your web module -- for example, an auto-configured DispatcherServlet or DelegatingFilterProxy element -- configure those via Web-* manifest headers (e.g., Web-DispatcherServletUrlPatterns and Web-FilterMappings, respectively), and the elements in the provided web.xml fragment will then be merged with the auto-configured elements.

The following three listings demonstrate how Web-* manifest headers and a web.xml fragment can be combined to configure a version of the Form Tags show case application's web module. The first listing displays the web module's /META-INF/MANIFEST.MF file.

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: formtags-web
Bundle-Version: 2.0.8
Import-Package: org.springframework.showcase.formtags.domain;version="
 2.0.8",org.springframework.showcase.formtags.service;version="2.0.8",
 org.springframework.showcase.formtags.validation;version="2.0.8",org.
 osgi.framework,org.springframework.osgi.context
Import-Library: org.springframework.spring;version="2.5.4"
Module-Type: Web
Web-ContextPath: formTagsParWithWebModuleAndWebXmlFragment
Web-DispatcherServletUrlPatterns: *.htm

The second listing displays the /MODULE-INF/WEB-INF/web.xml fragment for the web module.

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <display-name>Spring Form Tags - Sample Web Application</display-name>

    <description>
        Sample web application which demonstrates the use of Spring 2.0's
        custom form tag library
    </description>

    <filter>
        <filter-name>imageFilter</filter-name>
        <filter-class>com.example.filter.ImageFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>imageFilter</filter-name>
        <url-pattern>/images/*</url-pattern>
    </filter-mapping>

    <session-config>
        <session-timeout>5</session-timeout>
    </session-config>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.htm</welcome-file>
    </welcome-file-list>

</web-app>

The third listing displays the resulting merged web.xml deployment descriptor with which the web application will be deployed on the dm Server.

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
    xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <servlet>
        <servlet-name>formtags-web-DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
        <init-param>
            <param-name>contextAttribute</param-name>
            <param-value>formtags-web-ApplicationContext</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>formtags-web-DispatcherServlet</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>

    <display-name>Spring Form Tags - Sample Web Application</display-name>

    <description>
        Sample web application which demonstrates the use of Spring 2.0's
        custom form tag library
    </description>

    <filter>
        <filter-name>imageFilter</filter-name>
        <filter-class>com.example.filter.ImageFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>imageFilter</filter-name>
        <url-pattern>/images/*</url-pattern>
    </filter-mapping>

    <session-config>
        <session-timeout>5</session-timeout>
    </session-config>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.htm</welcome-file>
    </welcome-file-list>

</web-app>

As you can see in the above listing, the SpringSource dm Server processes the Web-* manifest headers in the web module's /META-INF/MANIFEST.MF file, auto-generates the necessary web.xml elements -- which are configured to access the web module's Spring-DM powered WebApplicationContext -- and inserts the auto-generated elements into the merged deployment descriptor. The results of the auto-generation process are then merged with the elements supplied in the /MODULE-INF/WEB-INF/web.xml fragment unmodified.

5.2.4 WARs

When packaging WARs for deployment on the SpringSource dm Server, the following should serve as general guidelines.

  • Context Path: As with web modules, the unique context path under which a WAR is deployed in the Servlet Container can be configured via the Web-ContextPath manifest header. If no context path is explicitly configured, the file name of the WAR minus the .war extension will be used by default.

  • Standard Java EE WAR: you can deploy a standard WAR "as is" on the dm Server. There is typically no need to modify it in any way.

  • Shared Libraries WAR: a Shared Libraries WAR has exactly the same structure as a standard WAR. The only difference is that shared libraries, which were previously stored in /WEB-INF/lib or in a centralized location for the Servlet container, are now installed in the dm Server as OSGi bundles and referenced via Import-Package, Import-Bundle, etc.

  • Shared Services WAR: in terms of packaging and the physical structure of the deployment artifact, everything that applies to a Shared Libraries WAR equally applies to a Shared Services WAR. To enable service lookup from a Spring MVC based web application, however, you will need to configure an OSGi-enabled WebApplicationContext in your WAR's /WEB-INF/web.xml deployment descriptor. The SpringSource dm Server provides the ServerOsgiBundleXmlWebApplicationContext class, which is suited exactly for this purpose. The following code listing demonstrates how to configure ServerOsgiBundleXmlWebApplicationContext for your root WebApplicationContext.

    <context-param>
      <param-name>contextClass</param-name>
      <param-value>com.springsource.server.web.dm.ServerOsgiBundleXmlWebApplicationContext</param-value>
    </context-param>
    
    <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    The recommended approach for interacting with the OSGi Service Registry in a Shared Services WAR is to use Spring-DM's <osgi:reference ... /> and related XML namespace elements but to limit such usage to your root WebApplicationContext. It is therefore not typically recommended that you interact with the OSGi Service Registry, for example, from within a WebApplicationContext for a particular DispatcherServlet. If necessary, however, you may also configure a Spring MVC DispatcherServlet to create an OSGi-enabled WebApplicationContext as follows.

    <servlet>
      <servlet-name>dispatcherServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
        <param-name>contextClass</param-name>
        <param-value>com.springsource.server.web.dm.ServerOsgiBundleXmlWebApplicationContext</param-value>
      </init-param>
    </servlet>