Bug 54461 - JSP compiler init parameter documented as "compiler", actually "compilerClassName"
JSP compiler init parameter documented as "compiler", actually "compilerClass...
Status: RESOLVED FIXED
Product: Tomcat 7
Classification: Unclassified
Component: Documentation
7.0.35
All All
: P2 major (vote)
: ---
Assigned To: Tomcat Developers Mailing List
:
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2013-01-22 03:03 UTC by Nick Williams
Modified: 2013-01-23 19:33 UTC (History)
0 users



Attachments
Added link in jasper howto to the documentation for Javac task (711 bytes, patch)
2013-01-22 21:04 UTC, Violeta Georgieva
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Williams 2013-01-22 03:03:35 UTC
This bug exists in Tomcat 6, Tomcat 7 and (presumably) Tomcat 8 (trunk).

See the documentation for JSP compilation:

http://tomcat.apache.org/tomcat-6.0-doc/jasper-howto.html
http://tomcat.apache.org/tomcat-7.0-doc/jasper-howto.html

There's a configuration option listed in this documentation:

compiler - Which compiler Ant should use to compile JSP pages. See the Ant documentation for more information. If the value is not set, then the default Eclipse JDT Java compiler will be used instead of using Ant. No default value.

This does not exist. Creating an init-param with this value has no effect. The correct init-param is "compilerClassName," not "compiler."

Related, this option is very poorly documented. There is no indication about what this value should be. Tried com.sun.tools.javac.Main and added tools.jar to the classpath, but got a class cast exception. It would be nice if this explained what the proper alternative values are.
Comment 1 Violeta Georgieva 2013-01-22 21:04:06 UTC
Created attachment 29884 [details]
Added link in jasper howto to the documentation for Javac task
Comment 2 Violeta Georgieva 2013-01-22 21:08:34 UTC
(In reply to comment #0)
> 
> This does not exist. Creating an init-param with this value has no effect.
> The correct init-param is "compilerClassName," not "compiler."

"compiler" and "compilerClassName" are not one and the same.
"compiler" is the correct init-param.

> Related, this option is very poorly documented. There is no indication about
> what this value should be. Tried com.sun.tools.javac.Main and added
> tools.jar to the classpath, but got a class cast exception. It would be nice
> if this explained what the proper alternative values are.

Check the Javac Task documentation [1] there you can find what values are acceptable for "compiler".

I added a link to the jasper howto document (see attachment).

Regards
Violeta

[1] http://ant.apache.org/manual/Tasks/javac.html
Comment 3 Nick Williams 2013-01-22 22:27:39 UTC
I tried the following variations of the compiler init parameter:

        <init-param>
            <param-name>compiler</param-name>
            <param-value>classic</param-value>
        </init-param>

        <init-param>
            <param-name>compiler</param-name>
            <param-value>modern</param-value>
        </init-param>

        <init-param>
            <param-name>compiler</param-name>
            <param-value>jikes</param-value>
        </init-param>

        <init-param>
            <param-name>compiler</param-name>
            <param-value>extJavac</param-value>
        </init-param>

And with each one, I simply got these warnings whenever the first JSP tried to compile:

Jan 22, 2013 3:37:59 PM org.apache.jasper.compiler.JDTCompiler generateClass
WARNING: Unknown source VM 1.8 ignored.
Jan 22, 2013 3:37:59 PM org.apache.jasper.compiler.JDTCompiler generateClass
WARNING: Unknown target VM 1.8 ignored.

It continued to use the Eclipse compiler. It occurred to me that maybe the "compiler" init parameter does not work without the "compilerClassName" parameter, and it appears that is correct.

        <init-param>
            <param-name>compilerClassName</param-name>
            <param-value>org.apache.jasper.compiler.AntCompiler</param-value>
        </init-param>
        <init-param>
            <param-name>compiler</param-name>
            <param-value>jikes</param-value>
        </init-param>

That (as expected) produces an error that the jikes compiler could not be started (since I don't have the jikes compiler). Before I added in the compilerClassName, it never even tried to use the jikes compiler.

I also tried the "classic," "modern" and "extJavac," and while it's no longer trying to use the Eclipse compiler, it appears there are no options for using the JDK's javac compiler, as I get errors for each of these options that the lambda expression in my JSP is not valid syntax, despite the fact that the same lambda expression compiles in a class compiled by my JDK. This is, I suppose, a different issue.

As for the documentation bug, your change helps, but I believe it could be improved further:

1) "compilerClassName" is not documented at all. It NEEDS to be document, especially since "compiler" doesn't work unless you set "compilerClassName" to the AntCompiler class.

2) This is how I suggest wording the change you already made to "compile":

