Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSP on Tomcat 7 fails with NoClassDefFoundError: Lorg/apache/AnnotationProcessor

I am in the process of upgrading from Tomcat 6.0.24 to 7.0.23. I have a maven 2.2.1 project which precompiles JSPs using the jspc maven plugin.

When I deploy the WAR file for my app, and try to visit a JSP, I get the following error:

javax.servlet.ServletException: Error instantiating servlet class org.apache.jsp.my_jsp
...
root cause:
java.lang.NoClassDefFoundError: Lorg/apache/AnnotationProcessor;
    java.lang.Class.getDeclaredFields0(Native Method)
    java.lang.Class.privateGetDeclaredFields(Class.java:2291)
    java.lang.Class.getDeclaredFields(Class.java:1743)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928)
...

I have tried borrowing a snippet of the POM from this blog post to make jspc work with Tomcat 7, but this hasn't fixed the problem. How can I address this issue? Any pointers in the right direction would be appreciated.

like image 927
RMorrisey Avatar asked Jan 19 '12 18:01

RMorrisey


2 Answers

It turns out that I had another reference to the JSPC plugin in a sub-directory POM file (myproject-war/pom.xml). Fixing it both in /pom.xml and myproject-war/pom.xml was sufficient to solve the problem. Here is the updated POM snippet I used:

        <plugin>
            <groupId>org.codehaus.mojo.jspc</groupId>
            <artifactId>jspc-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>jspc</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <inputWebXml>${basedir}/target/web.xml</inputWebXml>
                <packageName>org.apache.jsp</packageName>
                <source>1.5</source>
                <target>1.5</target>
                <trimSpaces>false</trimSpaces>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>com.csc.aims</groupId>
                    <artifactId>aims-jar</artifactId>
                    <version>${project.version}</version>
                    <classifier>${env}</classifier>
                </dependency>
                <!-- 
                    Hack the jspc plugin, which only supports Tomcat 6, to work for Tomcat 7. See:
                    http://hasini-gunasinghe.blogspot.com/2011/09/how-to-use-pre-compiled-jsps-in-webapp.html 
                -->
                <dependency>  
                    <groupId>org.codehaus.mojo.jspc</groupId>  
                    <artifactId>jspc-compiler-tomcat6</artifactId>  
                    <version>2.0-alpha-3</version>  

                    <exclusions>  
                        <exclusion>  
                            <groupId>org.apache.tomcat</groupId>  
                            <artifactId>jasper</artifactId>  
                        </exclusion>  
                        <exclusion>  
                            <groupId>org.apache.tomcat</groupId>  
                            <artifactId>jasper-el</artifactId>  
                        </exclusion>  
                        <exclusion>  
                            <groupId>org.apache.tomcat</groupId>  
                            <artifactId>jasper-jdt</artifactId>  
                        </exclusion>  
                        <exclusion>  
                            <groupId>org.apache.tomcat</groupId>  
                            <artifactId>servlet-api</artifactId>  
                        </exclusion>  
                        <exclusion>  
                            <groupId>org.apache.tomcat</groupId>  
                            <artifactId>jsp-api</artifactId>  
                        </exclusion>  
                        <exclusion>  
                            <groupId>org.apache.tomcat</groupId>  
                            <artifactId>el-api</artifactId>  
                        </exclusion>  
                        <exclusion>  
                            <groupId>org.apache.tomcat</groupId>  
                            <artifactId>annotations-api</artifactId>  
                        </exclusion>  
                    </exclusions>  
                </dependency>  

                <dependency>  
                    <groupId>org.apache.tomcat</groupId>  
                    <artifactId>tomcat-jasper</artifactId>  
                    <version>${tomcat.version}</version> 
                </dependency>  

                <dependency>  
                    <groupId>org.eclipse.jdt.core.compiler</groupId>  
                    <artifactId>ecj</artifactId>  
                    <version>3.5.1</version>  
                </dependency>
            </dependencies>
        </plugin>

In addition, I had to update my tomcat provided dependencies, since the artifactId of each Tomcat dependency has changed in the new version; ex:

                <dependency>
                     <groupId>org.apache.tomcat</groupId>
                     <artifactId>tomcat-jasper</artifactId>
                     <version>${tomcat.version}</version>
                     <scope>provided</scope>
                </dependency>

instead of:

                <dependency>
                     <groupId>org.apache.tomcat</groupId>
                     <artifactId>jasper</artifactId>
                     <version>${tomcat.version}</version>
                     <scope>provided</scope>
                </dependency>

(Note: tomcat.version is property defined in my main POM):

<properties>
    ...
    <tomcat.version>7.0.23</tomcat.version>
    ...
</properties>
like image 120
RMorrisey Avatar answered Nov 11 '22 07:11

RMorrisey


I had the same problem because EvalTag.jar needed org.apache.AnnotationProcessor to run

My simple fix was to recreate the interface directly in my application. That way I don't need all the jasper.jar of tomcat 6.

package org.apache;
import java.lang.reflect.InvocationTargetException;
import javax.naming.NamingException;

public interface AnnotationProcessor {
    public void postConstruct(Object instance) throws IllegalAccessException, InvocationTargetException;
    public void preDestroy(Object instance) throws IllegalAccessException, InvocationTargetException;
    public void processAnnotations(Object instance) throws IllegalAccessException, InvocationTargetException, NamingException;
}
like image 1
mathd Avatar answered Nov 11 '22 05:11

mathd