 | Level: Intermediate Tim deBoer, Software Developer , IBM Toronto Lab
12 Dec 2001 When using third-party or utility classes in J2EE applications, you have a variety of choices about where to store them. This article explores the advantages and disadvantages of each location, and describes the best way to make them available to other modules in the application. The article describes a development scenario using WebSphere Studio Application Developer, and includes a simple plug-in that can periodically zip up a Java project into a JAR file within another project.
© 2001 International Business Machines Corporation. All rights reserved. Introduction When developing applications within the J2EE framework, you
often need third-party or utility classes. You can store these classes in a
variety of locations so that they can be used by the rest of the modules in
the application. This article explores the advantages and disadvantages of each
location, and explains why these classes are usually packaged as JAR files and
placed in one of only two locations. If the same team that is developing the J2EE application is
also developing the utility classes, the next questionis how both sets of code
can be managed, built, and tested within the same workbench. Within WebSphere
Studio Application Developer, you can create the utility classes in a Java#x2122 project,
but how can these classes be periodically jarred up and placed in another location?
Since Application Developer is built on top of the highly extendable open-source
Eclipse project, this is not a problem. This article presents a simple plug-in
that you can use to periodically or automatically zip up a Java project into
a JAR file within another project. Note: The attached plug-in is not part of WebSphere
Studio Application Developer and is only provided as a sample of the extensible
nature of the product. It is not officially supported and you should read the
full license agreement before downloading. Use at your own risk.
Where should utility classes go? Exploring the application server and the J2EE specification
reveals five places where classes can be stored so that they can be found by
the modules within a J2EE application. Each of these locations is discussed
below, as well as whether each location is applicable to utility classes.
- As loose classes within a Web module's
WEB-INF/classes
folder. These classes are visible only within the same Web module, and this
is usually not a valid location because the classes may not have anything
to do with the Web module that contains them.
- As a JAR file within a Web module's
WEB-INF/lib
folder. This is a good place to put utility classes used by the Web module.
However, since these JAR files are only visible from within the Web module,
this is not a good place for JAR files that are used by multiple modules.
- As loose classes within an EJB module. Although these classes are visible
from within other modules that use a manifest file, this is also a weak solution,
because the utility classes may not have anything to do with the other code
contained in the EJB module.
- As JAR files or loose classes on the application server's global classpath.
This appears to be an easy solution, since it makes the utility classes visible
to any modules running on the server. However, you should avoid this technique
for four reasons.
- Portability - By placing the code outside of the application
server, these classes or JAR files must be copied along with the application.
This technique also requires changing the global classpath of each server
it is deployed to. Because each application server has different classloaders
and this falls outside the J2EE specification, each server type may require
these classes to be handled differently.
- Visibility - This technique makes the classes visible to all
applications running on the server. Even if the classes are only required
by a single application, other applications can inadvertently use them.
- Maintainability - This technique forces all applications running
on the server to use the same version of the classes. If one application
is upgraded to a newer version of the classes, all of the other applications
must be upgraded and/or retested.
- Compatibility - This technique does not let an application use
a different version of any classes that are used by the application server
or other applications.
- As a JAR file within the Ear application. These classes are visible to any
module within the application that is using a valid manifest file. This is
usually the best solution, as it keeps the classes packaged in their own JAR
file, which is usable by any modules within the application. This solution
does not suffer from any of the problems of using the global classpath.
For the reasons above, you should usually package utility
classes as JAR files and place them in the WEB-INF/lib folder, or more likely,
directly in the Enterprise Application. However, what happens if the same team
that is developing the J2EE application is also developing these classes? Inside
Application Developer, Java projects are used to create and build utility classes,
and it is awkward to continually zip up these projects and then import the JAR
file back into the EAR project. As the utility classes change within the Java
project, it's cumbersome to rebuild and maintain the EAR project so that testing
can continue. If work on the utility classes is just starting, then the
simplest solution is probably just to put the folder containing the compiled
classes on the global classpath of the application server (or perhaps ws.ext.dirs
in the case of WebSphere). This allows rapid development and may provide an
adequate temporary solution. However, as the classes mature, you should use
the JAR file approach for the reasons given above, and to ensure that your application
will continue to run correctly when deployed to a production server. As another solution, the rest of this article presents a simple
plug-in that you can use to automatically create and maintain a JAR file within
one project by zipping up the contents of another project. This can greatly
simplify the J2EE development process while staying within the bounds of the
J2EE specification.
A J2EE development scenario Figure 1 below shows a typical J2EE application, which consists
of an EAR, EJB, Web, and Java project. Both the Web and EJB projects need to
use utility classes, and these classes are currently being developed within
the Java project. Figure 1. A typical J2EE application

As discussed above, the best way for the EJB and Web projects
to use these classes is to create a JAR file within the EAR. By modifying the
manifest file of the EJB and Web projects, they can use the JAR file at run
time, and continue to be fully portable to any J2EE application server without
any additional steps. Figure 2 below shows the end result, with a JAR file created
in the EAR project. But how do you create and maintain the JAR file out of the
build directory of the Java project? If both the J2EE and Java projects are
being developed simultaneously, keeping these in sync can become a major problem. Figure 2. Using a JAR file from an EAR

