The final step in the migration is that of a full blown
OSGi application with web support. The SpringSource dm Server introduces a
new packaging and deployment format: the PAR.
A PAR is a standard JAR with a ".par
"
file extension 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. Moreover, a PAR defines
both a physical and logical application boundary.
For web support above and beyond WAR-based deployment formats, the
SpringSource dm Server introduces a new 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 therefore build on the support for all three WAR deployment formats.
In addition, web modules benefit from reduced configuration for Spring
MVC based web applications.
The PAR sample is comprised of four directories, as shown below.
The formtags-par
directory is a Spring-Build project that
understands how to create the PAR from its constituent bundles.
Achieving the appropriate level of granularity for your OSGi application is more of an art than a science. It helps to look at the different requirements:
Table 7.1. Granularity drivers
Requirement | Description |
---|---|
Domain/Technical Layering | Applications can be split either by domain (i.e., by use case or vertically) or by their technical layers (i.e., horizontally). Since the Form Tags application essentially has only a single use case, the bundles are split by technical layering (i.e., domain, service, and web). |
Refreshability | A major benefit of OSGi is that of refreshability: if one bundle is changed, only bundles that have a dependency upon the exported types need to be refreshed. This has a high impact on development time costs as well as production costs. However, this can lead to lots of smaller, fine grained bundles. An example of this granularity would be to separate out the service API and implementation into two different bundles. This means that a change in the implementation wouldn't require any other bundles to be refreshed. |
Ultimately the right level of granularity will depend upon your particular application and team.
Note | |
---|---|
This topic will be revisited in greater detail later in the Programmer Guide in a chapter covering how to build a PAR from scratch. |
The service bundle is identical (except for the Bundle-SymbolicName
) to that
in the shared-services variation of the sample.
The PAR has also separated out the domain classes into their own bundle.
When layering by technical considerations, it is again
somewhat of an unofficial convention to have a
.domain
bundle.
A web module is a SpringSource dm Server construct which is both a web tier artifact and a valid OSGi bundle.
The following image is of the exploded web module JAR
(located inside the distributable /dist/formtags-par.*.jar
).
As you can see, at its core, a web module follows the conventions for an OSGi
bundle: the root of the bundle contains the META-INF
folder as well as compiled Java classes and class-path resources.
In addition, the web module contains a MODULE-INF
folder in the root of the bundle, which serves as the root for the
ServletContext
for the deployed web application.
The MODULE-INF
folder is therefore analogous to the
root of a standard WAR file. Note that there is no web.xml
deployment descriptor present in the /MODULE-INF/WEB-INF
folder, since the dm Server will automatically generate an appropriate
web.xml
based on web manifest headers.
Because a web module is an OSGi artifact, it follows that information about the
bundle should be in the /META-INF/MANIFEST.MF
.
In addition, in order to differentiate a web module from any other
type of bundle, you need to specify the Module-Type
manifest header and set its value to Web
.
Without this manifest header, the dm Server's deployment infrastructure
would simply deploy a web module as a standard bundle. The following
is the /META-INF/MANIFEST.MF
for the Form Tags
web module.
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: FormTags Web Module Bundle-SymbolicName: org.springframework.showcase.formtags.web-par Bundle-Vendor: SpringSource Inc. Import-Package: org.springframework.showcase.formtags.domain, org.springframework.showcase.formtags.service Import-Bundle: com.springsource.org.apache.taglibs.standard;version="1.1.2" Import-Library: org.springframework.spring;version="[2.5.4,3.0.0)" Module-Type: Web Web-ContextPath: formtags-par
Contrast this to the original web.xml
:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>formtags</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>formtags</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <jsp-config> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri> <taglib-location>/WEB-INF/tld/c.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri> <taglib-location>/WEB-INF/tld/fmt.tld</taglib-location> </taglib> </jsp-config> </web-app>
The same instructions are specified in the /META-INF/MANIFEST.MF
,
but they are much more concise. Please read Section 5.2.3.1, “Web Module Manifest Headers”
for detailed information on the requirements of a web module's /META-INF/MANIFEST.MF
and supported manifest headers.
Tip | |
---|---|
The <jsp-config... fragments are not needed by modern day
Servlet containers, but they are left in the above listing
for consistency with the original
web.xml from the Standard WAR sample.
|
Notice that there are no configuration options in the /META-INF/MANIFEST.MF
to indicate the location of the Spring configuration files. This is because, by default, a single
WebApplicationContext
will be created from all the Spring configuration files
in /META-INF/spring/*.xml
. This shouldn't be surprising as this is normal
behavior for any Spring-DM powered bundle.
Finally we need to construct the PAR itself. The following are the contents of the exploded PAR.
You can see that the PAR itself doesn't contain any resources or Java classes: it simply packages together a related set of bundles as a single, logical unit.
The PAR does however, contain its own /META-INF/MANIFEST.MF
.
Manifest-Version: 1.0 Application-SymbolicName: org.springframework.showcase.formtags-par Application-Version: 1.0.0 Application-Name: FormTags Showcase Application (PAR)
For more information on the contents of the PAR's
/META-INF/MANIFEST.MF
, please consult
Chapter 5, Developing Applications.
You can now deploy the PAR on the dm Server, for example by copying
/dist/formtags-par*.par
to the dm Server's
pickup
directory.
You should then see console output similar to the following:
Note | |
---|---|
The console output has been reformatted to fit this document. |
[2008-05-13 13:28:57.309] fs-watcher <SPSC1000I> Creating web application '/formtags-par'. [2008-05-13 13:28:57.539] async-delivery-thread-1 <SPSC1001I> Starting web application '/formtags-par'. [2008-05-13 13:28:58.016] fs-watcher <SPDE0010I> Deployment of 'formtags-par' version '1.0.0.RELEASE' completed.
Navigate to http://localhost:8080/formtags-par to see the welcome page.
Tip | |
---|---|
Note that the web application's context path is explicitly defined via the
Web-ContextPath manifest header in
/META-INF/MANIFEST.MF of the web module within
the PAR.
|