SpringSource dm Server™ Programmer Guide

Ramnivas Laddad

Colin Yates

Sam Brannen

Rob Harrop

Christian Dupuis

Andy Wilkinson

SpringSource dm Server™

1.0.1.RELEASE

Copyright © SpringSource Inc., 2008


Table of Contents

1. Preface
2. Prerequisites
2.1. Runtime Environment
2.2. References
3. Introduction to the SpringSource dm Server
3.1. Overview
3.2. What is the SpringSource dm Server?
3.2.1. What makes up the SpringSource dm Server?
3.3. Why the SpringSource dm Server?
3.3.1. Deployment options and migration paths
3.3.2. Simplified development and deployment of OSGi-based applications
3.3.3. Enhanced diagnostics during deployment and in production
4. Deployment Architecture
4.1. Supported Deployment Formats
4.1.1. Raw OSGi Bundles
4.1.2. WAR Deployment Formats
4.1.2.1. Standard WAR
4.1.2.2. Shared Libraries WAR
4.1.2.3. Shared Services WAR
4.1.3. Web Modules
4.1.4. PAR
4.2. Dependency Types
4.3. A guide to forming bundles
5. Developing Applications
5.1. Anatomy of a bundle
5.2. Packaging
5.2.1. PARs
5.2.2. Module
5.2.3. Web Modules
5.2.3.1. Web Module Manifest Headers
5.2.3.2. Web Module web.xml Fragments
5.2.4. WARs
5.3. Programmatic Access to Personality-specific Features
5.3.1. Programmatic Access to Web Personality Features
5.3.1.1. Programmatic Access to the WebApplicationContext
5.3.1.2. Programmatic Access to the BundleContext
5.4. Automatic Imports
5.4.1. Automatic Imports for the Web Personality
5.5. Working with dependencies
5.5.1. Importing libraries
5.5.2. Importing bundles
5.5.3. Defining libraries
5.5.4. Installing dependencies
5.6. Application trace
5.6.1. Using vanilla Log4J
5.7. Application versioning
6. Migrating to OSGi
6.1. Migrating Web Applications
6.1.1. Standard WAR
6.1.2. Shared Libraries WAR
6.1.3. Shared Services WAR
6.1.4. Web Module
6.1.5. Web Migration Summary
6.2. PAR
7. Case study: Migrating the Form Tags sample application.
7.1. Overview of the Form Tags Sample Application
7.2. Form Tags WAR
7.3. Form Tags Shared Libraries WAR
7.4. Form Tags Shared Services WAR
7.4.1. The Service Bundle
7.4.2. Accessing the Service and Types from the WAR
7.5. Form Tags PAR
7.5.1. Granularity of the PAR
7.5.2. Domain and Service Bundles
7.5.3. Form Tags Web Module
7.5.4. Constructing the PAR
7.6. Summary of the Form Tags Migration
8. Tooling
8.1. Installation
8.2. Running a SpringSource dm Server instance within Eclipse
8.3. Bundle and Library Provisioning
8.4. Setting up Eclipse Projects
8.4.1. Creating New Projects
8.4.2. Migrating existing Java Projects
8.5. Developing OSGi Bundles
8.5.1. Resolving Bundle Dependencies
8.5.2. Editing the Manifest
8.6. Deploying Applications
9. Working with Common Enterprise Libraries
9.1. Working with Hibernate
9.1.1. Importing Hibernate
9.2. Working with DataSources
9.3. Weaving and Instrumentation
9.4. JSP Tag Libraries
10. Known Issues
10.1. JPA Entity Scanning

1. Preface

Increasing complexity in modern enterprise applications is a fact of life. You not only have to deal with complex business logic, but also a myriad of other concerns such as security, auditing, exposing business functionality to external applications, and managing the evolution of that functionality and technologies. The Spring Framework and Spring Portfolio products address these needs by offering a Plain-Old Java Object (POJO) based solution that lets you focus on your business logic.

Complex applications pose problems that go beyond using the right set of technologies. You need to take into account other considerations such as a simplified development process, easy deployment, monitoring deployed applications, and managing changes in response to changing business needs. This is where the SpringSource Application Platform comes into play. It offers a simple yet comprehensive platform to develop, deploy, and service enterprise applications. In this Programmer Guide, we explore the runtime portion of the SpringSource Application Platform, the SpringSource dm Server, and learn how to develop applications to benefit from its capabilities.

2. Prerequisites

2.1 Runtime Environment

The SpringSource dm Server requires Java SE 5 or later to be installed. Java is available from Sun and elsewhere.

2.2 References

To make effective use of the SpringSource dm Server, you should also refer to the following guides:

3. Introduction to the SpringSource dm Server

3.1 Overview

In this chapter, we provide an overview of the SpringSource dm Server focusing on what it is, what benefits it provides to developers and administrators, and why you should use it.

3.2 What is the SpringSource dm Server?

The SpringSource dm Server, or dm Server for short, is the runtime portion of the SpringSource Application Platform. It is a lightweight, modular, OSGi-based runtime that provides a complete packaged solution for developing, deploying, and managing enterprise applications. By leveraging several best-of-breed technologies and improving upon them, the dm Server offers a compelling solution to develop and deploy enterprise applications.

3.2.1 What makes up the SpringSource dm Server?

The SpringSource dm Server is built on top of the following core technologies:

Note, however, that the SpringSource dm Server isn't just a combination of these technologies. Rather, it integrates and extends these technologies to provide many features essential for developing, deploying, and managing today's enterprise Java applications.