See the <a href="http://ant.apache.org/manual/Tasks/javac.html#compilervalues">Ant documentation</a> for more information. This value corresponds to the "compiler" attribute of the Javac Ant task, and all Ant-supported values are legal here. Parameter "compilerClassName" must be set to the AntCompiler class. If "compilerClassName" is not set to the AntCompiler class, this parameter is ignored and the Eclipse JDT Java compiler will be used instead of using Ant. If "compilerClassName" is set to the AntCompiler class but this parameter is not set, then the default Ant compiler will be used.
Comment 4 Christopher Schultz 2013-01-23 17:48:25 UTC
(In reply to comment #3)
> I tried the following variations of the compiler init parameter:
> 
>         <init-param>
>             <param-name>compiler</param-name>
>             <param-value>classic</param-value>
>         </init-param>
> 
>         <init-param>
>             <param-name>compiler</param-name>
>             <param-value>modern</param-value>
>         </init-param>
> 
>         <init-param>
>             <param-name>compiler</param-name>
>             <param-value>jikes</param-value>
>         </init-param>
> 
>         <init-param>
>             <param-name>compiler</param-name>
>             <param-value>extJavac</param-value>
>         </init-param>
> 
> And with each one, I simply got these warnings whenever the first JSP tried
> to compile:
> 
> Jan 22, 2013 3:37:59 PM org.apache.jasper.compiler.JDTCompiler generateClass
> WARNING: Unknown source VM 1.8 ignored.
> Jan 22, 2013 3:37:59 PM org.apache.jasper.compiler.JDTCompiler generateClass
> WARNING: Unknown target VM 1.8 ignored.

So, you're using Java 1.8 with this? JDTCompiler has hard-coded target version numbers that it will accept as parameters (and 1.8 is not recognized). Are you using other parameters, or are those being invented under the covers and not accessible to you?

Note that the "ignored" message just says that the "1.8" is being ignored and that the compiler will emit Java 1.5-compatible code. (I'm not sure why it emits Java 1.5-compatible code when Tomcat 7 requires Java 1.6 and Tomcat 8 will likely require Java 1.7, but that's the way it is).
Comment 5 Nick Williams 2013-01-23 18:07:45 UTC
That's unrelated to the documentation I reported. I mentioned that I was trying to compile with Java 8 for context, but I suppose that could have just made it more confusing.

It boils down to this: I wanted to compile JSPs with Java 8. I knew that Tomcat uses the Eclipse JDT compiler for JSP compilation, and I knew that the Eclipse JDT compiler did NOT support "1.8" yet, so I was expecting the warning that it was ignoring "1.8." However, the documentation on the "compiler" parameter vaguely eluded to the capability of using something other than the JDT compiler, but, following that documentation, I was having a very hard time getting it to work. Everything I tried to set the "compiler" variable to, I still got the warning from Eclipse.

I found a forum/list posting through Google (http://grokbase.com/t/tomcat/users/07685hc9k7/using-javac-instead-of-jdt-to-compile-jsps) that confused and misled me into thinking that the documentation was correct and that it should be "compilerClassName," not "compiler" (and what led me to file this bug, prematurely). But when I tried to set it to com.sun.tools.javac.Main as suggested in the forum, it couldn't be casted. That's how I discovered the JDTCompiler and AntCompiler classes and came to the mistaken conclusion that you had to set the compilerClassName parameter to the AntCompiler class AND set the compiler parameter to "modern" to achieve what I wanted to.

However, when I started getting errors from the compiler that were related to my lambda expression in my JSP, I (again, incorrectly) made the assumption that the Ant compiler wasn't using the the JDK compiler like I thought it would and that Ant didn't support Java 8. In actuality, my new problem was related to a bug with SMAPs and Java 8, and I had to add suppressSmap = true to my JSP configuration.

So, what all of that comes down to is, the SMAP issue needs to be fixed (I will file a separate issue for that) and the documentation could use some improvement. Currently it says:

compiler - Which compiler Ant should use to compile JSP pages. See the Ant documentation for more information. If the value is not set, then the default Eclipse JDT Java compiler will be used instead of using Ant. No default value.

Violeta changed it do:

compiler - Which compiler Ant should use to compile JSP pages. See the <a href="http://ant.apache.org/manual/Tasks/javac.html">Ant documentation</a> for more information. If the value is not set, then the default Eclipse JDT Java compiler will be used instead of using Ant. No default value.

I would recommend (A) adding documentation for the compilerClassName and explaining why it would need to be used, and (B) changing the compiler documentation to:

compiler - Setting this parameter automatically enables the Ant compiler instead of the Eclipse JDT compiler. The value specified indicates which compiler Ant should use to compile JSP pages. See the <a href="http://ant.apache.org/manual/Tasks/javac.html#compilervalues">Ant documentation</a> for the list of valid values for this parameter, which corresponds to the compiler attribute on the Ant Javac task. If the value is not set, then the default Eclipse JDT Java compiler will be used instead of using Ant. No default value. The JDK's tools.jar and Ant's ant.jar and ant-launcher.jar must be on Tomcat's classpath in order for this setting to work.

I think that explains it well, and should prevent any further confusion from tired people like me. :-)
Comment 6 Christopher Schultz 2013-01-23 18:35:33 UTC
(In reply to comment #5)
> That's unrelated to the documentation I reported. I mentioned that I was
> trying to compile with Java 8 for context, but I suppose that could have
> just made it more confusing.

It looks like lots of your problems are coming from the use of Java 8: that's what I'm trying to point out. If you use Java 1.8, it looks like the JSP compiler will auto-downgrade to 1.5 and all your labmdas and stuff will fail to compile.

> It boils down to this: I wanted to compile JSPs with Java 8.

[...]

> However, when I started getting errors from the compiler that were related
> to my lambda expression in my JSP, I (again, incorrectly) made the
> assumption that the Ant compiler wasn't using the the JDK compiler like I
> thought it would and that Ant didn't support Java 8. In actuality, my new
> problem was related to a bug with SMAPs and Java 8, and I had to add
> suppressSmap = true to my JSP configuration.

Try explicitly using "1.7" as the target VM and see if all your problems go away.

We will certainly fix the documentation, but you still need to be able to compile.
Comment 7 Mark Thomas 2013-01-23 19:22:38 UTC
Much of the information in this bug report is incorrect but it does highlight some gaps in the Jasper how-to. I have updated the how-to in trunk and 7.0.x and it will be included in 7.0.36 onwards.
Comment 8 Nick Williams 2013-01-23 19:33:03 UTC
I suppose my last comment was tl;dr :-). It was an explanation about the meandering journey on why I had some of the mistaken understandings that I did (and putting the blame squarely on that forum/list posting :-P ).

Highlights:

1) It works! I successfully got JSPs compiling in 1.8! And my lambda expressions work as expected. Horray! :-)

2) This bug report was solely for the purpose of saying that the jasper-howto.html documentation for the "compiler" paramater was lacking. That is still the case. My recommended changes:

compiler - Setting this parameter automatically enables the Ant compiler instead of the Eclipse JDT compiler. The value specified indicates which compiler Ant should use to compile JSP pages. See the <a href="http://ant.apache.org/manual/Tasks/javac.html#compilervalues">Ant documentation</a> for the list of valid values for this parameter, which corresponds to the compiler attribute on the Ant Javac task. If the value is not set, then the default Eclipse JDT Java compiler will be used instead of using Ant. No default value. The JDK's tools.jar and Ant's ant.jar and ant-launcher.jar must be on Tomcat's classpath in order for this setting to work.