java - 什么 Jersey 2.x 库版本可以解决这个问题?

标签 java rest web-services servlets

此错误与库版本有关,但我无法确定。

我正在 Crunchify 上完成一个 REST 示例:Link

项目副本链接:Temp Converter Challenge

我使用的是 Java 11,版本 1.8,运行时环境是 Tomcat 9。动态网页模块版本为4.0.0。

我收到以下错误: enter image description here

推荐的错误修复之一使用 Jersey 2.x,而该项目最初是使用 Jersey 1.x 构建的,如果混合使用,两者显然不兼容。这是错误的根本原因,我不知道使用什么版本的Jersey 2.x,尝试了一堆都没有成功。

我更新了 pom 和 web.xml 文件以反射(reflect) Jersey 2.x,这也是推荐使用的 Jersey 版本。

pom文件是这样的,注释内容是Jersey 1.x:

        <?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
                                    <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>CrunchifyRESTJerseyExample</groupId>
    <artifactId>CrunchifyRESTJerseyExample</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <build>
        <!-- <sourceDirectory>src</sourceDirectory> -->
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.7.0</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.1</version>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>asm</groupId>
            <artifactId>asm</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20170516</version>
        </dependency>
        
        
        
        
         <dependency>
              <groupId>org.glassfish.jersey.containers</groupId>
              <artifactId>jersey-container-servlet-core</artifactId>
              <version>2.13</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.13</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.inject</groupId>
            <artifactId>jersey-hk2</artifactId>
            <version>2.26</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>2.13</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.13</version>
            <scope>provided</scope>
        </dependency> 
        
        
        
        
    <!--    <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-bundle</artifactId>
            <version>1.19.4</version>
        </dependency>
         <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>1.19.4</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-core</artifactId>
            <version>1.19.4</version>
        </dependency> -->
        
         <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0.1</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.1</version>
        </dependency> 
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        
    </dependencies>
</project>

与原来的一些变化:

我说的是目标版本 1.8,而不是 1.7,因为即使指南也建议使用 1.8,但如果不在文件中指定它就无法执行此操作。此外,由于 pom 文件中的错误,我添加了以下依赖项:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.3.1</version>
</plugin>

