Servlet UnavailableException:No class in holder while starting jetty
Solution 1
Would need to know how Jetty is started in your yjava.servlet.container.jetty.JettyDaemon
to answer with any more depth.
If you want auto-wiring of Jersey, using Servlet 3.0 technique as outlined by org.glassfish.jersey.servlet.init.JerseyServletContainerInitializer
, then that JettyDaemon
class will have to enable the various annotation scanning configurations for Jetty.
For starters, your web.xml declaration is bad.
Yours (reformatted to be readable)
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
That XML is invalid, the web-app
element isn't closed, and you are missing some of the required attributes.
Correct for 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>
But your environment is Servlet 3.1, per your choice of Jetty 9 and the use of servlet-api 3.1.0 in your pom.xml, so that declaration would be:
<?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>
Solution 2
Changing the web.xml as below fixed my problem. I had to specify servlet-name and servlet-class. I tried the other way as described in Jersey 2.11 spec. I followed the steps in 4.7.1. Servlet 2.x Container =>Example 4.9. Hooking up Jersey as a 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>
Sharadr
Updated on June 11, 2022Comments
-
Sharadr about 2 years
Can anyone tell me what causes this exception while jetty server is starting. I am using jetty 9.2.2
javax.servlet.UnavailableException: No class in holder
The web.xml contains
<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>
The TestApiApplication.java extends Application
public class TestApiApplication extends Application { public TestApiApplication() { } @Override public Set<Class<?>> getClasses() { Set<Class<?>> s = new HashSet<Class<?>>(); s.add(TestResource.class); return s; } }
The drilled down version of my pom.xml is:
<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>
The complete stack trace is:
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)