JAX-RS:“ RESTEASY002005:执行GET org.jboss.resteasy.core.NoMessageBodyWriterFoundFailure失败

问题描述

我创建了一个简单的服务,使我能够侦听传入的REST请求,然后执行任务,并将任务的输出作为自定义对象(MyObject)返回给调用方。

当我从IntelliJ执行它时,该服务运行得非常好[我假设jaxrs jar是从InteliJ的内部存储库中加载的],但是当我从命令行执行jar时失败。例外如下:

[ERROR] RESTEASY002005: Failed executing GET /myapp/getVal
org.jboss.resteasy.core.NoMessageBodyWriterFoundFailure: Could not find MessageBodyWriter for response object of type: com.myproject.model.MyObject of media type: application/json
    at org.jboss.resteasy.core.ServerResponseWriter.lambda$writeNomapResponse$2(ServerResponseWriter.java:104) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.core.interception.ContainerResponseContextImpl.filter(ContainerResponseContextImpl.java:398) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.core.ServerResponseWriter.executeFilters(ServerResponseWriter.java:205) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:82) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:56) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:528) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:459) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:229) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:135) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:355) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:138) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:215) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) ~[myapp-jar-with-dependencies.jar:na]
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) ~[myapp-jar-with-dependencies.jar:na]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:867) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:542) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1345) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:480) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1247) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.server.Server.handle(Server.java:502) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765) ~[myapp-jar-with-dependencies.jar:na]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683) ~[myapp-jar-with-dependencies.jar:na]

我的代码段如下:

父母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 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.myproject</groupId>
  <artifactId>myapp</artifactId>
  <packaging>pom</packaging>
  <version>1.4-SNAPSHOT</version>
  <name>My Application</name>
  <description>My Application</description>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <maven-compiler-plugin.version>3.2</maven-compiler-plugin.version>
    <maven-assembly-plugin.version>2.4</maven-assembly-plugin.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <sonar.jacoco.reportPath>${coverage.reports.dir}/jacoco-unit.exec</sonar.jacoco.reportPath>
    <sonar.jacoco.itReportPath>${coverage.reports.dir}/jacoco-it.exec</sonar.jacoco.itReportPath>
    <sonar.jacoco.agent.jar>${basedir}/target/jacoco-jars/jacocoagent.jar</sonar.jacoco.agent.jar>
    <jacoco.reports.unit.dir>${basedir}/target/jacoco-reports/unit</jacoco.reports.unit.dir>
    <jacoco.reports.it.dir>${basedir}/target/jacoco-reports/it</jacoco.reports.it.dir>
    <coverage.reports.dir>${basedir}/target/coverage-reports</coverage.reports.dir>
    <sonar.dynamic>reuseReports</sonar.dynamic>
    <guice.version>4.1.0</guice.version>
    <java.version>1.8</java.version>
    <log4j.version>1.2.17</log4j.version>
    <jetty.version>9.4.14.v20181114</jetty.version>
    <resteasy.version>3.6.2.Final</resteasy.version>
    <maven.build.timestamp.format>yyyyMMdd'T'HHmm</maven.build.timestamp.format>
  </properties>
  <scm>
    <!-- My scm -->
  </scm>
  <repositories>
    <!-- My repositories -->
  </repositories>
  <modules>
    <module>myChild</module>
  </modules>
  <dependencies>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.1.3</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.1.3</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>log4j-over-slf4j</artifactId>
      <version>1.7.7</version>
    </dependency>
  </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-servlet</artifactId>
        <version>${jetty.version}</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxrs</artifactId>
        <version>${resteasy.version}</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-guice</artifactId>
        <version>${resteasy.version}</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jackson2-provider</artifactId>
        <version>${resteasy.version}</version>
      </dependency>
      <dependency>
        <groupId>com.google.inject.extensions</groupId>
        <artifactId>guice-multibindings</artifactId>
        <version>${guice.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <build>
    <finalName>myapp</finalName>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <archive>
            <manifest>
              <mainClass>com.myproject.main.mainClass</mainClass>
            </manifest>
          </archive>
        </configuration>
        <executions>
          <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-release-plugin</artifactId>
        <version>2.5.3</version>
        <configuration>
          <localCheckout>true</localCheckout>
          <autoVersionSubmodules>true</autoVersionSubmodules>
        </configuration>
      </plugin>

      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.18.1</version>
        <configuration>
          <argLine>-Dfile.encoding=${project.build.sourceEncoding} ${argLine}</argLine>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.3</version>
        <configuration>
          <destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
          <dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
          <append>true</append>
        </configuration>
        <executions>
          <execution>
            <id>agent-for-ut</id>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
          </execution>
          <execution>
            <id>jacoco-site</id>
            <phase>package</phase>
            <goals>
              <goal>report</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

我的孩子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 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <parent>
        <groupId>com.myproject</groupId>
        <artifactId>myapp</artifactId>
    <version>1.4-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.myproject.myapp</groupId>
    <artifactId>myChildApp</artifactId>
    <packaging>jar</packaging>
    <name>myChildApp</name>

    <dependencies>
        <dependency>
            <groupId>commons-cli</groupId>
            <artifactId>commons-cli</artifactId>
            <version>1.3.1</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-guice</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jackson2-provider</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
    </dependencies>
</project>

我的REST API代码如下:


@Path("/myapp")
@Singleton
public class MyResource {

    @GET
    @Path("/getVal")
    @Produces(MediaType.APPLICATION_JSON)
    public MyObject getVal(@QueryParam("id") @NonNull String id) throws Exception {
        try {
            return getMyObjData(id);
        } catch(IllegalArgumentException e) {
            throw new Exception(e.getMessage());
        }
    }
}

我经历了一些类似问题的链接,但没有一个帮助我。例如:

RestEasy: Could not find MessageBodyWriter for response object of type: java.util.ArrayList of media type: application/json

GET request fails with JAX-RS: Could not find MessageBodyWriter for response object of type: java.util.ArrayList of media type: text/html

simple example using resteasy-jaxrs not working

基于我使用IntelliJ进行的调试并在命令行上运行jar,在我看来,即使我添加了jar,但我尝试构建的jar却没有jaxrs的依赖关系(如果我没记错的话)到我的pom上。因此,我不确定如何处理此问题。有人可以帮我这个忙吗?

更新

根据评论,我对父母和孩子的pom进行了如下更新:

父母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 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.myproject</groupId>
  <artifactId>myapp</artifactId>
  <packaging>pom</packaging>
  <version>1.4-SNAPSHOT</version>
  <name>My Application</name>
  <description>My Application</description>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <maven-compiler-plugin.version>3.2</maven-compiler-plugin.version>
    <maven-assembly-plugin.version>2.4</maven-assembly-plugin.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <sonar.jacoco.reportPath>${coverage.reports.dir}/jacoco-unit.exec</sonar.jacoco.reportPath>
    <sonar.jacoco.itReportPath>${coverage.reports.dir}/jacoco-it.exec</sonar.jacoco.itReportPath>
    <sonar.jacoco.agent.jar>${basedir}/target/jacoco-jars/jacocoagent.jar</sonar.jacoco.agent.jar>
    <jacoco.reports.unit.dir>${basedir}/target/jacoco-reports/unit</jacoco.reports.unit.dir>
    <jacoco.reports.it.dir>${basedir}/target/jacoco-reports/it</jacoco.reports.it.dir>
    <coverage.reports.dir>${basedir}/target/coverage-reports</coverage.reports.dir>
    <sonar.dynamic>reuseReports</sonar.dynamic>
    <guice.version>4.1.0</guice.version>
    <java.version>1.8</java.version>
    <log4j.version>1.2.17</log4j.version>
    <jetty.version>9.4.14.v20181114</jetty.version>
    <resteasy.version>3.6.2.Final</resteasy.version>
    <maven.build.timestamp.format>yyyyMMdd'T'HHmm</maven.build.timestamp.format>
  </properties>
  <scm>
    <!-- My scm -->
  </scm>
  <repositories>
    <!-- My repositories -->
  </repositories>
  <modules>
    <module>myChild</module>
  </modules>
  <dependencies>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.1.3</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.1.3</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>log4j-over-slf4j</artifactId>
      <version>1.7.7</version>
    </dependency>
  </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-servlet</artifactId>
        <version>${jetty.version}</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxrs</artifactId>
        <version>${resteasy.version}</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-guice</artifactId>
        <version>${resteasy.version}</version>
      </dependency>
      <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jackson2-provider</artifactId>
        <version>${resteasy.version}</version>
      </dependency>
      <dependency>
        <groupId>com.google.inject.extensions</groupId>
        <artifactId>guice-multibindings</artifactId>
        <version>${guice.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <localCheckout>true</localCheckout>
          <autoVersionSubmodules>true</autoVersionSubmodules>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-release-plugin</artifactId>
        <version>2.5.3</version>
        <configuration>
          <localCheckout>true</localCheckout>
          <autoVersionSubmodules>true</autoVersionSubmodules>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.3</version>
        <configuration>
          <destFile>${basedir}/target/coverage-reports/jacoco-unit.exec</destFile>
          <dataFile>${basedir}/target/coverage-reports/jacoco-unit.exec</dataFile>
          <append>true</append>
        </configuration>
        <executions>
          <execution>
            <id>agent-for-ut</id>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
          </execution>
          <execution>
            <id>jacoco-site</id>
            <phase>package</phase>
            <goals>
              <goal>report</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-checkstyle-plugin</artifactId>
        <version>3.0.0</version>
        <executions>
          <execution>
            <id>validate</id>
            <phase>validate</phase>
            <configuration>
              <configLocation>google_checks.xml</configLocation>
              <encoding>UTF-8</encoding>
              <consoleOutput>true</consoleOutput>
              <failsOnError>true</failsOnError>
              <linkXRef>false</linkXRef>
            </configuration>
            <goals>
              <goal>check</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

儿童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 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <parent>
        <groupId>com.myproject</groupId>
        <artifactId>myapp</artifactId>
    <version>1.4-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.myproject.myapp</groupId>
    <artifactId>myChildApp</artifactId>
    <packaging>jar</packaging>
    <name>myChildApp</name>

    <dependencies>
        <dependency>
            <groupId>commons-cli</groupId>
            <artifactId>commons-cli</artifactId>
            <version>1.3.1</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-guice</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jackson2-provider</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.5.RELEASE</version>
        </dependency>
    </dependencies>

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.2.1</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <filters>
                <filter>
                  <artifact>*:*</artifact>
                  <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                  </excludes>
                </filter>
              </filters>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <mainClass>com.myproject.main.mainClass</mainClass>
                </transformer>
              </transformers>
              <createDependencyReducedPom>false</createDependencyReducedPom>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

即使进行了上述一组更改,我仍然看到相同的错误。

解决方法

问题类似于this one with Jersey,其中服务文件(用于自动注册提供程序)被排除在由maven-assembly-plugin构建的胖罐中。 solution将使用maven-shade-plugin,它具有一个转换器,可将所有服务文件的内容串联到一个uber jar的一个文件中。

,

经过几个小时的调试,我能够找到问题所在。从上面的pom文件可以看出,我正在使用Google Guice for DI。 使用Guice时,我们需要如下所示绑定JacksonProvider:

绑定(JacksonJsonProvider.class)

之所以在我的IDE上为我工作是因为IDE正在从其本地存储库(类路径)中加载必要的依赖项。

这为我解决了这个问题。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...