I have created a simple service that enables me to listen to incoming REST requests and then perform a task and return the output of the task back to the caller as a custom object (MyObject).
This service runs perfectly fine while I execute it from IntelliJ [i am assuming the jaxrs jar are being loaded from InteliJ's internal repository] but fails when i execute the jar from command line. The exception is as follows:
[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]
My code snippets are as follows:
parent 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>
My child 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>
My REST API code is a follows:
@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());
}
}
}
I have gone through a couple of links with similar issues but none helped me. For example:
simple example using resteasy-jaxrs not working
Based on my debugging with IntelliJ and by running the jar on command line, it appears to me that the jar I am trying to build does not have the dependency of jaxrs (if I am not mistaken) even though I have added them onto my pom. I therefore, am unsure how to proceed with this issue. Can someone help me out with this?
Update:
As per the comment I have updated my parent and child pom as below:
Parent 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>
Child 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>
Even after the above set of changes, I still see the same error.
After a couple of hours of debugging, I was able to find where the issue was. As can be seen in the pom files above, I am making use of Google Guice for DI. While using Guice, we need to bind JacksonProvider as shown below:
bind(JacksonJsonProvider.class)
The reason why it was working for me on my IDE was because the IDE was loading the necessary dependency from its local repository (classpath).
This fixed the issue for me.