Skip Headers

Oracle® Application Server Containers for J2EE Support for JavaServer Pages Developer's Guide 10g Release 3 (10.1.3) Part No. B14430-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# 7 Working with Custom Tags

This chapter discusses custom tags and tag libraries, covering the basic framework that vendors can use to provide their own libraries. There is also discussion of Oracle extensions and a comparison of standard runtime tags versus vendor-specific compile-time tags. The chapter consists of the following sections:

- What Are Custom Tags?

- Working with Tag Handlers

- OC4J Tag Handler Features

- Working with Tag Files

- Sharing Tag Libraries Across Web Applications

The chapter offers a detailed overview of tag library functionality. For complete information, refer to the Sun Microsystems JavaServer Pages Specification. For information about the tag libraries provided with OC4J, see the Oracle Containers for J2EE JSP Tag Libraries and Utilities Reference.

A multitude of resources are available for learning how to write and implement custom tags. For information beyond what is provided here, refer to the following resources:

- JavaServer Pages Specification, version 2.0 from Sun Microsystems

- Sun Microsystems Javadoc for the `javax.servlet.jsp.tagext` package, at the following Web site:

    http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/jsp/tagext /package-summary.html

## 7.1 What Are Custom Tags?

Custom tags, also known as tag extensions, are JSP elements that allow custom logic and output provided by other Java components to be inserted into JSP pages. The logic provided through a custom tag is implemented by a Java object known as a tag handler. When OC4J encounters a custom tag in a JSP during translation, it generates code to obtain and interact with the tag handler. Custom tags are included in a JSP page using XML syntax. Tags may or may not contain a body. Tags can also contain XML attributes that match properties in the corresponding tag handler.

With the advent of JSP 2.0, you now have two options for creating custom tags:

- Tag handlers

  Tags that require the creation of tag handler classes come in two types: Classic and simple.

  Classic tag handlers have been available since JSP 1.1. Classic tags are considered somewhat cumbersome to write, in part because of the complexity of the Java interfaces used to implement each tag's corresponding tag handler class. They are also dependent on Java expressions for dynamic attribute values. However, these tag handlers are the only option if Java scriplets or expressions must be used in the tag body

  Simple tag handlers are new in JSP 2.0, and offer a much simpler lifecycle and interface than classic tag handlers. Tag bodies accept JSP expression language (EL) expressions, allowing completely script-free tag development.

- Tag files

  Also new in JSP 2.0, tag files are revolutionary in that they allow tag libraries to be implemented completely in JSP or XML syntax, without the need to create and compile tag handler classes. Instead, tag files are translated into simple tag handlers by the OC4J JSP container and then compiled. Because of their ease of implementation, tag files offer an attractive alternative to writing tag handlers.

Related tag handlers or tag files can be packaged together in a tag library. Libraries developed as tag handlers must include an XML document known as a tag library descriptor (TLD) that describes the syntax of each tag and maps the tag to its corresponding handler class. Tag file libraries do not technically require a TLD, although descriptors are required if the library will be packaged as an archive for deployment.

The types of custom tags you create will depend on your needs. Tags that use either a classic or a simple tag handler are ideal when the flexibility of the Java language is required. Tag files are useful when creating tags that are presentation-centric or that take advantage of existing tag libraries, such as the JSTL.

### 7.1.1 Available Tag Libraries

Oracle provides extensive tag libraries with OC4J and other components. See the Oracle Containers for J2EE JSP Tag Libraries and Utilities Reference for details on available Oracle tag libraries.

Additional tag libraries are available from vendors and organizations. For example, the Jakarta Taglibs includes a wide selection of libraries available for download from `http://jakarta.apache.org/taglibs/`.

Note: The JSTL distribution is no longer installed in the `ORACLE_HOME/j2ee/home/jsp/lib/taglib` directory within OC4J. See "Sharing Tag Libraries Across Web Applications" for instructions on sharing tag libraries across deployed Web applications.

### 7.1.2 When Should You Co nsider Creating/Using Custom Tag Libraries?

Custom tags offer a number of benefits, including cleaner JSP code and code reusability. Some situations make creating and/or using custom tags almost mandatory. In particular, consider the following situations:

- JSP pages would otherwise have to include a significant amount of Java logic regarding presentation and format of output.

- Convenient JSP programming access to functionality that would otherwise require the use of a Java API is needed.

- Special manipulation or redirection of JSP output is required.

#### 7.1.2.1 Eliminating Extensive Java Logic

Because JSP developers might not be experienced in Java programming, they might not be ideal candidates for coding Java logic in the page—logic that dictates presentation and format of the JSP output, for example.

This is a situation where JSP tag libraries might be helpful. If many of your JSP pages will require such logic in generating their output, a tag library to replace Java logic would be a great convenience for JSP developers.

#### 7.1.2.2 Providing Convenient JSP Programming Access to API Features

Instead of having Web application programmers rely on Java APIs for using product functionality or extensions from servlets or JSP scriptlets, you can provide a tag library. A tag library can make the programmer's task much more convenient, with appropriate API calls being handled automatically by the tag handlers.

For example, tags as well as JavaBeans are provided with OC4J for e-mail and file access functionality. There is also a tag library as well as a Java API provided with the OC4J Web Object Cache. Similarly, while Oracle Application Server Personalization provides a Java API, OC4J also provides a tag library that you can use instead if you want to program a personalization application.

#### 7.1.2.3 Manipulating or Redirecting JSP Output

Another common situation for custom tags is if special runtime processing of the response output is required. Perhaps the desired functionality requires an extra processing step, or redirection of the output to somewhere other than the browser.

For example, you can create a custom tag - `<cust:log>` - that will redirect the tag text into a log file instead of to a browser:

    <cust:log>
       Text to log.
       More text to log.
       Yet more text to log.
    </cust:log>

## 7.2 Working with Tag Handlers

The following sections describe tag handlers, which define the semantics of actions that result from the use of custom tags:

- What Are Classic Tag Handlers?

- What Are Simple Tag Handlers?

- Attribute Handling and Conversions from String Values in Tag Handlers

- Implementing a Tag Handler

- Disabling or Enabling Tag Handler Reuse (Tag Pooling)

- Tag Handler Code Generation

### 7.2.1 What Are Classic Tag Handlers?

A classic tag handler is an instance of a Java class that directly or indirectly implements the standard `javax.servlet.jsp.tagext.Tag` interface. Although often regarded as somewhat complicated to write, classic tag handlers are your only option if Java scriplets or expressions must be used in the tag body or attribute values.

#### 7.2.1.1 Classic Tag Handler Interfaces

Depending on whether there is a tag body and how that body is to be processed, the tag handler implements one of the following interfaces, in the `javax.servlet.jsp.tagext` package:

- `Tag`: This interface defines the basic methods for all tag processing, but does not include tag body processing.

- `IterationTag`: This interface extends `Tag` and is for iterating through a tag body.

- `BodyTag`: This interface extends `IterationTag` and is for accessing the tag body content itself.

A classic tag handler class might implement one of these interfaces directly, or might extend a class (such as one of the support classes provided by Sun Microsystems) that implements one of them.

A tag handler, as applicable, supports parameter-passing, evaluation of the tag body, and access to other objects in the JSP page, including other tag handlers.

Note: The JSP specification does not mandate whether multiple uses of the same custom tag within a JSP page should use the same tag handler instance or different instances. This is left to the discretion of JSP vendors. See "OC4J Tag Handler Features" for information about the Oracle implementation.

#### 7.2.1.2 Custom Tag Processing, with or without Tag Bodies

A custom tag, as with a standard JSP tag, might or might not have a body. In the case of a custom tag, even when there is a body, its content might not have to be accessed by the tag handler.

There are four scenarios:

1. There is no body.

   In this case you need only a single tag, not a start-tag and end-tag. Following is a general example:

       <oracust:mytag attr="...", attr2="..." />

   This is equivalent to the following, which is also permissible:

       <oracust:mytag attr="...", attr2="..." ></oracust:abcdef>

   In this case, the tag handler should implement the `Tag` interface or extend `TagSupport`.

   The `<body-content>` setting for this tag in the TLD file should be `empty`.

2. There is a body; access to the body content by the tag handler is not required; the body is executed no more than once.

   In this case, there is a start-tag and an end-tag with a body of statements in between, but the tag handler does not process the body. Body statements are passed through for normal JSP processing only. Following is a general example of this scenario:

       <foo:if cond="<%= ... %>" >
       ...body executed if cond is true, but body content not accessed by tag handler...
       </foo:if>

   In this case, the tag handler should implement the `Tag` interface.

   The `<body-content>` setting for this tag in the TLD file should be `JSP` (the default) or `tagdependent`, depending on whether the body content should be translated or treated as template data, respectively.

3. There is a body; access of the body content by the tag handler is not required; the body is executed multiple times (iterated).

   This is the same as the second scenario, except there is iterative processing of the tag body.

       <foo:myiteratetag ... >
       ...body executed multiple times, according to attribute or other settings, but body content not accessed by tag handler...
       </foo:myiteratetag>

   In this case, the tag handler should implement the `IterationTag` interface.

   The `<body-content>` setting for this tag in the TLD file should be `JSP` (the default) or `tagdependent`, depending on whether the body content should be translated or treated as template data, respectively.

4. There is a body that must be processed by the tag handler.

   Again, there is a start-tag and an end-tag with a body of statements in between; however, the tag handler must access the body content.

       <oracust:mybodytag attr="...", attr2="..." >
       ...body accessed and processed by tag handler...
       </oracust:mybodytag>

   In this case, the tag handler should implement the `BodyTag` interface.

   The `<body-content>` setting for this tag in the TLD file should be `JSP` (the default) or `tagdependent`, depending on whether the body content should be translated or treated as template data, respectively.

#### 7.2.1.3 Tag Handlers That Access Body Content

For a custom tag with body content that the tag handler must be able to access, the tag handler class can implement the following standard interface:

- `javax.servlet.jsp.tagext.BodyTag`

The following standard support class implements the `BodyTag` interface, as well as the `java.io.Serializable` interface, and can be used as a base class:

- `javax.servlet.jsp.tagext.BodyTagSupport`

This class implements appropriate methods from the `Tag`, `IterationTag`, and `BodyTag` interfaces.

Note: In most cases, you should not use the `BodyTag` interface (or `BodyTagSupport` class) if your tag handler does not actually require access to the body content. This would result in the needless overhead of creating and maintaining a `BodyContent` object. Depending on whether iteration through the body is required, use the `Tag` interface or the `IterationTag` interface (or `TagSupport` class) instead.

The `BodyTag` interface inherits basic tag-handling functionality from the `Tag` interface, including the `doStartTag()` and `doEndTag()` methods and their defined return values. It also inherits functionality from the `IterationTag` interface, including the `doAfterBody()` method and its defined return values.

Along with its inherited features, the `BodyTag` interface adds functionality to capture execution results from the tag body. Evaluation of a tag body is encapsulated in an instance of the `javax.servlet.jsp.tagext.BodyContent` class. The page implementation object creates this instance as appropriate.

As with the `Tag` interface, the `doStartTag()` method specified in the `BodyTag` interface supports `int` return values of `SKIP_BODY` and `EVAL_BODY_INCLUDE`. For `BodyTag`, this method also supports an `int` return value of `EVAL_BODY_BUFFERED`. To summarize the meanings:

- `SKIP_BODY`: Do not evaluate the body.

- `EVAL_BODY_INCLUDE`: Evaluate the body and pass it through to the JSP `out` object without the body content being made available to the tag handler. This is essentially the same behavior as in an `EVAL_BODY_INCLUDE` scenario with a tag handler that implements the `IterationTag` interface.

- `EVAL_BODY_BUFFERED`: Create a `BodyContent` object for processing of the tag body content.

The `BodyTag` interface also adds definitions for the following methods:

- `setBodyContent()`: Set the `bodyContent` property (a `BodyContent` instance) of the tag handler.

- `doInitBody()`: Prepare to evaluate the tag body.

These steps occur before the tag body is evaluated. While the body is evaluated, the JSP `out` object will be bound to the `BodyContent` object.

After each evaluation of the body, as for tag handlers implementing the `IterationTag` interface, the page implementation instance calls the tag handler `doAfterBody()` method. This involves the following possible return values:

- `SKIP_BODY`: Stop iterating; do not reevaluate the tag body. Call `doEndTag()` instead. The JSP `out` object is restored from the page context.

- `EVAL_BODY_AGAIN`: Continue iterating; reevaluate the tag body. When the body is evaluated, it is passed through to the current JSP `out` object. After the body is evaluated, the `doAfterBody()` method is called again.

Once evaluation of the body is complete, for however many iterations are appropriate, the page implementation instance invokes the tag handler `doEndTag()` method.

For tag handlers implementing the `BodyTag` interface, evaluation results from the tag body are made accessible to the tag handler through an instance of the `javax.servlet.jsp.tagext.BodyContent` class. This class extends the `javax.servlet.jsp.JspWriter` class.

A `BodyContent` instance is created through the `pushBody()` method of the JSP page context.

Typical uses for a `BodyContent` object include the following:

- Convert its contents into a `String` instance and then use the string as a value for an operation.

- Write its contents into the JSP `out` object that was active as of when the start-tag was encountered.

### 7.2.2 What Are Simple Tag Handlers?

A new feature of JSP 2.0, simple tag handlers provide as much power as classic tag handlers, but are much easier to implement due to a much simpler Java interface and a more straightforward lifecycle.

Unlike classic tag handlers, simple tag handler objects are never cached and reused by the OC4J JSP container. Instead, an object is instantiated, executed and then discarded. There are no complicated caching semantics when using this interface since nothing is cached or reused. This simplified lifecycle helps make writing tag handlers easier and less prone to error.

Note that while this discussion focuses on implementing simple tag handlers as Java classes, simple tags can also be implemented completely in JSP syntax using tag files. See "Working with Tag Files" for details. However, this option is only viable if the flexibility of Java is not required.

#### 7.2.2.1 The SimpleTag Interface

Simple tag handler classes implement a single interface, `javax.servlet.jsp.tagext.SimpleTag`. The interface includes only one lifecycle method, `doTag()`. All iteration, body evaluation and other tag processing is performed within this method.

Ideally, your simple tag handler classes should extend the `javax.servlet.jsp.tagext.SimpleTagSupport` utility class, which implements the `SimpleTag` interface and provides a default implementation for the interface's methods. For example, this class provides `getJspBody()`, which returns the tag body passed to the handler.

Evaluation of the tag body is performed by the `setJspBody()` method, which is invoked by the OC4J JSP container with a `JspFragment` object encapsulating the body of the tag invocation. (See "Using JSP Fragments" for a discussion on JSP fragments.) The tag handler can call the `invoke()` method on the `JspFragment` to evaluate the body as many times as needed. This ability to be invoked and evaluated multiple times is a key feature of fragments.

Unlike classic tags, simple tag extensions do not rely on the `PageContext` of the calling JSP page's underlying servlet, but instead rely on `JspContext`, which `PageContext` now extends. `JspContext` provides generic services such as storing the `JspWriter` and keeping track of scoped attributes, while PageContext has functionality specific to serving JSPs in the context of servlets. Through these objects, a simple tag handler can retrieve the other implicit objects (`request`, `session` and `application`) available from a JSP page.

#### 7.2.2.2 Using Attributes

As with classic tags, the behavior of simple tags can be controlled through attributes that correspond to properties of the tag handler class.

There are three types of attributes: simple, fragment and dynamic.

Simple attributes are first evaluated by the OC4J JSP container when the tag is invoked, before being passed to the simple tag handler. Attributes are defined within the start tag using the syntax `attr="value"`. You can set the value as a `String` constant or an EL expression.

You can also define an attribute value within the body of a custom tag using the `<jsp:attribute>` element, a new element introduced in JSP 2.0. The following example uses `<jsp:attribute>` to use the output of the `<my:helloWorld>` custom tag to set the value of the `bar` property in a bean object:

    <jsp:setProperty name="foo" property="bar">   <jsp:attribute name="value">      <my:helloWorld/>   </jsp:attribute></jsp:setProperty>

Fragment attributes are used to create named fragments. See "Using JSP Fragments" for an overview on JSP fragments.

As its name implies, a dynamic attribute is an attribute not specified in the tag definition. The ability of a tag to dynamically specify attributes is a new feature of JSP 2.0 that is applicable to both simple and classic tag handlers. Dynamic attributes are especially useful in tags that have a number of attributes that are all processed in a similar manner.

Tag handlers that support dynamic attributes must declare that they do so in the `tag` element of the TLD. For example:

    <tag>
      <description>
       Tag that echoes all its attributes and body content
      </description>
      <name>echoAttributes</name>
      <tag-class>jsp2.examples.simpletag.EchoAttributesTag</tag-class>
      <body-content>empty</body-content>
      <dynamic-attributes>true</dynamic-attributes>
    </tag>

### 7.2.3 Attribute Handling and Conversions from String Values in Tag Handlers

A tag handler class has an underlying property for each attribute of the custom tag. These properties are analogous to JavaBean properties, with at least a setter method.

Recall that there are two approaches in setting a tag attribute:

- The first approach is where the attribute is a non-request-time attribute, set using a string literal value:

      nrtattr="string"

  For a non-request-time attribute, if the underlying tag handler property is not of type `String`, the Web container will try to convert the string value to a value of the appropriate type.

  Because tag attributes correspond to bean-like properties, their processing, such as for these type conversions from string values, is similar to that of bean properties. See "Bean Property Conversions from String Values".

- The second approach is where the attribute is a request-time attribute that is set using a request-time expression:

      rtattr="<%=expression%>"

  or:

      rtattr="${ELexpression}"

  FOr request-time attributes, there is no conversion. A request-time expression can be assigned to the attribute, and to its corresponding tag handler property, for any property type. This would apply to a tag attribute whose type is user-defined, for example.

### 7.2.4 Using Scripting Variables in Tags

Objects that are defined explicitly in a custom tag can be referenced in other actions through the JSP page context, using the object ID as a handle. Consider the following example:

    <oracust:foo id="myobj" attr="..." attr2="..." />

This statement results in the object `myobj` being available to scripting elements in the page, according to the declared scope of `myobj`. The `id` attribute is a translation-time attribute. You can specify a variable in one of two ways:

- Provide a `<variable>` element for the variable in the TLD file, to specify the name and type of the variable along with additional information. See "Variable Declaration Through TLD variable Elements".

- Create a tag-extra-info class, to specify the name and type of the variable along with additional information and related logic. Specify the tag-extra-info class name in a `<tei-class>` element in the TLD file. See "Variable Declaration Through Tag-Extra-Info Classes".

Generally, the more convenient `<variable>` mechanism will suffice.

The Web container enters `myobj` into the page context, where it can later be obtained by other tags or scripting elements using syntax such as the following:

    <oracust:bar ref="myobj" />

The `myobj` object is passed through the tag handler instances for the `foo` and `bar` tags. All that is required is knowledge of the name of the object (`myobj`).

Note: In the example, `id` and `ref` are merely sample attribute names; there are no special predefined semantics for these attribute names. It is up to the tag handler to define attribute names and create and retrieve objects in the page context.

#### 7.2.4.1 Scripting Variable Scopes

Specify the scope of a scripting variable in the `<variable>` element or tag-extra-info class of the tag that creates the variable. It can be one of the following `int` constants:

- `NESTED`: Use this setting for the scripting variable to be available between the start-tag and end-tag of the action that defines it.

- `AT_BEGIN`: Use this setting for the scripting variable to be available from the start-tag to the end of the page.

- `AT_END`: Use this setting for the scripting variable to be available from the end-tag to the end of the page

#### 7.2.4.2 Variable Declaration Through TLD va riable Elements

The JSP 1.1 specification mandated that use of a scripting variable for a custom tag requires the creation of a `tag-extra-info` (TEI) class. See "Variable Declaration Through Tag-Extra-Info Classes". The JSP1.2 specification, however, introduced a simpler mechanism—a `<variable>` element in the TLD file where the associated tag is defined. This is sufficient for most cases, where logic related to the variable is simple enough to not require use of a TEI class.

The `<variable>` element is a subelement under the `<tag>` element that defines the tag that uses the variable.

You can specify the name of the variable in one of two ways:

- Use a `<name-given>` subelement under `<variable>` to specify the variable name directly.

or:

- Use a `<name-from-attribute>` subelement under `<variable>` to specify a tag attribute whose value, at translation-time, will specify the variable name.

Along with `<name-given>` and `<name-from-attribute>`, the `<variable>` element has the following subelements:

- The `<variable-class>` element specifies the class of the variable. The default is `java.lang.String`.

- The `<declare>` element specifies whether the variable is to be a newly declared variable, in which case the JSP translator will declare it. The default is `true`. If `false`, then the variable is assumed to have been declared earlier in the JSP page through a standard mechanism such as a `jsp:useBean` action, a JSP scriptlet, a JSP declaration, or some custom action.

- The `<scope>` element specifies the scope of the variable: `NESTED`, `AT_BEGIN`, or `AT_END`, as described in "Scripting Variable Scopes". The default is `NESTED`.

Here is an example that declares two scripting variables for a tag `myaction`. Note that details within the `<tag>` element that are not directly relevant to this discussion are omitted:

    <tag>
       <name>myaction</name>
       ...
       <attribute>
         <name>attr2</name>
         <required>true</required>
       </attribute>
       <variable>
          <name-given>foo_given</name-given>
          <declare>false</declare>
          <scope>AT_BEGIN</scope>
       </variable>
       <variable>
          <name-from-attribute>attr2</name-from-attribute>
          <variable-class>java.lang.Integer</variable-class>
       </variable>
    </tag>

The name of the first variable is hard-coded as `foo_given`. By default, it is of type `String`. It is not to be newly declared, so is assumed to exist already, and its scope is from the start-tag to the end of the page.

The name of the second variable is according to the setting of the required `attr2` attribute. It is of type `Integer`. By default, it is to be newly declared and its scope is `NESTED`, between the `myaction` start-tag and end-tag.

#### 7.2.4.3 Variable Declaration Through Tag-Ext ra-Info Classes

For a scripting variable with associated logic that is at least somewhat complicated, the use of a `<variable>` element in the TLD file to declare the variable might be insufficient. In this case, you can specify details regarding the scripting variable in a subclass of the `javax.servlet.jsp.tagext.TagExtraInfo` abstract class. This manual refers to such a subclass as a tag-extra-info class. Tag-extra-info classes support additional validation of tag attributes and provide additional information about scripting variables to the JSP runtime.

The Web container uses tag-extra-info instances during translation. The TLD file specifies any tag-extra-info classes to use for scripting variables of a given tag. Use `<tei-class>` elements, as in the following example:

    <tag>
      <name>loop</name>
      <tag-class>examples.ExampleLoopTag</tag-class>
      <tei-class>examples.ExampleLoopTagTEI</tei-class>
      <body-content>JSP</body-content>
      <description>for loop</description>
      <attribute>
         ...
      </attribute>
      ...
    </tag>

The following are related classes, also in the `javax.servlet.jsp.tagext` package:

- `TagData`: An instance of this class contains translation-time attribute value information for a tag instance.

- `VariableInfo`: Each instance of this class contains information about a scripting variable that is declared, created, or modified by a tag at runtime.

- `TagInfo`: An instance of this class contains information about the relevant tag. The class is instantiated from the TLD file and is available only at translation time. `TagInfo` has methods such as `getTagName()`, `getTagClassName()`, `getBodyContent()`, `getDisplayName()`, and `getInfoString()`.

You can refer to the following location for further information:

    http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/jsp/tagext/package-summary.html

Note: It is uncommon to use `TagInfo` instances in a tag-extra-info implementation, although it might be useful if you want to map a single tag-extra-info class to multiple tag libraries and TLD files, for example.

The following methods of the `TagExtraInfo` class are related:

- `boolean isValid(TagData data)`

  The JSP translator calls this method for translation-time validation of the tag attributes, passing it a `TagData` instance.

- `VariableInfo[] getVariableInfo(TagData data)`

  The JSP translator calls this method during translation, passing it a `TagData` instance. This method returns an array of `VariableInfo` instances, with one instance for each scripting variable the tag creates.

- `void setTagInfo(TagInfo info)`

  Calling this method sets a `TagInfo` instance as an attribute of the tag-extra-info class. This method is typically called by the Web container.

- `TagInfo getTagInfo()`

  Use this method to retrieve the `TagInfo` attribute of the tag-extra-info class, assuming the `TagInfo` attribute was previously set.

The tag-extra-info class constructs each `VariableInfo` instance with the following information regarding the scripting variable:

- Variable name

- Java type (not a primitive type)

- A boolean value indicating whether the variable is to be newly declared, in which case the JSP translator will declare it

- Variable scope

Important: As of the OC4J 9.0.4 implementation, you can have the `getVariableInfo()` method return either a fully qualified class name (FQCN) or a partially qualified class name (PQCN) for the Java type of the scripting variable. FQCNs were required in previous releases, and are still preferred to avoid confusion in case there are duplicate class names between packages. Primitive types are not supported.

### 7.2.5 Access to Outer Tag Handler Instances

Where nested custom tags are used, the tag handler instance of the nested tag has access to the tag handler instance of the outer tag, which might be useful in any processing and state management performed by the nested tag.

This functionality is supported through the static `findAncestorWithClass()` method of the `javax.servlet.jsp.tagext.TagSupport` class. Even though the outer tag handler instance is not named in the JSP page context, it is accessible because it is the closest enclosing instance of a given tag handler class.

Consider the following JSP code example:

    <foo:bar attr="abc" >
       <foo:bar2 />
    </foo:bar>

Within the code of the `bar2` tag handler class (class `Bar2Tag`, by convention), you can have a statement such as the following:

    Tag bartag = TagSupport.findAncestorWithClass(this, BarTag.class);

The `findAncestorWithClass()` method takes the following as input:

- The `this` object that is the class handler instance from which `findAncestorWithClass()` was called (a `Bar2Tag` instance in the example)

- The name of the `bar` tag handler class (presumed to be `BarTag` in the example), as a `java.lang.Class` instance

The `findAncestorWithClass()` method returns an instance of the appropriate tag handler class, in this case `BarTag`, as a `javax.servlet.jsp.tagext.Tag` instance.

It is useful for a `Bar2Tag` instance to have access to the outer `BarTag` instance in case the `Bar2Tag` needs the value of a `bar` tag attribute or needs to call a method on the `BarTag` instance.

### 7.2.6 Implementing a Tag Handler

Creating either a classic or simple tag handler implemented in Java consists of the following key steps:

- Write and compile the tag handler class

- Package the tag handler in a tag library

- Define the tag in the tag library descriptor (TLD)

Several examples of simple tag handler implementations are provided with the sample applications that you can download from the Oracle Technology Network (OTN) Web site. After downloading and deploying the sample applications on OC4J, open the tag handler Java source files to see how each is implemented.

#### 7.2.6.1 Creating the Tag Handler Class

Each custom tag has its own handler class. By convention, the name of the tag handler class for a tag `abc`, for example, is `AbcTag`.

Note that a tag handler class must have a public no-arguments constructor.

A tag handler instance is typically created by the JSP page implementation instance, by use of a zero-argument constructor, and is a server-side object used at request-time. The tag handler has properties that are set by the Web container, including the page context object for the JSP page that uses the custom tag, and a parent tag handler object if the use of this tag is nested within an outer tag.

#### 7.2.6.2 Defining the Tag in the TLD

Each tag that your tag handler implements must be defined in the tag library descriptor file packaged with the tag library containing the handler class. The tag definition in the TLD fulfills two roles:

- Defines the syntax of the tag

- Provides the mapping between the tag and its corresponding tag handler class

The following snippet is based on the definition for the `<my:shuffle>` tag from `shuffle.tld`, the descriptor for the library containing the `ShuffleSimpleTag` handler class. This handler is included with the "Random Tic-Tac-Toe" sample application, which illustrates simple tag handler features. You can download this application from the Oracle Technology Network Web site.

The format for the TLD is shown in the following example. All TLD files are required to begin with a root `<taglib>` element that specifies the XML schema used to describe the TLD and the JSP version:

    <taglib xmlns="http://java.sun.com/xml/ns/j2ee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"    version="2.0">  <tlib-version>1.0</tlib-version>  <short-name>SimpleTagLibrary</short-name>  <uri>/SimpleTagLibrary</uri>  <tag>
       ...
      </tag>
    </taglib>

Next is the definition for the `<my:shuffle>` tag, contained within a `<tag>` element:

    <tag>  <name>shuffle</name>   <tag-class>oracle.otnsamples.jsp20.simpletag.ShuffleSimpleTag</tag-class>   <body-content>empty</body-content>   <attribute>     <name>fragment1</name>     <required>true</required>     <fragment>true</fragment>   </attribute>
       <attribute>     <name>fragment2</name>     <required>true</required>     <fragment>true</fragment>   </attribute>   <attribute>     <name>fragment3</name>     <required>true</required>     <fragment>true</fragment>   </attribute>
    </tag>

The subelements of a `<tag>` element define the tag, as follows:

- The required `<name>` subelement specifies the name of the tag.

- The required `<tag-class>` subelement specifies the name of the corresponding tag handler class. See "Working with Tag Handlers" for information about tag handler classes.

- The `<body-content>` subelement indicates how the tag body (if any) should be processed.

- Each `<variable>` subelement (if any), with its further subelements, defines a scripting variable. See "Using Scripting Variables in Tags" for information about scripting variables. The `<variable>` element is for relatively uncomplicated situations, where the logic for the scripting variable does not require a tag-extra-info class. The variable name is specified through either the `<name-given>` subelement, to specify the name directly, or the `<name-from-attribute>` subelement, to specify the name of a tag attribute that specifies the variable name. There is also a `<variable-class>` subelement to specify the class of the variable, a `<scope>` subelement to specify the scope of the variable, and a `<declare>` subelement to specify whether the variable is to be newly defined. See "Variable Declaration Through TLD variable Elements" for more information. Another subelement under `<variable>` is an optional `<description>` element.

- Each `<tei-class>` subelement (if any) specifies the name of a `tag-extra-info` class that defines a scripting variable. This is for situations where declaring the variable through a `<variable>` element is not sufficient. See "Variable Declaration Through Tag-Extra-Info Classes" for more information.

- Each `<attribute>` subelement (if any), with its further subelements, provides information about a parameter that you can pass in when you use the custom tag - in this example, a named fragment. Subelements of `<attribute>` include the `<name>` element to specify the attribute name, the `<type>` element to optionally note the Java type of the attribute value, the `<required>` element to specify whether the attribute is required (default `false`), and the `<rtexprvalue>` element to specify whether the attribute can accept runtime expressions as values (default `false`). See the example and accompanying discussion below. Another subelement under `<attribute>` is an optional `<description>` element.

Notes: As of Oracle Application Server 10g (9.0.4), the OC4J JSP container ignores the `<type>` element. It is for informational use only, for anyone examining the TLD file. Additionally, note the following: For literal attribute values, where `<rtexprvalue>` specifies `false`, the `<type>` value (if any) should always be `java.lang.String`. When `<rtexprvalue>` specifies `true`, then the type of the tag handler property corresponding to this tag attribute determines what you should specify for the `<type>` value (if any).

#### 7.2.6.3 Declaring the Tag in a JSP Page

The tag library containing the tag handler is referenced in the file using a`<taglib>` directive. Note the prefix `<my:...>` which indicates that any tag including this prefix is defined in the corresponding TLD.

    <%@ taglib uri="/WEB-INF/shuffle.tld" prefix="my" %>

As first defined in the JSP 1.1 specification, the `taglib` directive of a JSP page can fully specify the name and physical location, within a WAR file structure, of the TLD file that defines a particular tag library, as in the following example:

    <%@ taglib uri="/WEB-INF/oracustomtags/tlds/mytld.tld" prefix="oracust" %>

Specify the location as application-relative by starting with "`/`" as in this example. See "Requesting a JSP Page" for discussion of application-relative syntax.

Be aware that the TLD file should be in the `/WEB-INF` directory or a subdirectory.

Alternatively, as also defined since the JSP 1.1 specification, the `taglib` directive can specify the name and application-relative physical location of a JAR file instead of a TLD file, where the JAR file contains a single tag library and the TLD file that defines it. In this scenario, the JSP 1.1 specification mandated that the TLD file must be located and named as follows in the JAR file:

    META-INF/taglib.tld

The JSP 1.1 specification also mandated that the JAR file must be located in the `/WEB-INF/lib` directory.

Here is an example of a `taglib` directive that specifies a tag library JAR file:

    <%@ taglib uri="/WEB-INF/lib/mytaglib.jar" prefix="oracust" %>

Also see "Packaging Multiple Tag Libraries and TLD Files in a JAR File" which describes a scenario for packaging tag libraries to be shared by multiple Web applications.

#### 7.2.6.4 Using the Tag in a JSP

The `<my:shuffle>` tag is used in the TictactoeManual.jsp page, which draws a "tic-tac-toe" table of three rows and three columns. Each column has a tile of a particular color, achieved by calling the `<my:tile>` tag with three different colored tiles, or images. The `<my:shuffle>` tag is used to wrap these calls. The tag handler randomly executes the three tile fragments, causing the colored tiles within each row to be shuffled each time the page is loaded.

    <my:shuffle>   <jsp:attribute name="fragment1">
         <tr>
           <my:shuffle>
             <jsp:attribute name="fragment1">
               <my:tile imageVal="../images/blue_plain.gif" />
              </jsp:attribute>
              <jsp:attribute name="fragment2">
                <my:tile imageVal="../images/yellow_plain.gif" />
           </jsp:attribute>
           <jsp:attribute name="fragment3">
             <my:tile imageVal="../images/pink_plain.gif" />
           </jsp:attribute>
             </my:shuffle>
          </tr>
        </jsp:attribute>
          ...
    </my:shuffle>

## 7.3 OC4J Tag Handler Features

This section describes OC4J JSP extended features for tag handler pooling and code generation size reduction. It covers the following topics:

- Disabling or Enabling Tag Handler Reuse (Tag Pooling)

- Tag Handler Code Generation

### 7.3.1 Disabling or Enabling Tag Handler Reuse (Tag Pooling)

To improve performance, you can specify that tag instances be reused within each JSP page. This functionality is often referred to as tag pooling.

As of Oracle Containers for J2EE Release 3 (10.1.3), a compile-time tag pooling model is supported. The logic and patterns of tag handler reuse is determined at compile-time, during translation of the JSP pages. This is an effective way to improve performance for an application with very large numbers of tags within the same page (hundreds of tags, for example).

Tag pooling in the OC4J JSP container is configured using the `tags_reuse_default` parameter. See "Summary of JSP Configuration Parameters" for further information on setting this parameter.

Note: The runtime tag pooling model - previously the default mechanism used - is deprecated in Oracle Containers for J2EE Release 3 (10.1.3).

#### 7.3.1.1 Enabling or Disabling the Compile-Time Model for Tag Handler Reuse

You can switch to the compile-time model for tag-handler reuse in one of two ways:

- Set the `tags_reuse_default` configuration parameter to `compiletime`.

Or:

- Set the `tags_reuse_default` configuration parameter to `compiletime_with_release`.

A `compiletime_with_release` setting results in the tag handler `release()` method being called between uses of the same tag handler within the same page. This method releases state information, with details according to the tag handler implementation.

If the tag handler is coded in such a way as to assume a release of state information between tag usages, for example, then a `compiletime_with_release` setting would be appropriate. If you are unsure about the implementation of the tag handler and about which compile-time setting to use, you might consider experimentation.

Notes: Remember to retranslate your JSP pages when switching between the `compiletime`, `compiletime_with_release` or `runtime` models for tag handler reuse. The page context `oracle.jsp.tags.reuse` attribute is ignored with a `tags_reuse_default` setting of `compiletime` or `compiletime_with_release`.

#### 7.3.1.2 When Can the Compile-Time Tag Pooling Model Be Used?

In conformance with the JSP 2.0 specification, a tag instance can only be reused when the set of attributes defined for the tag is identical from usage to usage. This restriction is applicable to both the `compiletime` and `compiletime-with-release` tag pooling models.

The following example uses the tags from the JSTL `core` library to illustrate tag instance reuse.

    <%@ taglib uri='http://java.sun.com/jstl/core' prefix='c' %>

    // New instance of c:forEach tag is created.
    // Note the inclusion of the "var" attribute.
    <c:forEach var='item' begin='2' end='10'>

    // New instance of c:out tag is created.
    <c:out value="foo"/>

    </c:forEach>

    <%out.println("****");%>

    // The first c:forEach tag instance cannot be reused, since the "var"
    // attribute does not exist. A new tag instance is therefore created.
    <c:forEach begin='1' end='10'>

    // The existing c:out tag instance is reused, as
    // the set of attributes is identical in both usages.
    <c:out value="bar"/>

#### 7.3.1.3 Code Pattern for the compiletime Tag Pooling Model

The following illustrates the code pattern for the default `compiletime` model for tag pooling.

          try {
            tag01.doStartTag();
            ...
            tag01.doEndTag();
            // reuse tag01 without calling release()
            tag01.doStartTag();
            ...
            tag01.doEndTag();
          }
          catch (Throwable e) {
            tag01.release();
          }

#### 7.3.1.4 Code Pattern for the compiletime-with-release Tag Pooling Model

The following illustrates the code pattern for the `compiletime-with-release` option, which calls the `release()` method on the tag handler object between uses of the same tag handler within the same JSP.

          try {
            tag01.setPageContext(pageContext);
            tag01.doStartTag();
            ...
            tag01.doEndTag();
            tag01.release();
            // reuse tag01 with calling release()
            tag01.doStartTag();
            ...        tag01.doEndTag();
            tag01.release();
          }
          catch (Throwable e) {
            tag01.release();
          }

### 7.3.2 Tag Handler Code Generation

The Oracle JSP implementation reduces the code generation size for custom tag usage. In addition, there is a JSP configuration flag, `reduce_tag_code`, that you can set to `true` for even further size reduction.

Be aware, however, that when this flag is enabled, the code generation pattern does not maximize tag handler reuse. Although you can still improve performance by setting `tags_reuse_default` to `true` as described in "Disabling or Enabling Tag Handler Reuse (Tag Pooling)", the effect is not maximized when `reduce_tag_code` is also `true`.

## 7.4 Working with Tag Files

The following sections provide an overview and understanding of tag files:

- What Are Tag Files?

- Tag Body Processing

- Using Attributes in Tag Files

- Exposing Data through Variables in Tag Files

- Using JSP Fragments

- Implementing a Tag File

### 7.4.1 What Are Tag Files?

Introduced with JSP 2.0, tag files allow JSP authors to create custom tag libraries completely using JSP syntax, without requiring any knowledge of Java. In fact, writing a tag file is just like writing a JSP, with a few differences. Because of their ease of implementation, tag files offer an attractive alternative to traditional custom tag handlers.

The source for a tag file is simply a text file containing a reusable fragment of JSP code. Valid content that can be used in a tag file include:

- Standard JSP actions (such as `<jsp:useBean>`)

- Custom tags

- JSTL tags

- EL expressions or functions

- Template text

Unlike traditional custom tags, tag files do not require a corresponding tag handler class; instead each file is translated and compiled into a simple tag handler by the OC4J JSP container. Tag files effectively remove the need for Java programming, opening tag library creation to JSP authors who do not possess a strong working knowledge of Java.

Standard JSP directives are used in a tag file to provide processing instructions, just as in a JSP page. The one exception is the `page` directive, which cannot be used. Instead, tag files use the `tag` directive, which includes attributes specific to tag file processing.

Additional directives, such as `attribute` and `variable`, can only be used in tag files. "Using Attributes in Tag Files" and "Exposing Data through Variables in Tag Files" for details.

### 7.4.2 Tag Body Processing

How the body of a custom tag is processed is defined in the `body-content` attribute of the corresponding tag file's `tag` directive. The default value is `scriptless`, indicating that any of the JSP or static text elements listed above can be used in the tag body - although as the value infers, Java scripting elements are not allowed. Tags that do not accept a tag body should be declared as `empty`, as shown below:

    <%@ tag body-content="empty" %>

The tag's body is evaluated by the `<jsp:doBody>` standard action, which can only be used within tag files. Any dynamic JSP elements in the tag body are called, and the output they produce is mixed with template text in the body in the evaluation result.

The result is saved in a variable, which can be named using either the `var` or `varReader` attributes of the `<jsp:doBody>` tag. The `var` attribute captures the result as a `String` and should be sufficient for most usage scenarios.

The `varReader` attribute is used to capture the result as a `java.io.Reader` object, which may be more efficient when combined with a standard or custom tag, or with an EL function that reads its input from a `Reader`. If no variable is specified, the output is sent to the implicit `JspWriter` object.

As noted in the discussion of the SimpleTag interface, the body of the tag invocation is translated to a `JspFragment` object, which is then passed to the tag handler for processing. In this case, the value of `text` is displayed in bold and italic fonts in a Web browser. Fragments are very useful in the context of tag files, as discussed in "Using Attributes in Tag Files" below.

### 7.4.3 Using Attributes in Tag Files

Attributes are declared directly within tag files using `attribute` directives. In the example below, the `required` attribute is set to `true`, meaning that the page author must specify a value for this attribute when a tag element body passed in, or an error will be returned. The default value is false.

    <%@ attribute name="category" required="true" %>

As with classic and simple tag handlers, it is also possible to use undeclared dynamic attributes in a tag file. This is done by setting the `dynamic-attributes` attribute of the tag directive to the name of a Map containing the names and values of the dynamic attributes passed during tag invocation. The Map must contain each dynamic attribute name and value as a key/value pair.

    <%@ tag body-content="scriptless" dynamic-attributes="dynattrs" %>

### 7.4.4 Exposing Data through Variables in Tag Files

Variables are also declared directly within the tag file using the `variable` directive, which is analogous to the `<variable>` element used to declare variables used by a tag handler in a TLD. The name-given attribute specifies the variable's name and the variable-class attribute defines its type.

    <%@ variable name-given="current" variable-class="java.lang.Object" scope="NESTED" %>

As with tag handlers, the variable directive's scope attribute accepts one of three values, which control where the calling JSP sees the variable: AT_BEGIN, AT_END, or NESTED.

Tag files have access to a local page scope, which is distinct from the page scope of the calling JSP. The use of different scopes prevents confusion between the calling page and the tag file if they use the same names for page scope variables. In many cases, you may want to allow variable names to be specified by the calling JSP using an attribute supplied in a tag body, rather than hard-coding names in the tag file.

    <%@ variable name-from-attribute="var" alias="current" variable-class="java.lang.Object" scope="NESTED" %>

Here, the `name-from-attribute` and `alias` attributes are used instead of the `name-given` attribute used in the previous example. The`name-from-attribute` value is the name of the tag attribute providing the variable name.

The `alias` attribute value declares the name of the tag file's local page scope variable, which the OC4J JSP container copies to the calling JSP's page scope. This attribute is needed because the page author can assign any name for the variable in a custom tag, but a fixed name - the alias - must be used when developing the tag file.

### 7.4.5 Using JSP Fragments

A JSP fragment can be thought of as a template used to produce customized content. Introduced with JSP 2.0, JSP fragments are a new option for use with simple tag extensions, and as such are relevant for both tag files simple tag handlers. However, creating a fragment is typically done within the context of a tag file.

Like a tag file, a fragment is an encapsulation of dynamic JSP elements - such as standard JSP action tags, custom tags or EL expressions - and optionally static template text that is passed to a simple tag handler through a tag invocation.

A fragment can be invoked and evaluated by the tag handler zero or more times, as needed. Because the JSP elements within the fragment have access to the current values of all scoped variables, the result will typically be different from invocation to invocation. These qualities make fragments ideal for:

- Displaying conditional data or template text

- Displaying a set of data in an iteration

#### 7.4.5.1 Creating a JSP Fragment

Creating a named fragment for use in a tag file can be thought of as a two step process: You must declare the fragment within the tag file, then define its body within a `<jsp:attribute>` standard action tag inside the body of a custom tag.

You declare the fragment in the tag file using an `attribute` directive. Setting the directive's `fragment` attribute to `true` will cause the fragment to be evaluated by the tag handler. The default setting of `false` forces the attribute to be evaluated by the OC4J JSP container before being passed to the tag handler; hence the fragment's ability to be evaluated "zero or more times".

    <%@ attribute name="frag1" fragment="true" %><%@ attribute name="frag2" fragment="true" %>

You then define the associated logic within the tag file using JSP syntax. The following snippet from a tag file illustrates conditional logic implemented using JSTL tags. If the test evaluates true, `frag1` is invoked:

    <c:when test="${empRow[2] >= 10000}">   <c:set var="name" value="${empRow[0]}"/>   <c:set var="phone" value="${empRow[1]}"/>   <c:set var="salary" value="${empRow[2]}"/>   <jsp:invoke fragment="frag1"/></c:when>

The fragment is invoked by name using the `<jsp:invoke>` standard action tag within the tag file. Like `<jsp:doBody>`, this action can only be used within tag files. The scoped variables within the tag body - in this case EL constructs - are set by the tag file, allowing the tag file code to customize the fragment each time it is invoked.

The fragment content, which as noted previously can consist of JSP elements and static HTML, is defined within the body of a `<jsp:attribute>` standard action tag within the body of a custom tag.

    <tags:EmpDetails deptNum="80">
     <jsp:attribute name="fragment1">
       <tr bgcolor="#FFFF99" align="center">
        <td><font color="#CC0033">${name}</font></td>
        <td><font color="#CC0033">${phone}</font></td>
        <td><font color="#CC0033">${salary}</font></td>
       </tr>
      </jsp:attribute>
    </tags:EmpDetails>

#### 7.4.5.2 A Tag File Example

The following is a simple example illustrating the use of the `var` attribute to store the result of a tag body evaluation.

The sample `doBodyVarTest.tag` file defines a variable named `text` that will store the result of evaluating the body of the `<tags:doBodyVarTest>` tag in `Example.jsp`. It also defines two fragment attributes—`frag1` and `frag2`—that will store the result of an EL variable evaluation.

When a tag file is executed, the Web container passes it two types of fragments: fragment attributes and the tag body. Within the tag file, the `<jsp:invoke>` element is used to evaluate a fragment attribute, while the `<jsp:doBody>` element is used to evaluate a tag file body. The result of evaluating either type of fragment is sent to the response or is stored in an EL variable for later manipulation.

    <%@ attribute name="frag1" required="true" fragment="true" %>
    <%@ attribute name="frag2" required="true" fragment="true" %>
    <%@ variable name-given="text" scope="NESTED" %>
     <jsp:doBody var="text" />
      <TABLE border="0">
       <TR>
        <TD>
         <b><jsp:invoke fragment="frag1"/></b>
        </TD>
       </TR>
       <TR>
        <TD>
         <i><jsp:invoke fragment="frag2"/></i>
        </TD>
       </TR>
      </TABLE>

The `Example.jsp` code creates an instance of the `doBodyVarTest` tag. Note the `<jsp:body>` tag, which contains a string that will be set by the tag handler into the `text` variable. The `<jsp:body>` tag is used to explicitly specify the body of a simple tag, and is the only option for specifying a tag body when one or more `<jsp:attribute>` elements appear in the body of a tag invocation.

    <%@ taglib tagdir="/WEB-INF/tags" prefix="tags" %>

    <html>
     <body>
      <tags:doBodyVarTest>
       <jsp:attribute name="frag1">
        ${text}
       </jsp:attribute>
       <jsp:attribute name="frag2">
        ${text}
       </jsp:attribute>
       <jsp:body>
        Have a great day!
       </jsp:body>
      </tags:doBodyVarTest>
     </body>
    </html>

### 7.4.6 Implementing a Tag File

The process for implementing a tag library as tag files is straightforward: You need only to write the tag files as outlined in this chapter.

#### 7.4.6.1 Creating the Tag File

As noted earlier in this chapter, writing a tag file is very similar to writing a JSP. See "What Are Tag Files?" for a summary of elements that can be included in a tag file.

Be aware that tag files in your JAR file remain as uncompiled tag files, meaning that your code can be viewed by anyone with a text editor.

#### 7.4.6.2 Packaging Tag Files

Tag files can be deployed in one of two ways:

- Drop the tags directly into a `/WEB-INF/tags` directory within an application's directory structure

  When deployed in this manner, tag files do not require a tag library descriptor. However, the tags will only be accessible to the single application, unless you copy the tags to the `/WEB-INF/tags` directory for each application.

- They can be packaged in a JAR file

  Packaging tag files in this manner requires a TLD. Any tag files within the JAR that are not defined in the TLD are ignored by the OC4J JSP container.

When packaged in a JAR, tag files are added under the `/META-INF/tags` within the JAR. The JAR will then be installed in the `/WEB-INF/lib/` directory of a Web application.

Each tag file in the JAR is defined in the TLD within a `<tag-file>` element, as opposed to the `<tag>` element used to define classic or simple tag handlers. Each `<tag-file>` element takes two sub-elements:

- The `<name>` element defines the tag name and must be unique

- The `<path>` element specifies the full path of the tag file and must therefore begin with `/META-INF/tags`

The example below shows a TLD defining two tag files packaged in a JAR for distribution:

    <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd"
       version="2.0">
      <tlib-version>1.0</tlib-version>
      <short-name>MyTagFiles</short-name
      <uri>/MyTagFiles</uri>
      <description>JSP 2.0 tag files</description>
      <tlib-version>1.0</tlib-version>
      <short-name>My Tag Files</short-name>
      <tag-file>
        <name>EmpDetails</name>
        <path>/META-INF/tags/mytags/EmpDetails.tag</path>
      </tag-file>
      <tag-file>
        <name>ProductDetails</name>
        <path>/META-INF/tags/mytags/ProductDetails.tag</path>
      </tag-file>
    </taglib

#### 7.4.6.3 Declaring the Tag File in a JSP

A JSP page imports a tag library implemented with tag files using the `taglib` directive. The tag library prefix is specified using the `prefix` attribute. However, the other attributes included vary depending on how the tag files are deployed.

If the tag files are not packaged in a JAR, the value of the `tagdir` attribute must be set to the context-relative path to the directory that contains the tag files.

    <%@ taglib tagdir="/WEB-INF/tags/mytags" prefix="mytags" %>

If the tag files are packaged in a JAR, the `uri` attribute is used, and is set to the content of the `<uri>` element in the TLD.

    <%@ taglib uri="/MyTagFiles" prefix="mytags" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

## 7.5 Sharing Tag Libraries Across Web Applications

The following sections discuss the packaging, placement, and access of tag libraries and their TLD files:

- Packaging Multiple Tag Libraries and TLD Files in a JAR File

- Specifying Well-Known Tag Library Locations

- Enabling the TLD Caching Feature

### 7.5.1 Packa ging Multiple Tag Libraries and TLD Files in a JAR File

The JSP specification allows the packaging of multiple tag libraries, and the TLD files that define them, in a single JAR file.

This section presents an example of multiple tag libraries packaged in a single JAR file. The JAR file includes tag handler classes, `tag-library-validator` (TLV) classes, and TLD files for multiple libraries.

The following lists the contents and structure of the JAR file. Note that in a JAR file with multiple TLD files, the TLD files must be located under the `/META-INF` directory or a subdirectory.

    examples/BasicTagParent.class
    examples/ExampleLoopTag.class
    examples/BasicTagChild.class
    examples/BasicTagTLV.class
    examples/TagElemFilter.class
    examples/TagFilter.class
    examples/XMLViewTag.class
    examples/XMLViewTagTLV.class
    META-INF/xmlview.tld
    META-INF/exampletag.tld
    META-INF/basic.tld
    META-INF/MANIFEST.MF

A JAR file with multiple TLD files must be placed in the `/WEB-INF/lib` directory or in an OC4J "well-known" tag library location as described in "Specifying Well-Known Tag Library Locations". During translation, the JSP container searches these two locations for JAR files, searches each JAR file for TLD files, and accesses each TLD file to find its `<uri>` element.

#### 7.5.1.1 Key TLD File Entries

In each TLD file, there is a `<uri>` element under the root `<taglib>` element. Use this feature as follows:

- The `<uri>` element must specify a value that is to be matched by the `uri` setting of a `taglib` directive in any JSP page that wants to use the corresponding tag library.

- To avoid unintended results, each `<uri>` value should be unique across all `<uri>` values in all TLD files on the server.

The value of the `<uri>` element can be arbitrary; however, it must follow the XML namespace convention.I t is simply used as a key and does not indicate a physical location. By convention, however, its value is of the form of a physical location.

The `basic.tld` file includes the following:

    <taglib>

      <tlib-version>1.0</tlib-version>
      <jsp-version>2.0</jsp-version>
      <short-name>basic</short-name>
      <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/basic.tld</uri>

      ...

    </taglib>

The `exampletag.tld` file includes the following:

    <taglib>

      <tlib-version>1.0</tlib-version>
      <jsp-version>2.0</jsp-version>
      <short-name>example</short-name>
      <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/exampletag.tld</uri>

      ...

    </taglib>

The `xmlview.tld` file includes the following:

    <taglib>
      ...
      <tlib-version>1.0</tlib-version>
      <jsp-version>1.2</jsp-version>
      <short-name>demo</short-name>
      <uri>http://xmlns.oracle.com/j2ee/jsp/tld/demos/xmlview.tld</uri>
      ...
    </taglib

#### 7.5.1.2 Key web.xml Deployment Descriptor Entries

This section shows the `<taglib>` elements of the `web.xml` deployment descriptor. These map the full URI values, as seen in the `<uri>` elements of the TLD files in the previous section, to shortcut URI values used in the JSP pages that access these libraries.

The `<taglib>` element can include two subelements:

- `<taglib-uri>`

  Contains the shortcut URI that will be used as the value of the `uri` attribute in the `taglib` directive in JSP pages that use the tag.

- `<taglib-location>`

  Contains the unique identifier for the tag library. In this case, the `<taglib-location>` value actually indicates a key, not a location, and corresponds to the `<uri>` value in the TLD file of the desired tag library.

For the scenario of an individual TLD file, or the scenario of a JAR file that contains a single tag library and its TLD file, the `<taglib-location>` subelement indicates the application-relative physical location (by starting with "`/`") of the TLD file or tag library JAR file. See "Specifying Well-Known Tag Library Locations" for related information.

For the scenario of a JAR file that contains multiple tag libraries and their TLD files, a `<taglib-location>` subelement indicates the unique identifier of a tag library. In this case, the `<taglib-location>` value actually indicates a key, not a location, and corresponds to the `<uri>` value in the TLD file of the desired tag library. See "Packaging Multiple Tag Libraries and TLD Files in a JAR File" for related information.

    <taglib>
      <taglib-uri>/oraloop</taglib-uri>
      <taglib-location>http://xmlns.oracle.com/j2ee/jsp/tld/demos/exampletag.tld
      </taglib-location>
    </taglib>
    <taglib>
      <taglib-uri>/orabasic</taglib-uri>
      <taglib-location>
         http://xmlns.oracle.com/j2ee/jsp/tld/demos/basic.tld
      </taglib-location>
    </taglib>
    <taglib>
      <taglib-uri>/oraxmlview</taglib-uri>
      <taglib-location>
         http://xmlns.oracle.com/j2ee/jsp/tld/demos/xmlview.tld
      </taglib-location>
    </taglib>

#### 7.5.1.3 JSP Page taglib Directives for Multiple-Library Example

This section shows the appropriate `taglib` directives, which reference the shortcut URI values defined in the `web.xml` elements listed in the preceding section.

The page `basic1.jsp` includes the following directive:

    <%@ taglib prefix="basic" uri="/orabasic" %>

The page `exampletag.jsp` includes the following directive:

    <%@ taglib prefix="example" uri="/oraloop" %>

The page `xmlview.jsp` includes the following directive:

    <%@ taglib prefix="demo" uri="/oraxmlview" %>

### 7.5.2 Specifying Well-Known Tag Library Locations

As an extension of the standard "well-known URI" functionality described in the JSP specification, OC4J supports the use of one or more directories, known as well-known tag library locations, where you can place tag library JAR files that will be shared across multiple Web applications.

The default well-known tag library location is the `ORACLE_HOME/j2ee/home/jsp/lib/taglib/` directory. A tag library installed in this location will be available by default to all Web applications deployed to the OC4J instance.

You can also define additional shared tag library locations, and install tag library JAR files to be shared across applications in these directories. Defining a well-known tag library location is a two-step process:

1. Define each directory in the `jsp-taglib-locations` attribute of the of the `<orion-web-app>` element in the `ORACLE_HOME/j2ee/home/config/global-web-application.xml` file. Separate each location with a semicolon.

2. Add a `<library>` element for each directory to `ORACLE_HOME/j2ee/home/config/application.xml`, the configuration file for the `default` application. Set the `path` attribute to the directory containing the tag library JAR file.

Important: The ability to specify and utilize multiple shared tag library locations is determined by the value of the `jsp-cache-tlds` attribute of the `<orion-web-app>` element. See Table 7-1, "TLD Caching Parameters" for details.

### 7.5.3 Enabling the TLD Caching Feature

As part of its support for sharing tag libraries, OC4J provides a persistent caching feature for TLD files. This includes a global cache for TLD files in any well-known tag library locations, as well as an application-level cache for any application that uses TLD caching.

The use of TLD caching speeds performance at application startup and during JSP page translation. You might turn it off, however, if either of the following circumstances are true:

- Your application does not use tag libraries.

- You have pre-translated the JSP pages and none of the TLD files use `<listener>` elements for tag library event listeners.

TLD caching is enabled or disabled through the `jsp-cache-tlds` attribute of the `<orion-web-app>` element.

- At the global level, TLD caching is set through this attribute in the `global-web-application.xml` file, the Web configuration file for the global Web application. The value set in this file is the default inherited by all other Web applications deployed to the OC4J instance.

- At the application level, caching is set in the application-specific `orion-web.xml` file. The setting in this file overrides the default setting in `global-web-application.xml`.

The following table summarizes the values for the `jsp-cache-tlds` attribute.

Table 7-1 TLD Caching Parameters

Value of jsp-cache- tlds | Value set in global-web-application.xml
--- | ---
`standard` | TLD caching is enabled. This is the default setting at the global and application level. Add tag library JARs to the default well-known tag library location, which is `ORACLE_HOME/j2ee/home/jsp/lib/taglib`. The tag libraries will be available to all Web applications. Note that TLD (`*.tld`) files must be placed in the `/WEB-INF` directory. Do NOT put TLD files in the `/classes` or `/lib` subdirectories.
`on` | TLD caching is enabled. Add JAR files containing tag libraries to one of the following: The default well-known tag library location, which is `ORACLE_HOME/j2ee/home/jsp/lib/taglib`. An additional location specified in the `jsp-taglib-locations` attribute of the `<orion-web-app>` element in `global-web-application.xml`. See "Specifying Well-Known Tag Library Locations" for details on specifying additional locations.
`off` | TLD caching is disabled. Add tag library JARs to the default well-known tag library location only, which is `ORACLE_HOME/j2ee/home/jsp/lib/taglib`. A different location can be specified as the value of the `well_known_taglib_loc` initialization parameter in `ORACLE_HOME/j2ee/home/config/global-web-application.xml`. Initialization parameters are specified within `<init-param>` subelements of `<servlet>jsp</servlet>` notation in this file. See "Setting JSP Parameters in the XML Configuration Files" for details.

Important: If a TLD file is present both in the well-known location and under the `/WEB-INF` directory of an application, the `/WEB-INF` copy takes precedence and is used. If TLD files with the same URI value are present in or under the `/WEB-INF` directory and also in a JAR file in the `/WEB-INF/lib` directory, the decision of which one to use is indeterminate. Avoid this situation.

#### 7.5.3.1 Understanding the TLD Cache Features and Files

For any application that uses TLD caching, whether it is enabled at the global or application level, there are two levels of caching, and two aspects of caching at each level.

Caching levels:

- There is a global cache for TLD files that are in JAR files in any well-known tag library locations.

- There is an application-level cache for TLD files under the application `/WEB-INF` directory.

  At the application level, tag library JAR files, which include TLD files, must be in the `/WEB-INF/lib` directory.

  Individual TLD files can be directly in `/WEB-INF` or in any subdirectory, but preferably not in `/WEB-INF/lib` or `/WEB-INF/classes`. If the `jsp-cache-tlds` attribute of the `<orion-web-app>` element is set to `standard`, TLDs must NOT be placed in either `/WEB-INF/lib` or `/WEB-INF/classes`.

Caching aspects at each level:

- There is a file containing resource information for the relevant location—the well-known location for the global cache, or `/WEB-INF` or `/WEB-INF/lib` for the application-level cache. Because of this feature, JAR files do not have to be scanned more than once. The file contains two types of entries:

  - There is a list of all resources (tag library JAR files) that includes a timestamp for each resource so that any change to any resource can be detected. There is also an indication ("`true`" or "`false`") of whether each resource includes a TLD file.

  - There is a list of TLD files, where each entry consists of a TLD name, TLD URI value if present, and tag library listeners if present.

- There is a serialized DOM representation of each TLD file. Because of this feature, TLD files do not have to be parsed more than once.

The global cache is always located in a directory called `tldcache`, parallel to the configuration directory. The `tldcache` directory contains the following:

- A file, `_GlobalTldCache`, that contains resource information, as described above, for any well-known locations.

- DOM representations of the TLD files that are in well-known locations. For each TLD file that is in a JAR file in a well-known location, the DOM representation is in a subdirectory according to the name of the JAR file, with a file name according to the name of the TLD file. For example, if `email.tld` is found in `ojsputil.jar` in a well-known location, then its DOM representation would be in the following file (file name `email` in directory `ojsputil_jar`):

      ORACLE_HOME/j2ee/home/jsp/lib/taglib/persistence/ojsputil_jar/email

  This is for an Oracle Application Server environment, where `ORACLE_HOME` is defined. In OC4J standalone, the `j2ee` directory is relative to where OC4J is installed.

The application-level cache is in the directory indicated by the `jsp-cache-directory` setting in either `global-web-application.xml` or `orion-web.xml`. This directory contains the following:

- There is a file, `_TldCache`, that contains resource information, as described above, for TLD files under the `/WEB-INF` directory—either in JAR files in `/WEB-INF/lib`, or individually in `/WEB-INF` or any subdirectory, but preferably not `/WEB-INF/lib` or `/WEB-INF/classes`.

  If the `jsp-cache-tlds` attribute of the `<orion-web-app>` element is set to `standard`, TLDs must NOT be placed in either `/WEB-INF/lib` or `/WEB-INF/classes`.

- There are DOM representations of the TLD files under `/WEB-INF`. For TLD files that are in JAR files in the `/WEB-INF/lib` directory, the DOM representations go into subdirectories under the directory indicated by `jsp-cache-directory`, in the same type of scheme as described for the global cache. For individual TLD files under `/WEB-INF`, the DOM representations go directly in the `jsp-cache-directory` location.

  Notes: TLD changes at the global level are reflected only after OC4J is restarted. TLD changes at the application level are reflected immediately in an OC4J standalone environment, but only after the application is restarted in an Oracle Application Server environment. You can increase the OC4J verbosity level to see information regarding construction of TLD caches and regarding any TLD URIs that are duplicated. Level 4 provides some information; level 5 provides additional information. The default level is 3.