Servlet class com.foobar.jaxrs.application.MyApplication is not a javax.servlet.Servlet

流过昼夜 提交于 2019-12-12 17:07:21

问题


I'm trying to configure Jersey with Servlet 3.1 and an Application Subclass. Been reading documentation for a while and trying to get this going, but i'm not sure what's wrong here.

web.xml (though I shouldn't need one I get a 404 without one...)

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

<display-name>Foobar Models</display-name>

<welcome-file-list>
    <welcome-file>index.htm</welcome-file>
</welcome-file-list>

<session-config>
    <session-timeout>30</session-timeout>
    <cookie-config>
        <name>SESSIONID</name>
    </cookie-config>
</session-config>

<servlet>
    <servlet-name>Foo Bar Application</servlet-name>
    <servlet-class>com.foobar.jaxrs.application.FooBarApplication</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Foo Bar Application</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>

</web-app>

Application Subclass

package com.foobar.jaxrs.application;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/api")
public class FooBarApplication extends Application {
public Set<Class<?>> getClasses() {
    Set<Class<?>> s = new HashSet<Class<?>>();
    s.add(com.foobar.api.HealthCheckResource.class);
    return s;
}
}

HealthCheckResource.java

package com.foobar.api;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("health")
public class HealthCheckResource {

    @GET
    @Produces("text/html")
    public String getHeath() {
        return "Foo Bar Application is healthy!";
    }

}

Running in jetty (same in Tomcat 8)

HTTP ERROR 404

Problem accessing /foobar/api/health. Reason:

    Servlet class com.foobar.jaxrs.application.FooBarApplication is not a javax.servlet.Servlet
Caused by:

javax.servlet.UnavailableException: Servlet class com.foobar.jaxrs.application.FooBarApplication is not a javax.servlet.Servlet
    at org.mortbay.jetty.servlet.ServletHolder.checkServletType(ServletHolder.java:362)
    at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:243)
    at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
    at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
....

回答1:


Well, the message says it all. You're trying to deploy your Application subclass, which doesn't extend from Servlet, as a servlet. That can't possibly work.

This is not how the Jersey documentation tells to do things. Here is what it says:

Hooking up Jersey as a Servlet

<web-app>
    <servlet>
        <servlet-name>MyApplication</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            ...
        </init-param>
    </servlet>
    ...
    <servlet-mapping>
        <servlet-name>MyApplication</servlet-name>
        <url-pattern>/myApp/*</url-pattern>
    </servlet-mapping>
    ...
</web-app>

Note that the servlet class is org.glassfish.jersey.servlet.ServletContainer. Not your custom Application subclass.

Custom Application subclass

If you extend the Application class to provide the list of relevant root resource classes (getClasses()) and singletons (getSingletons()), i.e. your JAX-RS application model, you then need to register it in your web application web.xml deployment descriptor using a Servlet or Servlet filter initialization parameter with a name of javax.ws.rs.Application [sic] as follows:

Example 4.11. Configuring Jersey container Servlet or Filter to use custom Application subclass

<init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>org.foo.MyApplication</param-value>
</init-param>

Note that the custom Application subclass is configured as an init-param of the servlet. Not as the servlet class.




回答2:


I figured out the issue - I was running in gradle's jetty plugin which uses servlet 2.5 but i'm deploying a servlet 3.1 app. I was able to get it to work without the web.xml after deploying to Tomcat 8 with the correct configuration.

It still doesnt work with Jetty (need to get an updated version of jetty), but in Tomcat 8 this works:

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

    <display-name>Foo Bar Models</display-name>

    <welcome-file-list>
        <welcome-file>index.htm</welcome-file>
    </welcome-file-list>

</web-app>

BaseApplication.java package com.foobar.jaxrs.application;

import java.util.HashSet;
import java.util.Set;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("")
public class BaseApplication extends Application {

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


来源:https://stackoverflow.com/questions/33323138/servlet-class-com-foobar-jaxrs-application-myapplication-is-not-a-javax-servlet

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!