Tomcat 7上的JSP出现NoClassDefFoundError: Lorg/apache/AnnotationProcessor错误

5
我正在将Tomcat 从6.0.24升级到7.0.23。 我有一个使用jspc maven插件预编译JSP的maven 2.2.1项目。
当我部署应用程序的WAR文件并尝试访问JSP时,我会收到以下错误:
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)
...

我尝试借用来自这篇博客文章的POM片段,以使jspc与Tomcat 7配合使用,但这并没有解决问题。如何解决这个问题?有指导方向的任何提示将不胜感激。
3个回答

5

事实证明,我在子目录的POM文件(myproject-war/pom.xml)中还有对JSPC插件的引用。在/pom.xml和myproject-war/pom.xml中进行修复就足以解决问题。以下是我使用的更新后的POM代码片段:

        <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>

此外,我需要更新由Tomcat提供的依赖项,因为每个Tomcat依赖项的artifactId在新版本中已更改;例如:

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

替代方案:

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

(注意:tomcat.version是在我的主POM中定义的属性):
<properties>
    ...
    <tomcat.version>7.0.23</tomcat.version>
    ...
</properties>

也许我不理解,但是在你的类路径中为什么要使用tomcat-jasper,并在jspc插件中进行这么多的排除? - Zarathustra

1
我遇到了同样的问题,因为EvalTag.jar需要org.apache.AnnotationProcessor才能运行。
我的简单解决方法是在我的应用程序中直接重新创建接口。这样我就不需要tomcat 6的所有jasper.jar了。
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;
}

0

看起来你没有在类路径中包含必需的jar文件。

http://www.jarfinder.com/index.php/java/info/org.apache.AnnotationProcessor

以上链接显示哪个jar文件拥有这个类,我看到它在catalina-6*.jar中,因此我猜测它已经被删除/弃用/更新了在Tomcat 7中。
您可以尝试在类路径中包含此jar文件(同时这并不是一个好主意),因为它可能会创建其他冲突或影响您的应用程序的可移植性。

我同意,从Tomcat 6中包含库文件似乎可以作为一种权宜之计解决问题; 但是,除非我找不到其他解决方案,否则我不想追求这种方法。我想找出编译用于Tomcat 7的JSP的“正确”方式……假设那是问题的根源。 - RMorrisey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接