由名称类'空字符串'的ClassNotFoundException引起的TomEE OpenEJBException

时间:2014-07-15 21:27:48

标签: java jsf tomcat servlets tomee

当尝试使用运行Mojarra 2.2.0的Java Server Faces Web应用程序启动TomEE时,我得到一个由类名为“”(空字符串)的Servlet引起的ClassNotFoundException。我用调试器捕获了错误,希望找出空字符串的来源。是不是在web.xml文件中指定了所有servlet类名?有没有人碰到这个? web.xml文件是否以某种方式损坏了?

异常堆栈跟踪:

SEVERE: Unable to deploy collapsed ear in war StandardEngine[Catalina].StandardHost[localhost].StandardContext[/CopSync]
org.apache.openejb.OpenEJBException: Unable to load servlet class: : <-- Class name goes here
    at org.apache.openejb.config.AnnotationDeployer$ProcessAnnotatedBeans.deploy(AnnotationDeployer.java:2061)
    at org.apache.openejb.config.AnnotationDeployer$ProcessAnnotatedBeans.deploy(AnnotationDeployer.java:1824)
    at org.apache.openejb.config.AnnotationDeployer.deploy(AnnotationDeployer.java:355)
    at org.apache.openejb.config.ConfigurationFactory$Chain.deploy(ConfigurationFactory.java:396)
    at org.apache.openejb.config.ConfigurationFactory.configureApplication(ConfigurationFactory.java:938)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.startInternal(TomcatWebAppBuilder.java:1179)
    at org.apache.tomee.catalina.TomcatWebAppBuilder.configureStart(TomcatWebAppBuilder.java:1054)
    at org.apache.tomee.catalina.GlobalListenerSupport.lifecycleEvent(GlobalListenerSupport.java:127)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5355)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: 
    at org.apache.openejb.core.TempClassLoader.loadClass(TempClassLoader.java:141)
    at org.apache.openejb.core.TempClassLoader.loadClass(TempClassLoader.java:74)
    at org.apache.openejb.config.AnnotationDeployer$ProcessAnnotatedBeans.deploy(AnnotationDeployer.java:2054)
    ... 17 more

编辑:添加了调试器变量值的屏幕截图。 Eclipse调试器中变量状态的屏幕截图: enter image description here

AnnotationDeployer中抛出OpenEJBException的代码片段:

          if (servletClass != null && servlet.getJspFile() == null) { // jaxrs application doesn't have a jsp file
                if (!"org.apache.openejb.server.rest.OpenEJBRestServlet".equals(servletClass)) {
                    try {
                        Class clazz = classLoader.loadClass(servletClass);
                        classes.add(clazz);
                        if (servlet.getServletClass() == null) {
                            servlet.setServletClass(servletClass);
                        }
                    } catch (ClassNotFoundException e) {
                        if (servlet.getServletClass() != null) {
 line 2061                           throw new OpenEJBException("Unable to load servlet class: " + servletClass, e);
                        } else {
                            logger.error("servlet " + servlet.getServletName() + " has no servlet-class defined and is not a subclass of Application");
                        }
                    }
                }

TempClassLoader的代码段

       final String resourceName = name.replace('.', '/') + ".class";

        //Copy the input stream into a byte array
        final byte[] bytes;
        this.bout.reset();
        InputStream in = null;

        try {

            in = this.getResourceAsStream(resourceName);

            if (in != null && !(in instanceof BufferedInputStream)) {
                in = new BufferedInputStream(in);
            }

            if (in == null) {
line 141                throw new ClassNotFoundException(name);
            }

            IO.copy(in, this.bout);
            bytes = this.bout.toByteArray();

        } catch (IOException e) {
            throw new ClassNotFoundException(name, e);
        } finally {
            IO.close(in);
        }

web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>ProjectName</display-name>
  <welcome-file-list>
    <welcome-file>login.xhtml</welcome-file>
  </welcome-file-list>
  <listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
  </listener>
  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>
  <context-param>
    <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <param-name>com.sun.faces.forceLoadConfiguration</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>
  <context-param>
    <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
    <param-value>resources.application</param-value>
  </context-param>

  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>

  <servlet>
    <description>JAX-RS Tools Generated - Do not modify</description>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <servlet-class></servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <url-pattern>/jaxrs/*</url-pattern>
  </servlet-mapping>
</web-app>

pom.xml文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>ProjectName</groupId>
  <artifactId>ProjectName</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>javax.faces</groupId>
            <artifactId>jsf-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.10-FINAL</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.10-FINAL</version>
        </dependency>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-bundle-jaxrs</artifactId>
            <version>2.7.11</version>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.3-1101-jdbc41</version>
        </dependency>
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>

        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.0</version>
        </dependency>
            <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>1.9.5</version>
        </dependency>
    </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.3</version>
        <configuration>
          <warSourceDirectory>WebContent</warSourceDirectory>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

1 个答案:

答案 0 :(得分:2)

定义servlet class

时,您有一个空的JAX-RS Servlet
<servlet>
    <description>JAX-RS Tools Generated - Do not modify</description>
    <servlet-name>JAX-RS Servlet</servlet-name>
    <servlet-class></servlet-class>   <!-- HERE -->
    <load-on-startup>1</load-on-startup>
</servlet>

在这种情况下,servlet容器尝试使用空名称加载类,这通常是错误的,因此抛出Exception

您必须为Servlet提供完全限定的类名,例如:

<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>