The following diagram presents a high-level overview of the dm Server's architecture.

At the heart of the SpringSource dm Server is the SpringSource Dynamic Module Kernel (DMK). The DMK is an OSGi-based kernel that takes full advantage of the modularity and versioning of the OSGi platform. The DMK builds on Equinox and extends its capabilities for provisioning and library management, as well as providing core functionality for the dm Server.

To maintain a minimal runtime footprint, OSGi bundles are installed on demand by the DMK provisioning subsystem. This allows for an application to be installed into a running dm Server and for its dependencies to be satisfied from an external repository. Not only does this remove the need to manually install all your application dependencies, which would be tedious, but it also keeps memory usage to a minimum.

As shown in the figure, SpringSource DMK runs on top of Equinox within a standard Java Virtual Machine. Above the DMK is a layer of subsystems which contribute functionality to the dm Server. Subsystems are configured to run for various profiles and typically provide additional services to the basic OSGi container such as serviceability, management, and personality-specific deployment.

In the SpringSource dm Server, applications are modular and each module has a personality that describes what kind of module it is: web, batch, web service, etc. The dm Server deploys modules of each personality in a personality-specific manner. For example, web modules are configured in Tomcat with web context. Each module in the application can be updated independently of the other modules whilst retaining the identity of being part of the larger application. Whatever kind of application you are building, the programming model remains standard Spring and Spring DM.

Version 1.0.1.RELEASE of the SpringSource dm Server supports the bundle, web, and WAR personalities, which enable you to build sophisticated web applications. The WAR personality includes support for standard Java EE WARs, "shared library" WARs, and "shared services" WARs, each of which will be covered in greater detail in Chapter 4, Deployment Architecture. Future releases will include support for more personalities such as batch, web services, etc.

3.3 Why the SpringSource dm Server?

You could deploy a web application in a stand-alone servlet engine or application server. Or you could even deploy directly in an OSGi container such as Equinox. However, deploying in the SpringSource dm Server offers a number of key benefits that make it both more appealing and more suitable for enterprise application development.

3.3.1 Deployment options and migration paths

While many applications deployed in the SpringSource dm Server will take advantage of OSGi capabilities, not all applications need such sophistication. For example, development teams may initially choose to continue packaging existing web applications as standard WAR files and then gradually migrate toward a fully OSGi-based packaging and deployment model. The SpringSource dm Server makes such migrations easy for developers by supporting multiple packaging and deployment formats. These formats and migration strategies are discussed in greater detail in Chapter 6, Migrating to OSGi and Chapter 7, Case study: Migrating the Form Tags sample application..

3.3.2 Simplified development and deployment of OSGi-based applications

Prior to the release of the SpringSource dm Server, developing and deploying OSGi applications involved inherent complexity such as:

  • Obtaining OSGi bundles for popular Java libraries: For optimal benefits, every technology you use in an OSGi application must be packaged as OSGi bundles. Currently, this involves manually converting JAR files into bundles and making sure that any libraries needed by those bundles are also available as OSGi bundles.
  • Package management complexity: OSGi bundles use other bundles through Import-Package manifest headers. Many applications use a set of common technologies (e.g., an ORM solution, a web framework, etc.). Combining these two characteristics leads to duplicated configuration in the form of repeated and verbose Import-Package statements.
  • Lack of application-level isolation: In OSGi everything is a bundle, and all bundles share the same OSGi Service Registry. To highlight how conflicts can arise between applications and their services in this shared service registry, consider the following scenarios.
    • Application A is comprised of bundles B and C. In a standard OSGi environment, if you attempt to install two instances of the same version of application A (i.e., two sets of bundles B and C), a clash will occur, because you cannot deploy multiple bundles with the same Bundle-SymbolicName and Bundle-Version combination.
    • Application A1 is comprised of bundles B1 and C1. Similarly, application A2 is comprised of bundles B2 and C2. Each bundle has a unique combination of Bundle-SymbolicName and Bundle-Version. Bundles B1 and B2 both export service S which is imported by both C1 and C2. In contrast to the previous example, there is no conflict resulting from duplicate Bundle-SymbolicName/Bundle-Version combinations; however, there is a clash for the exported service S. Which service S will bundles C1 and C2 end up using once they are installed? Assuming bundles B1 and C1 are intended to work together, you would not want bundle C1 to get a reference to service S from bundle B2, because it is installed in a different logical application. On the contrary, you typically want bundle C1 to get a reference to service S exported by bundle B1, but in a standard OSGi environment this may not be the case.

Furthermore, since standard OSGi does not define a notion of an application as a set of bundles, you cannot deploy or undeploy an application and its constituent bundles as a single unit.

The SpringSource dm Server introduces a number of features to solve these issues:

  • It includes OSGi bundles for many popular Java libraries to get you started quickly with creating OSGi applications.
  • It introduces an OSGi library concept that obviates the need to duplicate verbose Import-Package statements.
  • It introduces the PAR packaging format which offers application-level isolation and deployment.

3.3.3 Enhanced diagnostics during deployment and in production

Identifying why an application won't deploy or which particular library dependencies are unsatisfied is the cause of many headaches! Similarly, production time errors that don't identify the root cause are all too familiar to Java developers. The dm Server was designed from the ground up to enable tracing and First Failure Data Capture (FFDC) that empower developers with precise information at the point of failure to fix the problem quickly.