我还更改了 xml 内容,因为 servlet 还必须与 Jersey 版本兼容。注释掉的是 Jersey 1.x 的版本

    <?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"
            id="WebApp_ID" version="3.1">
    <display-name>CrunchifyRESTJerseyExample</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
 
     <servlet>
        <servlet-name>Jersey REST Service</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>com.crunchify.restjersey</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet> -->
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/crunchify/*</url-pattern>
    </servlet-mapping>
</web-app>

单独运行该项目会产生以下结果: enter image description here

我进一步尝试了对 2020 版 Eclipse 项目的评论中的建议,但无济于事。

我已经查看了许多类似的问题,包括示例下的评论。这只是我到目前为止所查找内容的一部分:

How to fix 'javax.servlet.ServletException: Servlet.init()' Error for Tomcat

Jersey with Spring Error : Servlet.init() for servlet Jersey REST Service threw exception

Servlet.init() for servlet example threw exception

也许这个例子太旧了,但一切都指向导致它无法正常工作的库版本,我无法弄清楚我最终需要哪些版本。

更新,2022 年 4 月 9 日:

项目堆栈跟踪:

Apr. 09, 2022 2:01:00 P.M. com.sun.jersey.api.core.servlet.WebAppResourceConfig init
INFO: Scanning for root resource and provider classes in the Web app resource paths:
  /WEB-INF/lib
  /WEB-INF/classes
Apr. 09, 2022 2:01:01 P.M. org.apache.catalina.core.ApplicationContext log
SEVERE: Servlet.init() for servlet [Jersey Web Application] threw exception
java.lang.IllegalArgumentException
    at jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:170)
    at jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:153)
    at jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:424)
    at com.sun.jersey.spi.scanning.AnnotationScannerListener.onProcess(AnnotationScannerListener.java:138)
    at com.sun.jersey.core.spi.scanning.JarFileScanner.scan(JarFileScanner.java:97)
    at com.sun.jersey.spi.scanning.servlet.WebAppResourcesScanner$1.f(WebAppResourcesScanner.java:94)
    at com.sun.jersey.core.util.Closing.f(Closing.java:71)
    at com.sun.jersey.spi.scanning.servlet.WebAppResourcesScanner.scan(WebAppResourcesScanner.java:92)
    at com.sun.jersey.spi.scanning.servlet.WebAppResourcesScanner.scan(WebAppResourcesScanner.java:79)
    at com.sun.jersey.api.core.ScanningResourceConfig.init(ScanningResourceConfig.java:80)
    at com.sun.jersey.api.core.servlet.WebAppResourceConfig.init(WebAppResourceConfig.java:102)
    at com.sun.jersey.api.core.servlet.WebAppResourceConfig.<init>(WebAppResourceConfig.java:89)
    at com.sun.jersey.api.core.servlet.WebAppResourceConfig.<init>(WebAppResourceConfig.java:74)
    at com.sun.jersey.spi.container.servlet.WebComponent.getWebAppResourceConfig(WebComponent.java:668)
    at com.sun.jersey.spi.container.servlet.ServletContainer.getDefaultResourceConfig(ServletContainer.java:435)
    at com.sun.jersey.spi.container.servlet.ServletContainer.getDefaultResourceConfig(ServletContainer.java:602)
    at com.sun.jersey.spi.container.servlet.WebServletConfig.getDefaultResourceConfig(WebServletConfig.java:87)
    at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:699)
    at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:674)
    at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:205)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:394)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:577)
    at javax.servlet.GenericServlet.init(GenericServlet.java:158)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1134)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1089)
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:761)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:135)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:887)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1684)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)

Apr. 09, 2022 2:01:01 P.M. org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Allocate exception for servlet [Jersey Web Application]
java.lang.IllegalArgumentException
    at jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:170)
    at jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:153)
    at jersey.repackaged.org.objectweb.asm.ClassReader.<init>(ClassReader.java:424)
    at com.sun.jersey.spi.scanning.AnnotationScannerListener.onProcess(AnnotationScannerListener.java:138)
    at com.sun.jersey.core.spi.scanning.JarFileScanner.scan(JarFileScanner.java:97)
    at com.sun.jersey.spi.scanning.servlet.WebAppResourcesScanner$1.f(WebAppResourcesScanner.java:94)
    at com.sun.jersey.core.util.Closing.f(Closing.java:71)
    at com.sun.jersey.spi.scanning.servlet.WebAppResourcesScanner.scan(WebAppResourcesScanner.java:92)
    at com.sun.jersey.spi.scanning.servlet.WebAppResourcesScanner.scan(WebAppResourcesScanner.java:79)
    at com.sun.jersey.api.core.ScanningResourceConfig.init(ScanningResourceConfig.java:80)
    at com.sun.jersey.api.core.servlet.WebAppResourceConfig.init(WebAppResourceConfig.java:102)
    at com.sun.jersey.api.core.servlet.WebAppResourceConfig.<init>(WebAppResourceConfig.java:89)
    at com.sun.jersey.api.core.servlet.WebAppResourceConfig.<init>(WebAppResourceConfig.java:74)
    at com.sun.jersey.spi.container.servlet.WebComponent.getWebAppResourceConfig(WebComponent.java:668)
    at com.sun.jersey.spi.container.servlet.ServletContainer.getDefaultResourceConfig(ServletContainer.java:435)
    at com.sun.jersey.spi.container.servlet.ServletContainer.getDefaultResourceConfig(ServletContainer.java:602)
    at com.sun.jersey.spi.container.servlet.WebServletConfig.getDefaultResourceConfig(WebServletConfig.java:87)
    at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:699)
    at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:674)
    at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:205)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:394)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:577)
    at javax.servlet.GenericServlet.init(GenericServlet.java:158)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1134)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1089)
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:761)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:135)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:887)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1684)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)

最佳答案

如何解决问题

实际上,在克隆你的 GitHub 项目时,我只需要确保两个 <servlet-name> web.xml 中的条目完全相同。你的不一样,因为你在从教程中复制文件后更改了一个,而不是两个。

<servlet-name>Jersey REST Service</servlet-name>

我用 mvn clean package 构建了你的例子,然后为本地安装的 Tomcat 9.0.62 创建运行配置,将 WAR 添加为部署,

Tomcat deployment config

启动服务器,它立即工作:

Browser, opening application URL

Jersey 和 ASM 版本

您正在使用超旧的软件版本,例如Jersey 2.13 太旧了,甚至没有包含在 Eclipse Jersey 中。 GitHub 存储库,从 2018 年开始发布第一个版本 2.28-RC1 .为了找到存档的遗产GlassFish Jersey存储库,我必须先环顾四周。

无论如何,Jersey 2.13,您为项目选择的版本,根据 POM 在内部使用 ASM 5.0.2 .我在你自己的 POM 中看到了 ASM 3.3.1,根据 ASM release notes甚至还不完全支持 Java 7。然而,您正在根据您的 Maven 编译器设置编译为 Java 8 字节代码版本。因此,无论 ASM 在您的项目中做什么,您都希望至少使用支持 Java 8 的版本。那至少是 ASM 5.0,因此我建议坚持使用 Jersey 使用的版本 5.0.2。

但这并不能解决您的问题。堆栈跟踪实际上表示 jersey.repackaged.org.objectweb.asm.ClassReader 中存在问题,即在 ASM 类中打包并重新定位到 Jersey 本身。它没有使用您在 POM 中指定的旧版本。我无法在本地重现您的问题。我只想提一下。

优化POM

后来我用了mvn dependency:analyze为了找出您实际使用的依赖项。正如我所说,ASM 未在您的 servlet 中使用。所以你可以删除它。您只需要 Jersey、JSON 和 Jakarta WS-RS API,这是 Jersey 库之一的传递依赖项,但如果您访问它的类,您仍然应该在 POM 中引用它。依赖传递依赖不是干净的 Maven 方式。我还升级了您使用的插件和 JSON 依赖项,然后删除了所有未使用的内容。新的 POM 看起来像这样:

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>CrunchifyRESTJerseyExample</groupId>
  <artifactId>CrunchifyRESTJerseyExample</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.10.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.3.2</version>
      </plugin>
    </plugins>
  </build>

  <dependencies>
    <dependency>
      <groupId>org.json</groupId>
      <artifactId>json</artifactId>
      <version>20220320</version>
    </dependency>
    <dependency>
      <groupId>jakarta.ws.rs</groupId>
      <artifactId>jakarta.ws.rs-api</artifactId>
      <version>2.1.6</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.containers</groupId>
      <artifactId>jersey-container-servlet</artifactId>
      <version>2.35</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.inject</groupId>
      <artifactId>jersey-hk2</artifactId>
      <version>2.35</version>
    </dependency>
    <dependency>
      <groupId>org.glassfish.jersey.media</groupId>
      <artifactId>jersey-media-json-jackson</artifactId>
      <version>2.35</version>
    </dependency>
  </dependencies>
</project>

GitHub 拉取请求

https://github.com/username917/Temerature-Converter-Challenge/pull/2

关于java - 什么 Jersey 2.x 库版本可以解决这个问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71649841/

相关文章:

java - 如何更改项目的编译SDK版本?

java - 如何让 EasyMock 模拟多次返回一个空列表

python - DRF 发布到 ViewSet 而不写入模型

rest - 如何通过http客户端强制调用restful服务?

php - 在 WSDL 文件中为服务提供者使用动态 IP 地址

java - 如何在Java中通过lti-Civil CaptureDeviceStream从网络摄像头捕获视频?

java - 使用 arraylist 随机排列范围

java - Spring 3.0 REST 实现还是 Jersey ?

c# - 如何序列化 NHibernate 映射对象的所有属性?

java - 如何在 play 框架中将 java 集合发布到 web 服务