java - 由名称为 'empty string' 的类的 ClassNotFoundException 引起的 TomEE OpenEJBException

标签 java jsf tomcat servlets apache-tomee

当尝试使用运行 Mojarra 2.2.0 的 Java Server Faces Web 应用程序启动 TomEE 时,我收到由类名为“”(空字符串)的 Servlet 引起的 ClassNotFoundException。我用调试器捕获了错误,希望找出空字符串的来源。不是所有的 servlet 类名都在 web.xml 文件中指定了吗?有人遇到过这个吗? 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>

最佳答案

在定义 JAX-RS Servlet 时,您有一个空的 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>

关于java - 由名称为 'empty string' 的类的 ClassNotFoundException 引起的 TomEE OpenEJBException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24768488/

相关文章:

java - 我是否需要在保证发生之前的对象上进行同步?

java - 编译java代码时缺少参数

java - 查找特定 LocalDate 是否属于 YearMonth 的最简单方法是什么?

JSF Controller 、服务和 DAO

tomcat - 无法查看使用 Eclipse IDE 创建的示例 Portlet

java - 利用现有数据库的应用程序的 Web 框架?

java - RenderResponse 中的 TimeoutException(不知道为什么)

java - 使用 rostillic.us Controller 类时 getSessionAsSigner 为 null

eclipse - Eclipse 中的 Maven 配置文件和 Tomcat

java - 无法使 Struts2.2.1 注释在 Netbeans 6.9 上工作