|
|
|
Contents: |
|
|
|
Related content: |
|
|
|
Subscriptions: |
|
|
| JAR your custom taglibs for safer, easier
distribution
Brett
McLaughlin (mailto:brett@oreilly.com?cc=&subject=Pack
'em up!) Author, O'Reilly and Associates 2 September 2003
Storing 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:
- Create a base directory for your taglibs called tag-libraries.
- In that directory, create a subdirectory called META-INF.
- Copy the TLD file you want from your Web application's WEB-INF/tlds
directory into this META-INF directory.
- 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 Brett 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. |
|
|