【问题标题】:Servlet UnavailableException:No class in holder while starting jettyServlet UnavailableException:启动码头时持有人中没有类
【发布时间】:2014-12-07 17:34:33
【问题描述】:

谁能告诉我是什么原因导致码头服务器启动时出现此异常。我正在使用码头 9.2.2

javax.servlet.UnavailableException: 持有者中没有类

web.xml 包含

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

<servlet>
    <servlet-name>com.test.api.TestApiApplication</servlet-name>
</servlet>
<servlet-mapping>
    <servlet-name>com.test.api.TestApiApplication</servlet-name>
    <url-pattern>/v1/*</url-pattern>
</servlet-mapping>
</web-app>

TestApiApplication.java 扩展了应用程序

public class TestApiApplication extends Application {

 public TestApiApplication() {
 }

@Override
 public Set<Class<?>> getClasses() {
    Set<Class<?>> s = new HashSet<Class<?>>();
    s.add(TestResource.class);
    return s;
 } 
}

我的 pom.xml 的深入版本是:

<properties>
    <jersey.version>2.11</jersey.version>
    <spring.framework.version>4.0.6.RELEASE</spring.framework.version>
    <jaxrs.version>2.0</jaxrs.version>
</properties>
<dependencies>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>javax.ws.rs-api</artifactId>
        <version>2.0</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet-core</artifactId>
        <version>${jersey.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>${jersey.version}</version>
    </dependency>

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.18.1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-jetty-servlet</artifactId>
        <version>2.11</version>
    </dependency>
</dependencies>

完整的堆栈跟踪是:

javax.servlet.UnavailableException: No class in holder
    at org.eclipse.jetty.servlet.BaseHolder.doStart(BaseHolder.java:88)
    at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:332)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:868)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:298)
    at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1341)
    at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1334)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:741)
    at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:497)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:41)
    at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:186)
    at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:498)
    at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:146)
    at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:180)
    at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:64)
    at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:609)
    at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:528)
    at org.eclipse.jetty.util.Scanner.scan(Scanner.java:391)
    at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:313)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.deploy.providers.ScanningAppProvider.doStart(ScanningAppProvider.java:150)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:560)
    at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:235)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
    at org.eclipse.jetty.server.Server.start(Server.java:380)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
    at org.eclipse.jetty.server.Server.doStart(Server.java:347)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
    at yjava.servlet.container.jetty.JettyDaemon.start(JettyDaemon.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.apache.commons.daemon.support.DaemonLoader.start(DaemonLoader.java:177)

【问题讨论】:

  • yjava.servlet.container.jetty.JettyDaemon.start 是做什么的?

标签: jetty


【解决方案1】:

您应该将 pom.xml 的 servlet 内容更正为jersey-container-servlet

【讨论】:

    【解决方案2】:

    需要知道 Jetty 如何在您的 yjava.servlet.container.jetty.JettyDaemon 中启动才能更深入地回答。

    如果您想使用 org.glassfish.jersey.servlet.init.JerseyServletContainerInitializer 概述的 Servlet 3.0 技术自动连接 Jersey,那么 JettyDaemon 类将必须为 Jetty 启用各种注释扫描配置。

    首先,您的 web.xml 声明很糟糕。

    你的(重新格式化为可读)

    <web-app version="3.0" 
             xmlns="http://java.sun.com/xml/ns/javaee" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    

    该 XML 无效,web-app 元素未关闭,并且您缺少一些必需的属性。

    Servlet 3.0 更正:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    </web-app>
    

    但是您的环境是 Servlet 3.1,根据您选择的 Jetty 9 和在 pom.xml 中使用 servlet-api 3.1.0,因此声明将是:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         metadata-complete="false"
         version="3.1">
    </web-app>
    

    【讨论】:

    • 感谢您的回复我更新了 web.xml 中的命名空间部分。但事实证明,我必须定义 org.glassfish.jersey.servlet.ServletContainer。但根据球衣规范,我不需要这样做 repo1.maven.org/maven2/org/glassfish/jersey/… (4.7.2. Servlet 3.x Container)
    • @Sharadr 您的 JettyDaemon 没有为注释扫描和 SCI 使用正确设置环境和/或配置。
    • 你能告诉我为什么你认为我的 JettyDaemon 不是属性设置吗?
    • Jersey 的 SCI 没有被执行的事实告诉我。确保将 WebAppContext 配置设置为支持注释 - 请参阅 github.com/jetty-project/embedded-servlet-3.1/blob/master/src/… 的示例项目
    【解决方案3】:

    如下更改 web.xml 解决了我的问题。我必须指定 servlet-name 和 servlet-class。我尝试了Jersey 2.11 spec 中描述的另一种方式。 我按照 4.7.1 中的步骤进行操作。 Servlet 2.x 容器 => 示例 4.9。将 Jersey 连接为 Servlet

        <?xml version="1.0" encoding="UTF-8"?>
        <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
          metadata-complete="false" version="3.1">   
    
          <servlet>
          <servlet-name>TestApp</servlet-name>
             <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
             <init-param>
                <param-name>javax.ws.rs.Application</param-name>
                <param-value>com.test.api.TestApiApplication</param-value>
             </init-param>
          </servlet>
    
          <servlet-mapping>
            <servlet-name>TestApp</servlet-name>
            <url-pattern>/v1/*</url-pattern>
          </servlet-mapping>
        </web-app>
    

    【讨论】:

      猜你喜欢
      • 2014-07-16
      • 2021-12-26
      • 2017-02-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-19
      • 1970-01-01
      • 2020-01-15
      • 2011-12-08
      相关资源
      最近更新 更多