[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

DEP-7: Java Web Application Packaging



There seemed to be enough interest in my proposal for how to handle web
application packaging that it was worth writing it up as a somewhat more
formal proposal so that we could look over all of the implications.  The
DEP system was designed for that, and includes the assumptions that
proposals can change (possibly a lot) or be rejected, so it seemed like a
good framework to use.

I've therefore written up what I think makes the most sense to do for web
applications as a first draft in DEP-7.  There are probably huge problems
with this, particularly since I'm relatively new to the world of Java web
applications and not horribly familiar with the problems and details.
Please forgive (and point out!) any glaring mistakes.

I'm entirely prepared to throw out most of this document in favor of
better ideas.  I've just found that getting something down for others to
look at helps the discussion a lot.

Anyway, here's the first draft.  I will follow up to this message with the
first draft of the proposed tool interface.  (The syntax is Markdown,
which will hopefully be readable enough as-is.)

[[meta title="DEP-7: Java Web Application Packaging"]]

    Title: Java Web Application Packaging
    DEP: 7
    State: DRAFT
    Date: 2010-08-24
    Drivers: Russ Allbery <rra@debian.org>
    URL: http://dep.debian.net/deps/dep7
    License: http://www.jclark.com/xml/copying.txt
    Abstract:
     Propose a file layout, set of conventions and best practices, and a
     supporting script interface for packaging Java web applications
     (servlets) and deploying them in containers.
     
# Introduction

Considerable progress has been made in recent years in packaging Java
libraries for Debian.  However, less work has been done, to date, on
packaging Java servlets.  These are common both in the free software world
as an implementation platform for web applications and in the enterprise
application development world.

Java servlets pose special challenges for Debian packaging, particularly
in the area of Filesystem Hierarchy Standard compliance.  The normal
deployment method for a servlet is either as a monolithic WAR file or a
corresponding directory structure that contains everything of interest to
the servlet.  This combines configuration files, code, and metadata in one
file or one directory tree, causing problems for proper configuration file
handling and integration of user customization.

Debian will also support multiple servlet containers, and a Java servlet
package should be able to deploy that servlet into the servlet container
of the user's choice.  We should attempt to minimize the amount of work
required in each servlet package to support additional servlet containers
and centralize that work as much as possible in a helper utility and by
following standard deployment strategies that will be supported by Java
servlet containers.

The goal of this proposal is to provide the basis of a Java web
application (servlet) packaging policy, including file system layout and
best practices, and specify the interface of a deployment tool to
translate between a Debian-Policy-compliant file layout with proper
handling of configuration files and the deployment WAR file or directory
tree required by a web container.  If accepted, it would be included in
the Java packaging policy for Debian.

This DEP will be discussed on the debian-java@lists.debian.org mailing
list.

# File Layout

A Java web application is normally deployed as either a WAR file or as an
exploded archive, which is the same file structure as a WAR file except
expressed on disk as a directory tree.  All components of the servlet are
included in the WAR file, which in addition to JAR files, classes, and JSP
files includes the configuration file `WEB-INF/web.xml`.  This file often
configures the application and controls such things as URL mappings, and
may need to be customized by the user.  Some web applications have
additional configuration files that need customization, or may even use
JSP as a templating language and expect the installing user to edit some
JSP pages.  However, the majority of the WAR file or exploded archive is
code.

Under Debian Policy and the Filesystem Hierarchy Standard,
architecture-independent code (the majority of a typical web application)
must be installed in `/usr/share`, but configuration files that the
installing user may want to edit to customize the application must be
installed in `/etc`.  This means that different components of the web
application must be installed in different paths.

This proposal reserves two areas in the file system for Java web
applications:

* `/usr/share/java/webapps/<webapp-name>`: Contains all
  architecture-independent files, such as JARs, class files, and JSPs,
  that make up the web application and that are not expected to be edited
  by the installing user.
  
* `/etc/java/webapps/<webapp-name>`: Contains all web application files
  that should be treated as configuration files in the Debian definition
  and possibly modified by the installing user to configure or customize
  the application.  This will normally include `WEB-INF/web.xml`.
  
Inside each of these directories, the layout of the files should match the
layout expected of a WAR file or exploded archive.  So, in other words,
the `web.xml` file for a web application named `demo-viewer` should be
installed in `/etc/java/webapps/demo-viewer/WEB-INF/web.xml`.

If the same file exists in both `/usr/share/java/webapps` and
`/etc/java/webapps`, the file in the latter location will take precedence.
Users may therefore selectively replace files in a web application by
putting a file with the same name into the `/etc/java/webapps` directory
in the appropriate location.

`<webapp-name>` should normally match the name of the Debian package
providing that web application.  It may contain a slash (`/`).  If one
package provides multiple web applications, a naming convention of
`<package>/<webapp>` should be used.  For example, if a package named
`apache-activemq` provided webapps `admin` and `fileserver`, the
`<webapp-name>`s for the above paths would be `apache-activemq/admin` and
`apache-activemq/fileserver`.

# Deployment

There are three common strategies for deploying a web application into a
web container:

1. Bundle the web application as a WAR file and drop that WAR file into
   the web application root for the web container.
   
2. Install the web application files as an exploded archive under the web
   application root for the web container.

3. Install the web application files elsewhere on the file system and then
   point the web container at the web application files using a mechanism
   such as a Tomcat context descriptor.

Approach 1 cannot be used directly by Debian packages since the WAR file
will contain both application code and configuration files with no way for
the user to change the configuration files.  Approach 2 is unappealing for
Debian packages since the files would need to be installed in the web
application root for every possible web container to work out of the box
with any web container in Debian, but the user may wish to run multiple
web containers with different sets of applications.

Approach 3 is tempting, and is currently being used in Debian for some
Java web applications.  However, in order to present the entire web
application as a unified tree, symlinks are required to allow
configuration files to be stored in `/etc` while the majority of the web
application is in `/usr/share`.  Since upstream web application developers
normally don't anticipate needing to separate configuration files from
other web application files, this may require a complicated and fragile
nest of symlinks to move the appropriate files into `/etc`.

Finally, approach 1 is the most "typical" approach for deploying web
applications in Java enterprise environments, so many upstream developers
expect users to deploy web applications as WAR files and tailor their
documentation accordingly.

Therefore, the proposed way to deploy web applications on Debian is for
the web application package to generate a WAR file from its installed
files and any user-edited configuration files, taken from the
`/usr/share/java/webapps` and `/etc/java/webapps` paths defined above, and
deploy that WAR file into the appropriate web application roots for the
desired web containers.  This will be done as follows:

1. From the `/usr/share/java/webapps` and `/etc/java/webapps` paths for
   the web application being deployed, build a merged tree of files
   created by first copying the `/usr/share/java/webapps` file tree and
   then copying the `/etc/java/webapps` file tree over top of it.  This
   implements the semantics described above, where any file in
   `/etc/java/webapps` overrides a file in `/usr/share/java/webapps` of
   the same name.
   
1. Generate a WAR file from that merged directory tree.

1. Deploy that WAR file to a web container.  If only one supported web
   container for that web application is installed on the system, the WAR
   file will be automatically deployed to that web container.  If there
   are multiple web containers on the system, the WAR file will be
   deployed into the preferred one following a web container ranking
   system (not yet specified).

1. On installation of the web application policy, it should be deployed
   into the web container chosen by the default algorithm above with a
   generic and safe configuration.

1. On upgrade or reconfiguration of the web application, redeploy the WAR
   file into whichever web container it was deployed.

1. On removal of the web application package, undeploy the WAR file from
   any web containers to which it was deployed.

These steps will be done with a tool that can also be run directly by the
user, allowing the user to build a WAR file without deploying it, undeploy
a web application from a particular web container, deploy a web
application into the non-default web container, and similar actions.

Whenever the user changes any of the configuration files for a web
application, they will have to redeploy the application using this same
tool.  This should be documented in README.Debian for any web application
using this system, and also in a README file in `/etc/java/webapps`.

Also see the
[draft interface for the deployment tool](java-deploy-webapp.pod).

# TODO

The following issues still need to be addressed:

* How to use the Endorsed Standards Override Mechanism to replace the XML
  parser for a particular web application or do the other overrides that
  require using this mechanism.
  
* Web application logging policy.

* Web application SecurityManager policy files.

* Determine a ranking system for web application containers to determine
  which web container a web application is deployed into when multiple
  containers are installed on the system.
  
* Does the deployment tool need to also deploy (and remove) extra
  configuration files that are specific to web containers, such as files
  for `/etc/tomcat6/policy.d`?

# License

Copyright 2010 Board of Trustees, Leland Stanford Jr. University

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the “Software”),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

# Changes

* 2010-08-24: Initial version based on a preliminary proposal to the
  debian-java mailing list.

-- 
Russ Allbery (rra@debian.org)               <http://www.eyrie.org/~eagle/>


Reply to: