Bizmarck
Bizmarck

Reputation: 2688

INFO: TLD skipped. URI: <tag name URI> is already defined

I have a web application that is being migrated from Tomcat 5.5.35 to Tomcat 7.0.39. Presently, there are several custom taglibs, each defined in its own tld file. Here is one example:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>customTag</short-name>
    <uri>http://www.something.com/util/customTag-db-taglib</uri>
    <description>
        Database tag library for Util 
    </description>
    <tag>
        <name>useBean</name>
        <tag-class>com.mx.releasemgr.tags.db.UseBeanTag</tag-class>
        <tei-class>com.mx.releasemgr.tags.db.UseBeanTEI</tei-class>
        <body-content>EMPTY</body-content>
        <attribute>
            <name>id</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>oid</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>oidParameter</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>type</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>scope</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
    ...
</taglib>

There is exactly ONE copy of this tld file in the WEB-INF folder. It was never put into a jar file.

The web.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
  xmlns="http://java.sun.com/xml/ns/javaee" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
...
<jsp-config>
     <taglib>
    <taglib-uri>customTag</taglib-uri>
    <taglib-location>/WEB-INF/customTag.tld</taglib-location>
</taglib>
</jsp-config>
...

This error is showing up in the catalina.out

Apr 11, 2013 3:50:08 PM org.apache.catalina.startup.TaglibUriRule body
INFO: TLD skipped. URI: http://www.mx.com/releasemgr/releasemgr-db-taglib is already defined

The taglib is imported like so:

<%@ taglib uri="customTag" prefix="db" %>

I have looked at this question but it does not seem to apply. I have added the <jsp-config>, it doesn't help. Am I calling the taglib wrong? Is the URI parameter correct? Any help is appreciated.

Upvotes: 1

Views: 2654

Answers (1)

Shi Lei
Shi Lei

Reputation: 120

Priority order of URIs required by spec is:

  1. J2EE platform taglibs - Tomcat doesn't provide these
  2. web.xml entries
  3. JARS in WEB-INF/lib & TLDs under WEB-INF (equal priority)
  4. Additional entries from the container

Your tld is loaded twice, the first is from web.xml, the second is from scan in WEB-INF and it's sub folders.

The solution is

1, remove it from web.xml

or

2, put your tld files in /WEB-INF/tags/


OK, this is just a short story. If you want to know more.

1, tomcat 5.5 has the same logic, it just does not do the annoying log.

2, This log happens when tomcat is starting. Loading tld when tomcat is staring is only for finding listeners in tld files.

3, It's another story when tld is really used in jsp.

When the first jsp is being compiled, tomcat will build a cache for uri and location pairs.

The uri loading is from the same order

1) web.xml entries, the tag uri is got from web.xml

2) scan tld files under WEB-INF, the tag uri is got from tld files

3) scan jars, the tag uri is got from tld files.

So in your config, customTag.tld is registered with 2 uri, customTag and http://www.mx.com/releasemgr/releasemgr-db-taglib

4) When tomcat is starting. It Loads tld to find listeners in tld files.

When loading from web.xml, it puts both customTag(from web.xml) and http://www.mx.com/releasemgr/releasemgr-db-taglib(from tld file) into a set.

When loading from WEB-INF, the uri is from tld file, which is ttp://www.mx.com/releasemgr/releasemgr-db-taglib. Tomcat needs to avoid duplicate tld listener adding, so it checks whether uri exists in the set. If uri already exists, it logs the message and skip adding tld listener.

Putting them together,

1, If there are no listeners in your tld files, no need to scan tld when Tomcat is starting. You can disable by setting processTlds to false in context.

When the first jsp is being compiled, tomcat will build a cache for uri and location pairs.

2, You can just ignore the warning. It's just for avoiding duplicate loading listeners in tld files.

Upvotes: 3

Related Questions