ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Drew Davidson <>
Subject Re: J2EE config/build best practices
Date Fri, 12 Apr 2002 22:14:21 GMT
Dave Smith wrote:

> Can anyone point me to a guide on the best way to layout source and package
> structure for building a J2EE project? Sort of an "Ant in Anger"
> ( for EJBs? I'm struggling
> to find the best place to put things so that it's easy to build and deploy.
> Should each EJB have its own subfolder in the project tree? Where should I
> put library code used by multiple EJBs and that may run outside a managed
> environment? I'm sure there are best practices that answer these questions
> and include sample build files, but I can't find a good guide. I don't want
> the Java Pet Store to serve as the model for my project...

This brings up an interesting point.  Ant is a good tool for doing your builds
but doesn't dictate practice; obviously the correct approach.  Look to Erik
Hatcher and his new book on Ant to provide true insight into this matter.

In the mean time...

It would be nice to have reusable ant "code" in the form of xml files that you
could include.  I've done this (partially) with my code in what I feel is a
rational way to lay things out.  I'm still not completely happy with it, but it
solves certain problems well and allows me to hand-edit my build.xml file
easily by just adding a single target that calls my specific project-type task
with the root of the directory I'm building:

<!-- ognl is a library -->
<target name="ognl">
    <ant target="library">
        <property name="srcdir" value="${workarea.src}/ognl"/>

<!-- ognl-test is a code that test the ognl library -->
<target name="ognl-test" depends="ognl">
    <ant target="compile-and-copy">
        <property name="srcdir" value="${workarea.src}/ognl/test"/>

The basis of all of this are several abstract targets that work using
parameters (the srcdir in the previous example) and implicitly assume a
structure to the "srcdir" directory.

For example, a web application would be layed out like the following:

<root>                          # root of my workarea
    lib                         # third-party libraries needed by all projects
(junit, struts, etc.)
    build_lib                   # third-party libraries needed by all projects
for building only (ant tasks, etc.)
    projects                    # top-level projects directory
        mylibrary               # library project that produces a jar file
            java                # source to the library
            meta                # resources to be put in the META-INF
(taglib.tld for example)
            test                # sub-project with testing code
                java            # Java source for test sub-project
        mywebapp                # root of the "mywebapp" web application
            java                # Java source that is independant of
            ui                  # Java source that is presentation-specific to
web application (Struts actions, etc.)
            meta                # web.xml, struts-config.xml, etc. that goes in
META-INF and WEB-INF directories
            global_resources    # .html, .jsp that are copied to the root
            jsp                 # similar to jsp except separate for
organizational purposes
            lib                 # webapp-required jars and zips that are copied
to WEB-INF/lib
            build_lib           # build-time libraries required by this build
but not installed with the web app (ant tasks, etc.)
            properties          # properties files that are used for project
            test                # test sub-project code for the webapp
(httpunit and cactus tests, junit tests, etc)
                java            # Java source for test sub-project

As you see from above, each project is listed in the build.xml and calls the
target for the type of project that you are building.  The above project is a
library so it calls the "library" target to build the library.  The ognl-test
is just code so it calls "compile-and-copy" to build.

I generally like the idea that the builds will go to a staging area (like
/tmp/builds/<projectname>) before being assembled into a deployable component.

In the case of my webapps and other EJB-based apps I like to have .ejb files
separate from one another and have them assembled at build-time.  I've had
several good replies to use XSLT to merge various .ejb files into one; I'm
working on this portion right now.

Related to the above is the problem with developing and deploying a Struts and
EJB-based application.  The number of files that you have to deal with gets
large quickly; these files are all related conceptually but you are forced to
have one file for things like the EJB deployment descriptor (which requires
that one file contain entity definitions for EJBs that have relations to one
another) and the struts-config.xml.  These files grow huge as your project
grows and they become virtually unmanageable.  Hence I've been trying to get a
way to specify on the relavent pieces that will coexist in the same directory.
For example, a fictional webapp called "mywebapp" from that has two
EJBs and a struts UI for editing them:

   ejbs            # EJB Java files and partial deployment descriptors
               # Image interface
           # ImageBean implementation
           # ImageHome interface
                Image.ejb          # <entity> for Image
                # User interface
            # UserBean implementation
            # UserHome interface
                User.ejb           # <entity> for User
                User-Image.ejb     # <relationship> between User and Image
                 # Struts Action that initiates
editing an Image (i.e. from a listing)
                    ImageEdit.jsp              # edit Image info
                    ImageListing.jsp           # lists all images available,
allows for clicking to edit
               # Struts Action that updates an
Image from an ImageForm
                       # Struts ActionForm with Image
                    Image-struts-config.xml    # Actions and forms related to
                  # Struts Action that initiates
editing a User (i.e. from a listing)
                    UserEdit.jsp               # edit User info; links to Image

                    UserListing.jsp            # lists all Users available,
allows for clicking to edit
                # Struts Action that updates an
User from an UserForm
                        # Struts ActionForm with User
                    User-struts-config.xml     # Actions and forms related to
    global_resources           # global resources
        images                 # context images
            logo.gif           # a logo picture
            Drew.gif           # my picture, which should be included in any
    jsp                        # global JSP copied into context root of webapp
        index.jsp              # index page
        wrapper.jsp            # page wrapper for all pages on the site
        footer.jsp             # footer for all pages on the site
        web.xml                # Application deployment descriptor
    properties     # testing parameters (i.e. database url, login)  # deployment parameters

Building the above application would do the following:
    1) compile all code under ejbs and ui into WEB-INF/classes
    2) combine all .ejb files into mywebapp.ejb and put this under WEB-INF (see
note below)
    3) combine all *-struts-config.xml files into struts-config.xml under
    4) copy all files under jsp to context root (preserving sub-directory
    5) copy all files under global_resources to context root (preserving
sub-directory structure)
    6) copy web.xml to WEB-INF (see note below)

note: web.xml and ejbs are filtered through properties stored at the top level
"properties" directory.  This allows you to store variant deployment options
and munge your web.xml and ejb files to fit the deployment database
configurations and servlet parameters.

The final webapp would be built to the staging area and result in the following

        web.xml                     # copied from meta
        struts-config.xml           # combines all *-struts-config.xml files
from source directories
        mywebapp.ejb                # combines all *.ejb files from source

Having your applications organized like this reduces the amount of flailing
around you do trying to find related files.  It also keeps things functionally
structured so that you have model code (EJBs) and UI code (Struts, .jsps)

Anyway that's just my opinion.  I could be wrong.

- Drew

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message