4. Deployment Architecture

The SpringSource dm Server offers several choices when it comes to deploying applications. Each choice offers certain advantages, and it is important to understand those in order to make the right choice for your application. In this chapter, we take a closer look at the choices offered, compare them, and provide guidelines in choosing the right one based on your specific needs.

The dm Server supports standard self-contained WAR files thus allowing you to use the SpringSource dm Server as an enhanced web server. The dm Server also supports the Shared Libraries WAR format which allows for slimmer WAR files that depend on OSGi bundles instead of including JAR files inside the WAR. The Shared Services WAR format allows developers to further reduce the complexity of standard WARs by deploying services and infrastructure bundles alongside the WAR. A shared services WAR will then consume the services published by those bundles. To complete the picture, the dm Server supports a new OSGi-based Web Module deployment format for web applications that builds on the benefits provided by a shared services WAR and provides additional conveniences for developing and deploying Spring MVC based web applications.

For applications consisting of multiple bundles and web applications, the PAR format is the primary deployment model which takes advantage of OSGi capabilities. We will explore all of these formats and their suitability later in this guide.

4.1 Supported Deployment Formats

The SpringSource dm Server supports applications packaged in the following formats:

When you deploy an application to the dm Server, each deployment artifact (e.g., a single bundle, WAR, or PAR) passes through a deployment pipeline. This deployment pipeline supports the notion of personality-specific deployers which are responsible for processing an application with a certain personality (i.e., application type). The 1.0.1.RELEASE release of the dm Server natively supports personality-specific deployers analogous to each of the aforementioned packaging options. Furthermore, the deployment pipeline can be extended with additional personality deployers, and future releases of the dm Server will provide support for personalities such as Batch, Web Services, etc.

Let's take a closer look now at each of the supported deployment and packaging options to explore which one is best suited for your applications.

4.1.1 Raw OSGi Bundles

At its core, the SpringSource dm Server is an OSGi container. Thus any OSGi-compliant bundle can be deployed directly on the dm Server unmodified. You'll typically deploy an application as a single bundle or a set of stand-alone bundles if you'd like to publish or consume services globally within the container via the OSGi Service Registry.

4.1.2 WAR Deployment Formats

For Web Application Archives (WAR), the SpringSource dm Server provides support for the following three formats.

Each of these formats plays a distinct role in the incremental migration path from a standard Java EE WAR to an OSGi-ified web application.

4.1.2.1 Standard WAR

Standard WAR files are supported directly in the dm Server. At deployment time, the WAR file is transformed into an OSGi bundle and installed into Tomcat. All the standard WAR contracts are honored, and your existing WAR files should just drop in and deploy without change. Support for standard, unmodified WAR files allows you to try out the SpringSource dm Server on your existing web applications and then gradually migrate toward the Shared Libraries WAR , Shared Services WAR , and Web Module formats.

