Links Contents | Source OrganizationDirectory Structure |
The description below uses the variable name $CATALINA_HOME
to refer to the directory into which you have installed Tomcat 4,
and is the base directory against which most relative paths are
resolved. However, if you have configured Tomcat 4 for multiple
instances by setting a CATALINA_BASE directory, you should use
$CATALINA_BASE instead of $CATALINA_HOME for each of these
references.
A key recommendation of this manual is to separate the directory
hierarchy containing your source code (described in this section) from
the directory hierarchy containing your deployable application
(described in the preceding section). Maintaining this separation has
the following advantages:
- The contents of the source directories can be more easily administered,
moved, and backed up if the "executable" version of the application
is not intermixed.
- Source code control is easier to manage on directories that contain
only source files.
- The files that make up an installable distribution of your
application are much easier to select when the deployment
hierarchy is separate.
As we will see, the ant development tool makes the creation
and processing of such directory hierarchies nearly painless.
The actual directory and file hierarchy used to contain the source code
of an application can be pretty much anything you like. However, the
following organization has proven to be quite generally applicable, and is
expected by the example build.xml configuration file that
is discussed below. All of these components exist under a top level
project source directory for your application:
- docs/ - Documentation for your application, in whatever
format your development team is using.
- src/ - Java source files that generate the servlets,
beans, and other Java classes that are unique to your application.
If your source code is organized in packages (highly
recommended), the package hierarchy should be reflected as a directory
structure underneath this directory.
- web/ - The static content of your web site (HTML pages,
JSP pages, JavaScript files, CSS stylesheet files, and images) that will
be accessible to application clients. This directory will be the
document root of your web application, and any subdirectory
structure found here will be reflected in the request URIs required to
access those files.
- web/WEB-INF/ - The special configuration files required
for your application, including the web application deployment descriptor
(
web.xml ), tag library descriptors for custom tag libraries
you have created, and other resource files you wish to include within
your web application. Even though this directory appears to be a
subdirectory of your document root, the Servlet Specification
prohibits serving the contents of this directory (or any file it contains)
directly to a client request. Therefore, this is a good place to store
configuration information that is sensitive (such as database connection
usernames and passwords), but is required for your application to
operate successfully.
During the development process, two additional directories will be
created on a temporary basis:
- build/ - When you execute a default build
(
ant ), this directory will contain an exact image
of the files in the web application archive for this application.
For containers like Tomcat that allow you to deploy
unpacked directory structures, you need only copy this directory structure
into a subdirectory of $CATALINA_HOME/webapps in order to
deploy and test it.
- dist/ - When you execute the
ant dist
target, this directory will be created. It will create an exact image
of the binary distribution for your web application, including an license
information, documentation, and README files that you have prepared.
Note that these two directories should NOT be archived in
your source code control system, because they are deleted and recreated (from
scratch) as needed during development. For that reason, you should not edit
any source files in these directories if you want to maintain a permanent
record of the changes, because the changes will be lost the next time that a
build is performed.
External Dependencies |
What do you do if your application requires JAR files (or other
resources) from external projects or packages? A common example is that
you need to include a JDBC driver in your web application, in order to
operate.
Different developers take different approaches to this problem.
Some will encourage checking a copy of the JAR files you depend on into
the source code control archives for every application that requires those
JAR files. However, this can cause significant management issues when you
use the same JAR in many applications - particular when faced with a need
to upgrade to a different version of that JAR file.
Therefore, this manual recommends that you NOT store
a copy of the packages you depend on inside the source control archives
of your applications. Instead, the external dependencies should be
integrated as part of the process of deploying your
application. In that way, you can always pick up the appropriate version
of the JAR files from wherever your development system administrator has
installed them, without having to worry about updating your application
every time the version of the dependent JAR file is changed.
In the example Ant build.xml file, we will demonstrate
how to define build properties that let you configure the locations
of the files to be copied, without having to modify build.xml
when these files change. The build properties used by a particular
developer can be customized on a per-application basis, or defaulted to
"standard" build properties stored in the developer's home directory.
|
|
Source Code Control |
As mentioned earlier, it is highly recommended that you place all of the
source files that comprise your application under the management of a
source code control system like the Concurrent Version System (CVS). If you
elect to do this, every directory and file in the source hierarchy should be
registered and saved -- but none of the generated files. If you register
binary format files (such as images or JAR libraries), be sure to indicate
this to your source code control system.
We recommended (in the previous section) that you should not store the
contents of the build/ and dist/ directories
created by your development process in the source code control system. An
easy way to tell CVS to ignore these directories is to create a file named
.cvsignore (note the leading period) in your top-level source
directory, with the following contents:
| | | |
build
dist
build.properties
| | | | |
The reason for mentioning build.properties here will be
explained in the Processes section.
Detailed instructions for your source code control environment are beyond
the scope of this manual. However, the following steps are followed when
using a command-line CVS client:
- To refresh the state of your source code to that stored in the
the source repository, go to your project source directory, and
execute
cvs update -dP .
- When you create a new subdirectory in the source code hierarchy, register
it in CVS with a command like
cvs add {subdirname} .
- When you first create a new source code file, navigate to the directory
that contains it, and register the new file with a command like
cvs add {filename} .
- If you no longer need a particular source code file, navigate to the
containing directory and remove the file. Then, deregister it in CVS
with a command like
cvs remove {filename} .
- While you are creating, modifying, and deleting source files, changes
are not yet reflected in the server repository. To save your changes in
their current state, go to the project source directory
and execute
cvs commit . You will be asked to write a brief
description of the changes you have just completed, which will be stored
with the new version of any updated source file.
CVS, like other source code control systems, has many additional features
(such as the ability to tag the files that made up a particular release, and
support for multiple development branches that can later be merged). See the
links and references in the Introduction for
more information.
|
BUILD.XML Configuration File |
We will be using the ant tool to manage the compilation of
our Java source code files, and creation of the deployment hierarchy. Ant
operates under the control of a build file, normally called
build.xml , that defines the processing steps required. This
file is stored in the top-level directory of your source code hierarchy, and
should be checked in to your source code control system.
Like a Makefile, the build.xml file provides several
"targets" that support optional development activities (such as creating
the associated Javadoc documentation, erasing the deployment home directory
so you can build your project from scratch, or creating the web application
archive file so you can distribute your application. A well-constructed
build.xml file will contain internal documentation describing
the targets that are designed for use by the developer, versus those targets
used internally. To ask Ant to display the project documentation, change to
the directory containing the build.xml flie and type:
To give you a head start, a basic build.xml file
is provided that you can customize and install in the project source directory
for your application. This file includes comments that describe the various
targets that can be executed. Briefly, the following targets are generally
provided:
- clean - This target deletes any existing
build and dist directories, so that they
can be reconstructed from scratch. This allows you to guarantee that
you have not made source code modifications that will result in
problems at runtime due to not recompiling all affected classes.
- prepare - This target "prepares" the
build
directory, creating subdirectories as required. A common use of this
target is to copy static files (documentation, HTML pages, and JSP pages)
from the source directory to the build directory. When
executed, this target will only create directories if they do not
exist, and only copy files if the destination file does not exist,
or the source version of the file is newer. This target is generally
invoked indirectly, by virtue of a depends attribute on
some other task.
- compile - This target is used to compile any source code
that has been changed since the last time compilation took place. The
resulting class files are created in the
build directory, so
that they can be executed when the application is deployed. Because
this command is executed so often during development, it is normally
made the "default" target so that a simple ant command will
execute it.
- all - This target is a short cut for running the
clean target, followed by the compiile target.
Thus, it guarantees that you will recompile the entire application, to
ensure that you have not unknowingly introduced any incompatible changes.
- deploy - This target is used to install your
application into a servlet container (we will continue to use Tomcat
in our examples) so that it can be tested. If your application requires
external JAR files, they will be copied to the
/WEB-INF/lib
directory at deployment time.
- javadoc - This target creates Javadoc API documentation
for the Java classes in this web application. The example
build.xml file assumes you want to include the API
documentation with your app distribution, so it generates the docs
in a subdirectory of the dist directory. Because you normally
do not need to generate the Javadocs on every compilation, this target is
usually a dependency of the dist target, but not of the
compile target.
- dist - This target creates a distribution directory for
your application, including any required documentation, the Javadocs for
your Java classes, and a web application archive (WAR) file that will be
delivered to system administrators who wish to install your application.
Because this target also depends on the
deploy target, the
web application archive will have also picked up any external dependencies
that were included at deployment time.
|
|