IBM Skip to main content
Search for:   within 
      Search help  
     IBM home  |  Products & services  |  Support & downloads   |  My account

developerWorks > Java technology | Web architecture
developerWorks
JSP best practices: Pack 'em up!
69 KBe-mail it!
Contents:
Why use JARs?
Creating a taglib directory
Creating a JAR file
Documentation and version control
Adding the manifest to your JAR
Creating the taglib URI
Wrapping up
Resources
About the author
Rate this article
Related content:
JSP best practices series
JSP taglibs: Better usability by design
Introduction to JSP technology
Subscriptions:
dW newsletters
dW Subscription
(CDs and downloads)
JAR your custom taglibs for safer, easier distribution

Level: Introductory

Brett McLaughlin (mailto:brett@oreilly.com?cc=&subject=Pack 'em up!)
Author, O'Reilly and Associates
2 September 2003

Column iconStoring your taglibs in a local filesystem is great for in-house development and testing, but it's not a good permanent solution. Custom taglibs should be widely accessible, which means they must be distributed in a standard and secure manner. Brett McLaughlin explains how to JAR your custom taglibs for easier maintenance, distribution, and installation in any JSP-compliant Web container.

So far in this series we've kept our custom taglibs in a local filesystem, where we could easily access and manipulate them. While local access is great for in-house development and testing, it's not a good permanent solution. The whole point of custom taglibs is that they should be widely accessible, which means they must be distributed in a standardized way that also allows for some essential security measures. In this installment of JSP best practices, you'll learn how to package your custom taglibs in a JAR file for safe and easy distribution.

Why use JARs?
Custom taglibs are inherently intended for distribution, whether that takes place within the rather small circle of a company development team, the wider circle of affiliate organizations, or the outside network of paying customers. In any of these cases, housing the taglib on your local filesystem and making it available from that location is a bad idea.

If your taglib is intended for use by an in-house development team, the first thing you want to think about upon releasing it is separation of responsibility. In JSP programming, it is ideal to have two teams working in parallel: Java developers to write the implementation detail and JSP page authors to deal with the front end. But experience has shown how quickly this separation breaks down if it isn't enforced. Housing your custom taglibs on a locally accessible filesystem sets up a situation where even good intentions -- such as a JSP page author "correcting" the TLD file or a Java programmer "tweaking" the HTML -- could wreak havoc with your development cycle, as well as the end product.

The situation becomes even more critical when you factor in remote parties such as outside companies and organizations. Any time you allow an outside party (such as an end user or page author) uncontrolled access to your code, you're inviting trouble. Suppose, for example, that a user from an outside company changes your TLD, or goofs up the tag class file. Not only will you very likely be blamed for the resulting errors, but chances are you won't be able to locate the individual who made the mistake. You'll spend twice the time you ought to debugging code that is essentially the result of a user error. And this type of mistake won't happen just once -- it'll be a recurring incident as long as you house your master taglib on a locally accessible filesystem.

Finally, let's consider what could happen if you decide to market and sell your custom taglibs. Decompiling classes is remarkably easy these days, which means that someone could easily purchase your code, alter it, and use it maliciously with your company's name attached. Or, they could simply repackage it and sell it as their own work. Neither scenario is a particularly good one. Obfuscating your code (which make decompiling binary code difficult, and often impossible) is one way to avoid malicious alteration or theft. Packaging your taglib into a single, discrete unit is also recommended.

The JSP specification allows us to use the Java platform's JAR facility for packaging custom taglibs. Once they are JARed, taglibs are available for broad distribution, maintenance, and installation. And, as you will see, JARing a taglib isn't all that hard to do.

Creating a taglib directory
The first step is to create a taglib directory structure like the one shown in Listing 1:

Listing 1. Directory structure for a taglib JAR

$basedir/
          META-INF/
     META-INF/site-utils.tld
     com/
     com/newInstance/
     com/newInstance/site/
     com/newInstance/site/tags/
     com/newInstance/site/tags/LastModifiedTag.class
     com/newInstance/site/tags/SSOSubmitTag.class
     com/newInstance/site/tags/CopyrightTag.class
     com/newInstance/site/utils/HTMLParser.class
     com/newInstance/site/utils/RegExp.class

You can create this directory structure in your own Web container as follows:

  1. Create a base directory for your taglibs called tag-libraries.
  2. In that directory, create a subdirectory called META-INF.
  3. Copy the TLD file you want from your Web application's WEB-INF/tlds directory into this META-INF directory.
  4. Copy the package structure you want from WEB-INF/classes into the base directory.

Be sure you only copy over the directories and classes that your tag library uses -- the last thing you want is to distribute your own Java classes along with your tags!

Creating a JAR file
The next step is to use the Java command jar to create a JAR file from your taglib directory structure, as shown in Listing 2:

Listing 2. Creating a JAR file

[legolas:tqag-libraries] bmclaugh% jar cvf newInstance-taglib_1-1.jar 
META-INF com
added manifest
adding: com/(in = 0) (out= 0)(stored 0%)
adding: com/newInstance/(in = 0) (out= 0)(stored 0%)
adding: com/newInstance/site/(in = 0) (out= 0)(stored 0%)
adding: com/newInstance/site/tags/(in = 0) (out= 0)(stored 0%)
adding: com/newInstance/site/tags/CopyrightTag.class(in = 980) 
               (out= 382)(deflated 39%)
adding: com/newInstance/site/tags/LastModifiedTag.class(in = 1488) 
               (out= 818)(deflated 45%)
adding: com/newInstance/site/tags/SSOSubmitTag.class(in = 2208) 
               (out= 1060)(deflated 48%)
adding: META-INF/(in = 0) (out= 0)(stored 0%)
adding: META-INF/site-utils.tld(in = 589) (out= 334)(deflated 43%)

The resulting JAR file can be passed around to whomever you like -- whether that be the page author down the hall or a company across the ocean.

Documentation and version control
An important part of creating any taglib is documentation -- you are documenting your code, right? -- and this is especially true when it comes to packaging taglibs for distribution. You've probably noticed that the above JAR includes the comment added manifest, which refers to a special type of file defined by the JAR specification. A manifest is a text file that has information about a JAR, and is always included in the same place within a JAR. If you want to know about the contents or functionality of a Java archive, the manifest is the first (and best) place to look.

In this case, the manifest includes a version identifier (VID), which lets you track revisions and upgrades between your work and the JAR files that end users or page authors have.

Listing 3 shows a simple manifest file for a tag library:

Listing 3. A simple manifest file

Name: com/newInstance/site/tags/
Sealed: true
Implementation-Title: "newInstance.com Site Utility Tag Library"
Implementation-Version: "1.1"
Implementation-Vendor: "Brett McLaughlin"

The above manifest defines the name of the Java package being distributed and specifies that the JAR file should be sealed. Sealing a file ensures that all classes in the com.newInstance.site.tags package must exist within the same JAR file. By extension, this prevents a user from creating his own classes, assigning them to the same package, and overriding or extending their functionality. Sealing is a good practice for ensuring consistency and versioning of your code.

Adding the manifest to your JAR
The last step is to provide a name, version, and provider for your taglib package. The info you provide will be easily accessible by any JAR tool, and will also make it easier for you to determine whether you need to upgrade the library for your users.

Listing 4 shows how to add a manifest to a JAR file on creation. The filename here is manifest.mf, but you can use any filename you choose.

Listing 4. Creating a JAR file with a manifest

[legolas:tqag-libraries] bmclaugh% jar cvfm
newInstance-taglib_1-1.jar manifest.mf META-INF com
added manifest
adding: com/(in = 0) (out= 0)(stored 0%)
adding: com/newInstance/(in = 0) (out= 0)(stored 0%)
adding: com/newInstance/site/(in = 0) (out= 0)(stored 0%)
adding: com/newInstance/site/tags/(in = 0) (out= 0)(stored 0%)
adding: com/newInstance/site/tags/CopyrightTag.class(in = 980) 
               (out= 382)(deflated 39%)
adding: com/newInstance/site/tags/LastModifiedTag.class(in = 1488) 
               (out= 818)(deflated 45%)
adding: com/newInstance/site/tags/SSOSubmitTag.class(in = 2208) 
              (out= 1060)(deflated 48%)
adding: META-INF/(in = 0) (out= 0)(stored 0%)
adding: META-INF/site-utils.tld(in = 589) (out= 334)(deflated 43%)

Creating the taglib URI
After you have your JAR file, you'll need to let page authors know how to link to it from their Web container. As with files in a filesystem, the easiest way to do this is to create a URI (universal resource identifier), which lives in a web.xml file. Listing 5 shows a web.xml entry for identifying a taglib:

Listing 5. Identifying a tag library in web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
   PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
          "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
   <taglib>
     <taglib-uri>
     http://www.newInstance.com/taglibs/site-utils
     </taglib-uri>
     <taglib-location>
     /WEB-INF/lib/newInstance-taglib_1-1.jar
     </taglib-location>
   </taglib>
</web-app>

As you probably noted, we've placed the JAR file in the target Web application's WEB-INF/lib directory. All JAR files used by a Web application should reside in this directory. Rather than making a reference to a TLD file on the filesystem, as we did before, the web.xml file now points to the JAR file that contains our taglib.

Wrapping up
With the simple steps outlined here we've moved our taglib out of the general filesystem and into the more controlled, distributable environment of a JAR file. Accessing a taglib in a JAR is identical to accessing one in a filesystem outside of a JAR: you simply specify the URI in a taglib directive, and get to work.

In the next several tips, we'll move beyond these JSP basics and look at some Web-specific JSP functionality. Covering subjects ranging from working with a database to handling dynamic navigation links, these tips will put some polish on your Java-based Web sites and Web applications.

Resources

About the author
Photo of Brett McLaughlinBrett McLaughlin has been working in computers since the Logo days (remember the little triangle?). He currently specializes in building application infrastructure using Java and Java-related technologies. He has spent the last several years implementing these infrastructures at Nextel Communications and Allegiance Telecom Inc. Brett is one of the co-founders of the Java Apache project Turbine, which builds a reusable component architecture for Web application development using Java servlets. He is also a contributor of the EJBoss project, an open source EJB application server, and Cocoon, an open source XML Web-publishing engine. Contact Brett at brett@oreilly.com.


69 KBe-mail it!

What do you think of this document?
Killer! (5) Good stuff (4) So-so; not bad (3) Needs work (2) Lame! (1)

Comments?



developerWorks > Java technology | Web architecture
developerWorks
  About IBM  |  Privacy  |  Terms of use  |  Contact