In addition to the standard support for WARs that you would expect from Tomcat, the dm Server also enables the following features:

  1. Spring-driven load-time weaving (see Section 6.8.4, “Load-time weaving with AspectJ in the Spring Framework").

  2. Diagnostic information such as FFDC (first failure data capture)

The main benefit of this application style is familiarity -- everyone knows how to create a WAR file! You can take advantage of the dm Server's added feature set without modifying the application. The application can also be deployed on other Servlet containers or Java EE application servers.

You may choose this application style if the application is fairly simple and small. You may also prefer this style even for large and complex applications as a starting point and migrate to the other styles over time as discussed in Chapter 6, Migrating to OSGi .

4.1.2.2 Shared Libraries WAR

If you have experience with developing and packaging web applications using the standard WAR format, you're certainly familiar with the pains of library bloat. So, unless you're installing shared libraries in a common library folder for your Servlet container, you have to pack all JARs required by your web application in /WEB-INF/lib . Prior to the release of the SpringSource dm Server, such library bloat has essentially been the norm for web applications, but now there is a better solution! The Shared Libraries WAR format reduces your application's deployment footprint and eradicates library bloat by allowing you to declare dependencies on libraries via standard OSGi manifest headers such as Import-Package and Require-Bundle . The dm Server provides additional support for simplifying dependency management via the Import-Library and Import-Bundle manifest headers which are essentially macros that get expanded into OSGi-compliant Import-Package statements.

[Tip]Tip

For detailed information on which libraries are already available, check out the SpringSource Enterprise Bundle Repository .

4.1.2.3 Shared Services WAR

Once you've begun taking advantage of declarative dependency management with a Shared Libraries WAR, you'll likely find yourself wanting to take the next step toward reaping further benefits of an OSGi container: sharing services between your OSGi-compliant bundles and your web applications. By building on the power and simplicity of Spring-DM, the Shared Services WAR format puts the OSGi Service Registry at your finger tips. As a best practice you'll typically publish services from your domain, service, and infrastructure bundles via <osgi:service ... /> and then consume them in your web application's ApplicationContext via <osgi:reference ... />. Doing so promotes programming to interfaces and allows you to completely decouple your web-specific deployment artifacts from your domain model, service layer, etc., and that's certainly a step in the right direction. Of the three supported WAR deployment formats, the Shared Services WAR is by far the most attractive in terms of modularity and reduced overall footprint of your web applications.

4.1.3 Web Modules

Above and beyond WAR-based deployment formats, the SpringSource dm Server introduces a deployment and packaging option for OSGi-compliant web applications, the Web Module format. Web modules have a structure similar to a Shared Services WAR and can therefore take full advantage of all three WAR deployment formats. In addition, web modules benefit from reduced configuration for Spring MVC based applications via new OSGi manifest headers such as Web-DispatcherServletUrlPatterns and Web-FilterMappings. For further details on these and other Web-* manifest headers, please consult Section 5.2.3.1, “Web Module Manifest Headers”.

If you're building a Spring MVC based web application as a web module, you won't need to worry about configuring a root WebApplicationContext or an ApplicationContext for your DispatcherServlet. Based on metadata in your web module's /META-INF/MANIFEST.MF, the dm Server will auto-generate an appropriately configured web.xml for you on-the-fly, and your application will use the ApplicationContext created for your web module by Spring-DM. Future releases of the dm Server will add additional support to simplify configuration of Spring Web Flow based web applications as well.

4.1.4 PAR

A PAR is a standard JAR which contains all of the modules of your application (e.g., service, domain, and infrastructure bundles as well as a WAR or web module for web applications) in a single deployment unit. This allows you to deploy, refresh, and undeploy your entire application as a single entity. If you are familiar with Java EE, it is worth noting that a PAR can be considered a replacement for an EAR (Enterprise Archive) within the context of an OSGi container. As an added bonus, modules within a PAR can be refreshed independently and on-the-fly, for example via the SpringSource dm Server Tool Suite (see Chapter 8, Tooling).

Many of the benefits of the PAR format are due to the underlying OSGi infrastructure, including:

  • Fundamentally modularized applications: instead of relying on fuzzy boundaries between logical modules in a monolithic application, this style promotes physically separated modules in the form of OSGi bundles. Then each module may be developed separately, promoting parallel development and loose coupling.

  • Robust versioning of various modules: the versioning capability offered by OSGi is much more comprehensive than any alternatives. Each module can specify a version range for each of its dependencies. Bundles are isolated from each other in such a way that multiple versions of a bundle may be used simultaneously in an application.

  • Improved serviceability: each bundle may be deployed or undeployed in a running application. This allows modifying the existing application to fix bugs, improve performance, and even to add new features without having to restart the application.

Furthermore, PARs scope the modules of your application within the dm Server. Scoping provides both a physical and logical application boundary, effectively shielding the internals of your application from other PARs deployed within the dm Server. This means your application doesn't have to worry about clashing with other running applications (e.g., in the OSGi Service Registry). You get support for load-time weaving, classpath scanning, context class loading, etc., and the dm Server does the heavy lifting for you to make all this work seamlessly in an OSGi environment. If you want to take full advantage of all that the SpringSource dm Server and OSGi have to offer, packaging and deploying your applications as a PAR is definitely the recommend choice.

[Tip]OSGi != multiple JARs

Note that while physically separated modules can, in theory, be implemented simply using multiple JARs, complex versioning requirements often make this impractical. For example, consider the situation depicted in the diagram below.

  • Bundle A depends on version 1.0.0 of bundle B and version 2.0.0 of bundle C.

  • Bundle B depends on version 1.0.0 of bundle C.

Suppose that versions 1.0.0 and 2.0.0 of bundle C are neither backward nor forward compatible. Traditional monolithic applications cannot handle such situations: either bundle A or bundle B would need reworking which undermines truly independent development. OSGi's versioning scheme enables this scenario to be implemented in a robust manner. If it is desirable to rework the application to share a single version of C, then this can be planned in and is not forced.

4.2 Dependency Types

In an OSGi environment, there are two kinds of dependencies between various bundles: type dependency and service dependency.

  • Type dependency: A bundle may depend on a type exported by another bundle thus creating a type dependency. Type dependencies are managed through Import-Package and Export-Package directives in the OSGi manifest. This kind of dependency is similar to a JAR file using types in other JAR files from the classpath. However, as we've seen earlier, there are significant differences.

  • Service dependency: A bundle may also publish services (preferably using Spring-DM), and other bundles may consume those services. If two bundles depend on the same service, both will be communicating effectively to the same object. More specifically, any state for that service will be shared between all the clients of that service. This kind of arrangement is similar to the commonly seen client-server interaction through mechanisms such as RMI or Web Services.

4.3 A guide to forming bundles

So what makes a good application suitable for deployment on the SpringSource dm Server? Since OSGi is at the heart of the dm Server, modular applications consisting of bundles, which each represent distinct functionality and well-defined boundaries, can take maximum advantage of the OSGi container's capabilities. The core ideas behind forming bundles require following good software engineering practices: separation of concerns, minimum coupling, and communication through clear interfaces. In this section, we look at a few approaches that you may use to create modular applications for SpringSource dm Server deployment. Please consider the following discussion as guidelines and not as rules.

Bundles can be formed along horizontal slices of layering and vertical slices of function. The objective is to enable independent development of each bundle and minimize the skills required to develop each bundle.

For example, an application could have the following bundles: infrastructure, domain, repository, service, and web as shown in the following diagram.

Each bundle consists of types appropriate for that layer and exports packages and services to be used by other layers. Let's examine each bundle in more details:

Table 4.1. Bundles across layers

BundlesImported PackagesExported PackagesConsumed ServicesPublished Services
InfrastructureThird-party librariesInfrastructure interfacesNoneNone
DomainDepends: for example, if JPA is used to annotate persistent types, then JPA packages.Public domain typesNoneNone
WebDomain, ServiceNoneService beansNone
ServiceDomain, Infrastructure, RepositoryService interfacesRepository beansService beans
RepositoryDomain, Third-party libraries, ORM bundles, etc.Repository interfacesDataSources, ORM session/entity managers, etc.Repository beans


Within each layer, you may create bundles for each subsystem representing a vertical slice of business functionality. For example, as shown in the following figure, the service layer is divided into two bundles each representing separate business functionalities.

You can similarly separate the repositories, domain classes, and web controllers based on the business role they play.

5. Developing Applications

Applications that take advantage of the OSGi capabilities of the SpringSource dm Server are typically comprised of multiple bundles. Each bundle may have dependencies on other bundles. Furthermore, each bundle exposes only certain packages and services. In this chapter, we look at how to create bundles, import and export appropriate functionality, and create artifacts to deploy web applications on the SpringSource dm Server.

5.1 Anatomy of a bundle

[Tip]Tip

This is an abbreviated introduction to OSGi bundles. Please refer to the Spring Dynamic Modules for OSGi documentation for full details.

An OSGi bundle is simply a jar file with metadata that describe additional characteristics such as version and imported and exported packages.

A bundle exports types and publishes services to be used by other bundles:

  • Types: via the OSGi Export-Package directive,

  • Services: via Spring-DM's <service ... /> XML namespace element.

A bundle may import types and services exported by other bundles:

  • Types: via the OSGi Import-Package directive,

  • Services: via Spring-DM's <reference ... /> XML namespace element.

Let's see an example from the PetClinic sample application. The following listing shows the MANIFEST.MF file for the org.springframework.petclinic.infrastructure.hsqldb bundle.

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: PetClinic HSQL Database Infrastructure
Bundle-SymbolicName: org.springframework.petclinic.infrastructure.hsqldb
Bundle-Version: 1.0
Bundle-Vendor: SpringSource Inc.
Import-Library: org.springframework.spring;version="[2.5,2.6]"
Import-Bundle: com.springsource.org.apache.commons.dbcp;version="[1.2.2.osgi,1.2.2.osgi]",
 com.springsource.org.hsqldb;version="[1.8.0.9,1.8.0.9]"
Import-Package: javax.sql
Export-Package: org.springframework.petclinic.infrastructure
		

The org.springframework.petclinic.infrastructure.hsqldb bundle expresses its dependencies on the javax.sql package, the Commons DBCP and HSQLDB bundles, and the Spring library (we will examine the details of the library artifact in Section 5.5.3, “Defining libraries”). The Commons DBCP bundle is imported at a version of exactly 1.2.2.osgi and the HSQLDB bundle is imported at a version of exactly 1.8.0.9. The Spring library is imported at a version between 2.5 inclusive and 2.6 exclusive.

Note that you do not specify the bundle that will provide the imported packages. The SpringSource dm Server will examine the available bundles and satisfy the required dependencies.

The following osgi-context.xml file from the PetClinic sample's org.springframework.petclinic.repository.jdbc bundle declares a service published by the bundle and references a service published by another bundle.

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/osgi" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xsi:schemaLocation="http://www.springframework.org/schema/osgi  
        http://www.springframework.org/schema/osgi/spring-osgi.xsd
        http://www.springframework.org/schema/beans   
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <service id="osgiClinic" ref="clinic" interface="org.springframework.petclinic.repository.Clinic" />
    <reference id="dataSource" interface="javax.sql.DataSource"/>

</beans:beans>

The service element publishes the clinic bean (a regular Spring bean declared in the module-context.xml file) and specifies org.springframework.petclinic.repository.Clinic as the type of the published service.

The reference elements define a dataSource bean that references a service published by another bundle with a an interface type of javax.sql.DataSource.

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>

5.3 Programmatic Access to Personality-specific Features

Module personalities typically provide automatic access to features specific to the personality via custom manifest headers or other configuration mechanisms. There may be situations, however, for which programmatic access to such features is desirable or necessary. This section describes how to programmatically access personality-specific features from application code in a module.

5.3.1 Programmatic Access to Web Personality Features

5.3.1.1 Programmatic Access to the WebApplicationContext

The SpringSource dm Server automatically creates a WebApplicationContext for Web Modules and appropriately configured Shared Services WARs which have Spring-DM powered ApplicationContext XML configuration files. For Web Modules in particular, a WebApplicationContext will be created which is typically used in conjunction with an auto-configured Spring MVC DispatcherServlet. In such scenarios, there is generally no need to access the WebApplicationContext programmatically, since all components of the web application are configured within the scope of the WebApplicationContext itself. For Shared Services WARs, or for Web Modules which do not directly rely on Spring MVC, you can alternatively access the Spring-DM powered WebApplicationContext via the web application's ServletContext. The Web Personality subsystem stores the bundle's WebApplicationContext in the ServletContext under the attribute name "BSN-ApplicationContext", where BSN is the Bundle-SymbolicName of your Shared Services WAR or Web Module. Thus, for a Web Module, you can use Spring MVC's WebApplicationContextUtils' getWebApplicationContext(servletContext, attributeName) method (or other means) to programmatically retrieve a reference to the WebApplicationContext, which is an instance of ServerOsgiBundleXmlWebApplicationContext. For Shared Services WARs, you can programmatically retrieve the WebApplicationContext directly from the ServletContext.

Alternatively, since the Web Personality subsystem also stores the WebApplicationContext under the attribute name with the value of the WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE constant, you may choose to use Spring MVC's WebApplicationContextUtils' getWebApplicationContext(servletContext) or getRequiredWebApplicationContext(servletContext) methods to access the WebApplicationContext without providing an explicit attribute name.

5.3.1.2 Programmatic Access to the BundleContext

Similar to programmatic access to the ApplicationContext as described above, you can access the BundleContext of your Shared Services WAR or Web Module via the web application's ServletContext. The Web Personality subsystem stores the bundle context under the attribute name with the value of the ServerOsgiBundleXmlWebApplicationContext.BUNDLE_CONTEXT_ATTRIBUTE constant.

[Note]Note

ServerOsgiBundleXmlWebApplicationContext resides in the com.springsource.server.web.dm package which is automatically imported in your Web Module's or Shared Services WAR's bundle manifest.

5.4 Automatic Imports

The SpringSource dm Server generates automatic package imports (e.g., via the Import-Package manifest header) for various module personalities. This section lists which packages are automatically generated for each personality.

5.4.1 Automatic Imports for the Web Personality

All deployment artifacts supported by the Web personality (i.e., all WAR variants and Web Modules) will have the following packages automatically added to their bundle manifest via the appropriate Import-Package statements.

  • com.springsource.server.web.dm
  • javax.annotation
  • javax.annotation.security
  • javax.ejb
  • javax.el
  • javax.management
  • javax.management.loading
  • javax.management.modelmbean
  • javax.management.monitor
  • javax.management.openmbean
  • javax.management.relation
  • javax.management.remote
  • javax.management.remote.rmi
  • javax.management.timer
  • javax.naming
  • javax.naming.directory
  • javax.naming.event
  • javax.naming.ldap
  • javax.naming.spi
  • javax.net
  • javax.net.ssl
  • javax.persistence
  • javax.rmi
  • javax.rmi.CORBA
  • javax.rmi.ssl
  • javax.servlet
  • javax.servlet.http
  • javax.servlet.jsp
  • javax.servlet.jsp.el
  • javax.servlet.jsp.jstl.core
  • javax.servlet.jsp.jstl.fmt
  • javax.servlet.jsp.jstl.sql
  • javax.servlet.jsp.jstl.tlv
  • javax.servlet.jsp.resources
  • javax.servlet.jsp.tagext
  • javax.servlet.resources
  • javax.xml.ws
  • org.apache.el
  • org.apache.el.lang
  • org.apache.el.parser
  • org.apache.el.util

In addition, to ensure compatibility for existing, standard Java EE WARs, the dm Server automatically imports all packages exported by the OSGi system bundle, excluding any packages which begin with "org.eclipse" or "com.springsource". The resulting set of filtered system bundle exports will be automatically imported for all WAR variants but not for Web Modules; however, for all web deployment artifacts it is recommended that all known dependencies be explicitly specified in MANIFEST.MF via the appropriate Import-Package statements.

[Tip]System Bundle Package Exports

For further details on which packages are exported by the OSGi system bundle, consult the server.profile file located in the SERVER_HOME/lib directory which corresponds to the version of the JVM on which the dm Server is running (e.g., java5-server.profile or java6-server.profile).

5.5 Working with dependencies

Complex enterprise frameworks such a Spring and Hibernate are typically divided into many, many different packages. Traditionally, if an OSGi bundle wished to make extensive use of such a framework its manifest would have to import a huge number of different packages. This can be an error-prone and tedious process. Furthermore, application developers are used to thinking in terms of their application using a framework, such as Spring, as a whole, rather than a long list of all the different packages that comprise the framework.

The following figure provides a simple illustration of the complexity of only using Import-Package:

The SpringSource dm Server reduces the need for long lists of imported packages by introducing two new manifest headers; Import-Bundle and Import-Library. The following figure provides an illustration of the simplification that these new headers offer:

As you can see, use of Import-Bundle and Import-Library can lead to a dramatic reduction in the number of imports that you need to include in an application bundle's manifest. Furthermore, Import-Bundle and Import-Library are simply aliases for Import-Package; at deployment time Import-Bundle and Import-Library header entries are automatically expanded into numerous Import-Package entries. This means that you retain the exact same semantics of using Import-Package, without having to go through the labourious process of doing so.

5.5.1 Importing libraries

A bundle in an application can declare a dependency on a library by using the SpringSource dm Server-specific Import-Library header. This header specifies a comma-separated list of library symbolic names and version ranges that determine which libraries are imported. By default a dependency on a library is mandatory but this can be controlled through use of the resolution directive in exactly the same way as it can with Import-Package.

Import-Library: org.springframework.spring;version="[2.5.4, 3.0)",
 org.aspectj;version="[1.6.0,1.6.0]";resolution:="optional"
            

This example Import-Library header declares a mandatory dependency on the Spring library at a version from 2.5.4 inclusive to 3.0 exclusive. It also declares an optional dependency on the AspectJ library at exactly 1.6.0.

5.5.2 Importing bundles

A bundle in an application can declare a dependency on a bundle by using the SpringSource dm Server-specific Import-Bundle header. The header specifies a comma-separated list of bundle symbolic names and version ranges that determine which bundles are imported. By default a dependency on a bundle is mandatory but this can be controlled through use of the resolution directive in exactly the same way as it can with Import-Package.

Import-Bundle: com.springsource.org.apache.commons.dbcp;version="[1.2.2.osgi, 1.2.2.osgi]"
           

This example Import-Bundle header declares a mandatory dependency on the Apache Commons DBCP bundle at exactly 1.2.2.osgi.

5.5.3 Defining libraries

Libraries are defined in a simple text file, typically with a .libd suffix. This file identifies the library and lists all of its constituent bundles. For example, the following is the library definition for Spring 2.5.4:

Library-SymbolicName: org.springframework.spring
Library-Version: 2.5.4
Library-Name: Spring Framework
Import-Bundle: org.springframework.core;version="[2.5.4,2.5.5)",
 org.springframework.beans;version="[2.5.4,2.5.5)",
 org.springframework.context;version="[2.5.4,2.5.5)",
 org.springframework.aop;version="[2.5.4,2.5.5)",
 org.springframework.web;version="[2.5.4,2.5.5)", 
 org.springframework.web.servlet;version="[2.5.4,2.5.5)",
 org.springframework.jdbc;version="[2.5.4,2.5.5)",
 org.springframework.orm;version="[2.5.4,2.5.5)",
 org.springframework.transaction;version="[2.5.4,2.5.5)",
 org.springframework.context.support;version="[2.5.4,2.5.5)",
 org.springframework.aspects;version="[2.5.4,2.5.5)",
 com.springsource.org.aopalliance;version="1.0"
			    

The following table lists all of the headers that may be used in a library definition:

Table 5.3. Library definition headers

HeaderDescription
Library-SymbolicNameIdentifier for the library
Library-VersionVersion number for the library
Import-BundleA comma separated list of bundle symbolic names, each may optionally specify a version
Library-NameOptional. The human-readable name of the library
Library-DescriptionOptional. A human-readable description of the library

5.5.4 Installing dependencies

Rather than encouraging the packaging of all an application's dependencies within the application itself, SpringSource dm Server uses a local provisioning repository of bundles and libraries upon which an application can depend. When the SpringSource dm Server encounters an application with a particular dependency, it will automatically provide, from its provisioning repository, the appropriate bundle or library.

Making a dependency available for provisioning is simply a matter of copying it to the appropriate location in the dm Server's local provisioning repository. By default this is SERVER_HOME/repository/bundles/usr for bundles, and SERVER_HOME/repository/libraries/usr for libraries. A more detailed discussion of the provisioning repository can be found in the User Guide.

5.6 Application trace

As described in the User Guide SpringSource dm Server provides support for per-application trace. SpringSource dm Server provides SLF4J-based implementations of both Commons Logging and Log4J which allow trace generated by applications using those APIs to be captured and included in the application trace file. This use of SLF4J-based replacement implementations means that the standard configuration mechanisms for Commons Logging and Log4J cannot be used. Instead, application trace is configured via the use of the Application-TraceLevels header in the application's manifest as described in the User Guide.

5.6.1 Using vanilla Log4J

If you do not wish to take advantage of the SpringSource dm Server's built-in support for per-application trace, it is possible to force your application to utilise vanilla Log4J rather than the SLF4J-based implementation that is provided in the SpringSource dm Server. This can be achieved by specifying the bundle symbolic name of the vanilla Log4J bundle when importing the Log4J package in your application's manifests. E.g.:

Import-Package: org.apache.log4j;bundle-symbolic-name="com.springsource.org.apache.log4j"
                

5.7 Application versioning

In much the same way that individual OSGi bundles can be versioned, SpringSource dm Server allows applications to be versioned. This is achieved by using the Application-Version manifest header, in the case of a multi-bundle application packaged as a PAR file, or by using the Bundle-Version manifest header, in the case of a single-bundle application.

SpringSource dm Server uses an application's version to prevent clashes when multiple versions of the same application are deployed at the same time. For example, the application trace support described in Section 5.6, “Application trace”, includes the application's name and version in the trace file path. This ensures that each version of the same application has its own trace file.

6. Migrating to OSGi

Taking on a new technology such as OSGi may seem a bit daunting at first, but a proven set of migration steps can help ease the journey. Teams wishing to migrate existing applications to run on the SpringSource dm Server will find that their applications typically fall into one of the following categories.

  • Web Application: for web applications, this chapter provides an overview of the steps required to migrate from a Standard WAR to a Web Module. Furthermore, the following chapter provides a detailed case study involving the migration of the Spring 2.0 Form Tags show case application.

  • Anything else: for any other type of application, you will typically either deploy your application as multiple individual bundles or as a single PAR, which is the recommended approach for deploying applications on the SpringSource dm Server. See Section 6.2, “PAR” for details on migrating to a PAR.

6.1 Migrating Web Applications

Many applications may start with the standard WAR format for web applications and gradually migrate to a more OSGi-oriented architecture. Since the SpringSource dm Server offers several benefits to all supported deployment formats, it provides a smooth migration path. Of course, depending on your application's complexity and your experience with OSGi, you may choose to start immediately with an OSGi-based architecture.

6.1.1 Standard WAR

If you are not yet familiar with OSGi or simply want to deploy an existing web application on the SpringSource dm Server, you can deploy a standard WAR and leverage the dm Server with a minimal learning curve. In fact reading the SpringSource dm Server User Guide is pretty much all that you need to do to get started. Furthermore, you will gain familiarity with the SpringSource dm Server, while preparing to take advantage of the other formats.

6.1.2 Shared Libraries WAR

The Shared Libraries WAR format is the first step to reaping the benefits of OSGi. In this phase, you dip your toes into OSGi-based dependency management by removing JAR files from the WAR and declaring dependencies on corresponding OSGi bundles.

6.1.3 Shared Services WAR

In this phase, you take the next step toward a fully OSGi-based architecture by separating your web artifacts (e.g., Servlets, Controllers, etc.) from the services they depend on.

6.1.4 Web Module

The final step in migrating a WAR is to convert it to a Web Module. As mentioned in Section 4.1.3, “Web Modules”, this format has a structure similar to that of a Shared Services WAR and adds additional benefits of reduced configuration for Spring MVC based applications via new OSGi manifest headers.

6.1.5 Web Migration Summary

The following diagram graphically depicts the migration path from a Standard WAR to a Web Module. As you can see, the libraries (libs) move from within the deployment artifact to the Bundle Repository. Similarly, the services move from within the WAR to external bundles and are accessed via the OSGi Service Registry. In addition, the overall footprint of the deployment artifact decreases as you move towards a Web Module.

6.2 PAR

When migrating an existing application to the PAR packaging and deployment format, you consider modularity as the prime objective. Following the ideas discussed in Section 4.3, “A guide to forming bundles”, you refactor the application into multiple bundles. You may start conservatively with a small number of bundles and then further refactor those bundles.

If the original code is crafted following good software practices such as separation of concerns and use of well-defined interfaces, migration may involve modifying only configuration and packaging. In other words, your Java sources will remain unchanged. Even configuration is likely to change only slightly.

For example, the following diagram depicts a typical web application that has been refactored and packaged as a PAR. The blue elements within the Application box constitute the bundles of the application. Each of these bundles imports types from other bundles within the PAR using Import-Package. The green elements in the left column represent libraries installed on the dm Server. The PAR's bundles reference these libraries using Import-Library. The purple element in the left column represents a bundle within the dm Server's bundle repository which is imported by the DAO bundle using Import-Bundle. In contrast to a traditional, monolithic WAR deployment, the PAR format provides both a logical and physical application boundary and simultaneously allows the application to benefit from both the OSGi container and the SpringSource dm Server.

7. Case study: Migrating the Form Tags sample application.

In this chapter we will walk through the steps needed to migrate the Form Tags sample application from a standard Java EE WAR to a fully OSGi compliant web module within a PAR. The migration involves four packaging and deployment formats:

Each of these migration steps will produce a web application that can be deployed and run on the dm Server.

The following image displays the directory structure you should have after installing the Form Tags sample. Note however that the release tag will typically resemble 1.0.0.RELEASE.

The dist directory contains the distributables, and the projects directory contains the source code and build scripts.

For simplicity, this chapter will focus on the distributables -- which are built using Spring-Build -- rather than on configuring a project in an IDE.

[Tip]Tip
Pre-packaged distributables are made available in the dist directory; however, if you would like to modify the samples or build them from scratch, you may do so using Spring-Build. Take a look at the README.TXT file in each of the folders under the projects directory in the dm-server-formtags samples directories for instructions.

7.1 Overview of the Form Tags Sample Application

The sample that we will be using is the Form Tags show case sample which was provided with Spring 2.0. The Form Tags application has been removed from the official Spring 2.5.x distributions; however, since it is relatively simple but still contains enough ingredients to demonstrate the various considerations required during a migration, we have chosen to use it for these examples.

The purpose of the Form Tags show case sample was to demonstrate how the Spring specific form: tags, released in Spring 2.0, make view development with JSPs and tag libraries easier. The Form Tags application consists of a single UserService which returns a list of Users. Furthermore, the application demonstrates how to list, view, and edit Users in a simple Spring MVC based web application using JSP and JSTL.

7.2 Form Tags WAR

We begin with a standard WAR deployment.

[Note]Note
The SpringSource dm Server supports the standard Java EE WAR packaging and deployment format as a first-class citizen, and there are many benefits to deploying a standard WAR file on the dm Server including, but not limited to: tooling support, runtime error diagnostics, FFDC (i.e., first failure data capture), etc. In addition, support for standard WAR deployment provides an easy on-ramp for trying out the SpringSource dm Server with existing web applications.

The following screen shot displays the directory structure of the Form Tags application using the standard WAR format. As you can see, there is no deviation from the standard structure and layout, and as you would expect, all of the web application's third-party dependencies (e.g., Spring. Commons Logging, etc.) are packaged as JARs in WEB-INF/lib.

To deploy this application, simply copy dist/formtags-war-1.0.0.*.war to the SERVER_HOME/pickup directory for hot deployment.

You should then see the dm Server produce console output similar to the following:

[Note]Note

The console output has been reformatted to fit this document.

[2008-05-13 13:19:30.972] fs-watcher
    <SPSC1000I> Creating web application '/formtags-war-1.0.0.RELEASE'.
[2008-05-13 13:19:31.045] async-delivery-thread-1
    <SPSC1001I> Starting web application '/formtags-war-1.0.0.RELEASE'.
[2008-05-13 13:19:31.697] fs-watcher
    <SPDE0010I> Deployment of 'formtags-war-1.0.0.RELEASE.war' version '0' completed.

Navigate to http://localhost:8080/ plus the web application context path, which in the above case is formtags-war-1.0.0.RELEASE. Thus navigating to http://localhost:8080/formtags-war-1.0.0.RELEASE should render the sample application's welcome page, as displayed in the screen shot below.

[Tip]Tip
For WARs, the default web context path is the name of the WAR file without the .war extension. You can optionally specify a context path using the Web-ContextPath bundle manifest header, which will be described in further detail later.