java.lang.ClassNotFoundException 使用 JAX-RS 和 Maven

java.lang.ClassNotFoundException with JAX-RS and Maven

我认为这是一个重复的问题,但我找不到解决方案。我用 Maven 开发了一个 JAX-RS 服务。

这是我的 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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.diginreportengine.jersey</groupId>
    <artifactId>digin-report</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>DiginReportEngine</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.0.1</version>
            <scope>provided</scope>
        </dependency>
         <build>
        <finalName>Report</finalName>
    </build>

</project>

web.xml:

<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"
                        version="3.0">    
    <display-name>DigIn Report Engine</display-name> 
    <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>
                     com.sun.jersey.spi.container.servlet.ServletContainer
        </servlet-class>
        <init-param>
             <param-name>com.sun.jersey.config.property.packages</param-name>
             <param-value>com.diginreportengine.jersey.main</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet> 
    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/rs/*</url-pattern>
    </servlet-mapping> 
</web-app>

代码:

@Path("GetReport")
public class ReportService { 
    @GET
    @Path("{reportName}/{parameters}")
    @Produces(MediaType.TEXT_PLAIN)
    public Response getReport(@PathParam("reportName") String reportName,@PathParam("parameters") String parameters) {

    }

    @GET
    @Path("{reportName}")
    @Produces(MediaType.TEXT_PLAIN)
    public Response startEngine(@PathParam("reportName") String command) {
            return Response.status(200).entity("ok").build();
    }
}

日志:

INFO: Loaded APR based Apache Tomcat Native library 1.2.5 using APR version 1.5.1.
Mar 31, 2016 1:17:37 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
Mar 31, 2016 1:17:38 PM org.apache.catalina.core.AprLifecycleListener initializeSSL
INFO: OpenSSL successfully initialized (OpenSSL 1.0.2g  1 Mar 2016)
Mar 31, 2016 1:17:38 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-apr-8085"]
Mar 31, 2016 1:17:38 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-apr-8009"]
Mar 31, 2016 1:17:38 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 2121 ms
Mar 31, 2016 1:17:38 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Mar 31, 2016 1:17:38 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/8.0.32
Mar 31, 2016 1:17:41 PM org.apache.jasper.servlet.TldScanner scanJars
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
Mar 31, 2016 1:17:41 PM org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [234] milliseconds.
Mar 31, 2016 1:17:44 PM org.apache.jasper.servlet.TldScanner scanJars
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
Mar 31, 2016 1:17:44 PM org.apache.catalina.core.ApplicationContext log
INFO: Marking servlet jersey-serlvet as unavailable
Mar 31, 2016 1:17:44 PM org.apache.catalina.core.StandardContext loadOnStartup
SEVERE: Servlet [jersey-serlvet] in web application [/DiginReport] threw load() exception
java.lang.ClassNotFoundException: com.sun.jersey.spi.container.servlet.ServletContainer
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1308)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1142)
    at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:518)
    at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:499)
    at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:118)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1102)
    at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1038)
    at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4997)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5289)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Mar 31, 2016 1:17:44 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-apr-8085"]
Mar 31, 2016 1:17:44 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-apr-8009"]
Mar 31, 2016 1:17:44 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 5357 ms

您的配置很混乱:您添加了 JAX-RS 2.0 依赖项,但您在 web.xml 部署描述符中使用 Jersey 1.x 配置。

我想你想使用 Jersey 2.x,它是 JAX-RS 2.0 规范的参考实现。

快速概览

Jersey 1.x 和 Jersey 2.x 使用不同的包名:

  • 球衣 1.x: com.sun.jersey
  • 球衣 2.x: org.glassfish.jersey

Jersey 1.x 和 Jersey 2.x 实现不同版本的 JAX-RS 规范:

修复您的依赖项

pom.xml 中的依赖项更改为如下:

<dependencies>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <!-- if your container implements Servlet API older than 3.0, 
             use "jersey-container-servlet-core"  -->
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.22.2</version>
    </dependency>
</dependencies>

有关 Jersey 模块和依赖项的更多详细信息,请查看 documentation

修复部署描述符

您正在使用 Tomcat 8.x,supports Servlet API 3.1。对于简单部署,根本不需要 web.xml 部署描述符。

如果需要,可以空一个,如下:

<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"
    version="3.1">

 </web-app>

但是,您需要自定义 Application/ResourceConfig subclass annotated with @ApplicationPath 来为应用程序中配置的所有 Jersey 资源定义基本应用程序 URI:

@ApplicationPath("rs")
public class MyApplication extends ResourceConfig {

    public MyApplication() {
        packages("com.diginreportengine.jersey.main");
    }
}

如果您没有为基于 Maven 的 Web 应用程序项目提供 web.xml 部署描述符,您需要通过设置 [=] 配置 maven-war-plugin 以忽略丢失的 web.xml 文件27=] 配置 属性 到 false 在你的项目 pom.xml 文件:

<plugins>
    ...
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.6</version>
        <configuration>
            <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
    </plugin>
    ...
</plugins>

有关 Jersey 部署和运行时环境的更多详细信息,请查看 documentation