The attached plug-in provides a builder that automatically
zips up the contents of the Java project's build directory whenever any classes
are added, modified, or removed. Once you tell it where to create the zip file,
development can continue and the utility JAR file will be kept in sync with
the contents of the Java project.
Installing the zip creation plug-in To install the zip file creation plug-in, following these
steps:
- Download zipCreation.zip below.
- Extract the download file into the
Application
Developer installation/plugins folder.
- Verify that a new
Application Developer installation/plugins/com.ibm.sample.zip.creation
folder has been created during the unzipping.
Using the zip creation plug-in To use the plug-in, take the following steps for each Java
project that should be zipped into a JAR file.
- From within the Navigator view, right-click on the Java project and select
Properties.
- Select Zip Creation from the list on the left side of the dialog.
- If you want zip file creation to be automatic, select Enable. This
will cause the zip file to be created each time the contents within the current
project change. If you don't want zip file creation to be automatic, right-click
on the project and select Update zip file(s) on the project's popup
menu whenever you want to update the zip file.
- Ensure that the Workspace option is selected and click Browse.
- Select the EAR project within the workbench. Click OK.
- Type a new filename in the Filename field. For example,
utility.jar.
- Your dialog should now be completed as shown in Figure 3 below. Click OK.
Figure 3. Zip creation properties

If you take a look in the EAR project, you will see a new
JAR file created. As you continue to make changes to the Java project, these
changes will be reflected in the JAR file. For each EJB or Web project that needs to use the JAR file,
you will need to update the manifest and the Java build classpath to use this
new JAR file. You can do both of these steps at the same time using the Edit
Module Dependencies dialog. Follow these steps.
- Right-click on the EJB or Web project, and select Edit Module Dependencies.
- Select
utility.jar from the checkbox list
as shown in Figure 4 below.
- Click OK.
Figure 4. Edit Module Dependencies dialog

To disable the zip file creation or change the settings, just
reopen the project's properties and change the options. This plug-in can be
used in many other cases, and is not limited to this scenario. You can also
create zip files outside of the workbench, and you can add other source folders,
to include source or other resources within the created zip file.
Conclusion By looking at the various places where utility files can be
used by a J2EE application, we found that it is usually best to put utility
classes in a JAR file in the WEB-INF/lib folder
or directly in the Enterprise application. If the utility classes are used by
multiple modules (or even a single EJB module), always use the Enterprise application.
We then described the unsupported zip creation plug-in as one solution to the
problem of co-developing utility classes and J2EE applications within the same team.
Questions from users Question 1
Really good article, but two problems:
- With Application Developer 5.0, when I installed the zip creation plug-in, it's impossible to view the zip creation function
after right-clicking on a Java project in the J2EE navigator view or elsewhere.
I can see the zip creation function only for Web and EJB modules. Is this a bug?
- In this article, we learned about how modules can see utility classes. But how do utility classes see each other?
Or, if you prefer, how does a utility class in one package use a utility class in another package?
Thank you for all of your teaching. -- Eric Response from author
- Sorry, but as explained in the instructions, the zip creation properties are available only via the resource Navigator.
- Do you mean within a single JAR, or between two JARs? At compile time, you can set up whatever you want by using the Java build path for
the project. At run time, within a single JAR, the regular Java visibility rules are followed.
With multiple JARs, utility classes can see each other by having a valid manifest file in the JAR that points to the other JAR. For
information on manifest files and how they work, see the JAR specification on the Javasoft site.
You can easily do this across projects, but you need to be careful, because anything outside the application and modules
will not be considered part of the EAR and may not be included when an EAR is exported.
Question 2
In the Web project, all of the classes are compiled to WEB-INF/classes. Do you recommend to JAR the classes and put them
in WEB-INF/lib? If so, does WebSphere Studio V5 also need to install the zip creation plug-in to JAR the classes? Response from author
All classes that you are actively developing as part of the Web project get compiled into WEB-INF/classes,
and that is the correct place for them. Third party JARs, or utility JARs used by the project, can just be dropped into
WEB-INF/lib. These are the standard locations defined in the J2EE spec.
If you are developing a utility JAR to be used by the Web project, then you can create a Java project to develop the contents.
If you are using WebSphere Studio V5.0 or later and you are going to run these in the WebSphere Test Environment,
then you can use the utility Java project support (see the online help) to map the project as if it were a JAR
contained within the Web project's WEB-INF/lib directory. Otherwise, you can periodically JAR the Java project up
and put it in WEB-INF/lib, or use the zip creation plug-in. Question 3
This JAR file is excellent -- very useful. However, for my purposes it lacks a couple of useful
features. I would like to:
- Automatically place source code into the JAR (as you can with the export/JAR file function).
- Make the update function available from the Package Explorer view.
- Place one JAR or ZIP file into another (I can do this, but there is no way I can see to dictate the order
in which the two files would be built).
- Get the source code for the plug-in.
Response from author
- You can include source in the JAR/ZIP file in one of two ways: either put the source
and compiled code in the same folder, or make use of the "source containers" option to add more folders into the JAR.
- Thanks for the suggestion -- the next time that I update the plug-in I will make it available
from the Package Explorer and other views.
- Sorry, but the plug-in doesn't have any built-in support for multiple levels of JAR building.
The only way that you would be able to make sure that this is working in the right order would be to turn off the automatic
JAR building and use the Update option to build each JAR in turn, each time they change.
- Sorry, but this plug-in was shipped as part of an IBM product, so I am not free to distribute the source code.
To see additional user comments, click the View results button above. Top of page
Download | Description | Name | Size | Download method |
|---|
| Code samples | zipCreation.zip | 50 KB | FTP | HTTP |
|---|
About the author  | 
|  | Tim deBoer is a software developer on the WebSphere Studio Application Developer,
Server Tools team at the IBM Toronto Lab. With his teammates, he is currently responsible for the WebSphere and Tomcat test environments
and the EJB test client. You can contact
Tim at deboer@ca.ibm.com. |
Rate this page
|  |