4
votes

I recently upgraded from Apache Tomcat 6.X to 7.X to 8.0.12. I am currently able to compile and run my application in tomcat 8; however, my ant task for pre-compiling jsps is no longer working. The strange thing is that if I switch back to tomcat 7 without making any other changes the JspC call will work!

Here is the error output from the ant task:

Sep 17, 2014 4:01:23 PM org.apache.jasper.servlet.TldScanner scanJars
    INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
    java.lang.NullPointerException
        at org.apache.jasper.compiler.TldCache.getTaglibXml(TldCache.java:97)
        at org.apache.jasper.compiler.TagLibraryInfoImpl.(TagLibraryInfoImpl.java:179)
        at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:411)
        at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:469)
        at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1428)
        at org.apache.jasper.compiler.Parser.parse(Parser.java:139)
        at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:227)
        at org.apache.jasper.compiler.ParserController.parse(ParserController.java:100)
        at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:199)
        at org.apache.jasper.compiler.Compiler.compile(Compiler.java:356)
        at org.apache.jasper.JspC.processFile(JspC.java:1217)
        at org.apache.jasper.JspC.execute(JspC.java:1368)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
        at sun.reflect.GeneratedMethodAccessor7.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:435)
        at org.apache.tools.ant.Target.performTasks(Target.java:456)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
        at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
        at org.eclipse.ant.internal.launching.remote.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:36)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
        at org.eclipse.ant.internal.launching.remote.InternalAntRunner.run(InternalAntRunner.java:452)
        at org.eclipse.ant.internal.launching.remote.InternalAntRunner.main(InternalAntRunner.java:139)

Here is the ant task:

<target name="jspc-tomcat" depends="compile" description="compile jsps using tomcat jspc">
    <copy overwrite="false" file="${webxml.dir}/web.xml" tofile="web/WEB-INF/web.xml" />

    <jasper
        uriroot="web"
        outputDir="${build.dir}/JSP/src" />

    <delete file="web/WEB-INF/web.xml"/>
</target>
<target name="compile-jsps" depends="jspc-tomcat" description="compile jsps using apache tomcat">
    <mkdir dir="${build.dir}/JSP/classes"/>
    <mkdir dir="${build.dir}/JSP/lib"/>
    <javac memoryInitialSize="128m" memoryMaximumSize="512m" destdir="${build.dir}/JSP/classes"
        optimize="off" fork="true"
        debug="on" failonerror="false" source="1.8" target="1.8"
        srcdir="${build.dir}/JSP/src" includeantruntime="false"
        excludes="**/*.smap">
        <classpath>
            <fileset dir="${local.ctx1.home}/lib">
                <include name="*.jar"/>
            </fileset>
            <fileset dir="${local.ctx1.home}/bin">
                <include name="*.jar"/>
            </fileset>
            <pathelement path="${rade2.class.dir}" />
            <path refid="compile_classpath" />
        </classpath>
        <include name="**" />
        <exclude name="tags/**" />
    </javac>
</target>

I've tried playing with the taglibs and making sure they are all declared correctly. So far as I can tell, they are. I'm unable to interpret the cause of the NullPointerException coming from TldCache.java. Has anyone else experienced this or have any ideas on possible solutions?

1
Can you edit the file under ${catalina.home}/conf/logging.properties setting org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = FINE, Restart TOMCAT and then post the error message? This should tell you which JAR is missing those TLDs mentioned.Arty
There are quite a few JARs included in the build path that do not include TLDs. My understanding is that I can specify to exclude them from being searched for TLDs in order to speed up the compilation and tomcat startup time, but that allowing them to be searched should not be a problem. You do bring up a good point: I could try to exclude all of these JARs to see if that would prevent the error. I will have to try that today. I still believe it should be able to compile the JSPs regardless of including JARs without TLDs in the build path. Are my assumptions correct or have I misunderstood?Ben Arena
I was able to eliminate the TLD error on server startup by adding a JarScanner with defaultTldScan="false" to the tomcat server context.xml, but this did not affect my compilation error or the TLD INFO message posted during JSP compilation. I also tried adding the setting tomcat.util.scan.StandardJarScanFilter.jarsToSkip to the logging.properties file, but it did not appear to have any effect on either server startup or the ant task compilation.Ben Arena

1 Answers

2
votes

I found that I had a .tld file defined in my WEB-INF/tags directory, which is explicitly excluded in the ant target. Removing the exclusion from the ant target did not work, so I moved the .tld definition to /WEB-INF/jsps. I also had to restore my definition of the jasper taskdef, which I had changed to be imported from catalina-ant.xml per Apache's documentation.

In summary, moved .tld from WEB-INF/tags to WEB-INF/jsps and added a jasper taskdef in ant.

The final ant task is as follows:

<target name="jspc-tomcat" depends="compile"
 description="compile jsps using tomcat jspc">
    <copy overwrite="false" file="${webxml.dir}/web.xml"
        tofile="web/WEB-INF/web.xml" />
    <taskdef classname="org.apache.jasper.JspC" name="jasper">
        <classpath id="jspc.classpath">
            <pathelement location="${java.home}/../lib/tools.jar"/>
            <fileset dir="${local.ctx1.home}/bin">
                <include name="*.jar"/>
            </fileset>
            <fileset dir="${local.ctx1.home}/lib">
                <include name="*.jar"/>
            </fileset>
            <pathelement path="${rade2.class.dir}" />
            <path refid="compile_classpath" />
        </classpath>
    </taskdef>

    <jasper
        uriroot="web"
        outputDir="${build.dir}/JSP/src" />

    <delete file="web/WEB-INF/web.xml"/>
</target>
<target name="compile-jsps" depends="jspc-tomcat" description="compile jsps using apache tomcat">
    <mkdir dir="${build.dir}/JSP/classes"/>
    <mkdir dir="${build.dir}/JSP/lib"/>
    <javac memoryInitialSize="128m" memoryMaximumSize="512m" destdir="${build.dir}/JSP/classes"
        optimize="off" fork="true"
        debug="on" failonerror="false" source="1.8" target="1.8"
        srcdir="${build.dir}/JSP/src" includeantruntime="false"
        excludes="**/*.smap">
        <classpath>
            <fileset dir="${local.ctx1.home}/lib">
                <include name="*.jar"/>
            </fileset>
            <fileset dir="${local.ctx1.home}/bin">
                <include name="*.jar"/>
            </fileset>
            <pathelement path="${rade2.class.dir}" />
            <path refid="compile_classpath" />
        </classpath>
        <include name="**" />
        <exclude name="tags/**" />
    </javac>
</target>