views:

494

answers:

2

When pre-compiling JSPs with the Jasper compiler (using Tomcat), and then the Java compiler I see javac warnings like this (I have javac's -Xlint flag enabled):

warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
_jspx_dependants.add("/some-jsp.jspf");

Now, it's "just a warning," but I like clean builds, so naturally I want to get rid of the warning. Sure, I could turn -Xlint off for JSP compilation, but -Xlint is good stuff, so it stays.

In this example warning, the problem is that generic syntax isn't used. Instead of List<String>, we have only List. I realize that the good folks who write Jasper have to cater to those unfortunate souls who remain locked in a pre-Java5 world. That's fine, but why should I have to suffer these warnings?

Is there some well-known way to eliminate javac warnings caused by the Java source code created by the Jasper JSP compiler? I'm not interested in an IDE-specific solution (though that would be a partial solution for some people who use the particular IDE). I'm looking for a generally applicable solution.

A scan of the Jasper source code didn't reveal any "Java 5+" switches that would cause generic syntax emission. In fact, on the contrary I found this:

apache-tomcat-6.0.18-src/java/org/apache/jasper/compiler/Generator.java:494:            out.printin("_jspx_dependants = new java.util.ArrayList(");

which clearly shows the hardcoded code bereft of any hope for injection of elegant generic syntax.

+1  A: 

Disable the warnings you know are there and don't care about with:

-Xlint:-xxx
Disable warning xxx, where xxx is one of the warning names supported for -Xlint:xxx, below.

See here.

Charlie Martin
This is a good idea, but suppose that my JSP code has a scriptlet that also generates that type of warning (I'm not a fan of scriptlet's, but let's just say there are some). I don't want to mask such warnings; I'd like to know about warnings in my code. Simply turning off, say, all unchecked warnings, seems like it might be too coarse of a solution in some cases.
Greg Mattes
Sure, but this example lets you turn off only specific warnings. You might need a lot of -Xlint:-nnn flags, but you'd see any unexpected warnings.
Charlie Martin
Maybe I'm not understanding, does your solution allow specific warning /instances/ to be elided, or *all* warnings of a /particular type/? Suppose that both my code and the generated Java code cause an "unchecked" warning. I want to elide the warning from the Jasper code, but I want to see the warning from my code. Can your solution express: "disable that one particular unchecked warning, but not other unchecked warnings?" I think that "-Xlint:-unchecked" will disable all warnings.
Greg Mattes
It turns off all instances of a particular warning for a particular compilation. So you can, if you want to, define your compilation scheme to compile individual files with specific settings. That slows it down since the compiler has some startup time, but gives you pretty fine grained control. I don't know of any way to make it more fine-grained than per file.
Charlie Martin
A: 

I'm using an Ant-based build. My current solution to this problem is to edit the offending Jasper generated Java code in-place with the following Ant filtering code:

<move todir="WEB-INF/src">
    <fileset dir="WEB-INF/src"/>
    <globmapper from="*.java"
                to="*.java.foo"/>
    <filterchain>
        <tokenfilter>
            <replacestring from="private static java.util.List _jspx_dependants;"
                           to="private static java.util.List&lt;String&gt; _jspx_dependants;"/>
            <replacestring from="_jspx_dependants = new java.util.ArrayList"
                           to="_jspx_dependants = new java.util.ArrayList&lt;String&gt;"/>
            <replaceregex pattern="public final class (.*) extends org.apache.jasper.runtime.HttpJspBase"
                          replace="@SuppressWarnings(&quot;serial&quot;)&#xA;public final class \1 extends org.apache.jasper.runtime.HttpJspBase"/>
            <replacestring from="(PageContext)_jspx_page_context"
                           to="_jspx_page_context"/>
        </tokenfilter>
    </filterchain>
</move>
<move todir="WEB-INF/src" overwrite="true">
    <fileset dir="WEB-INF/src"/>
    <globmapper from="*.java.foo" to="*.java"/>
</move>

Please see this question to understand the "double move."

Greg Mattes