Gradle 具有 jersey 依赖项的 jar 生成 MessageBodyReader not found for media type=application/json
Gradle jar with jersey dependencies produces MessageBodyReader not found for media type=application/json
我已经编写了一个与第三方服务通信的 Jersey 客户端,如果我从 Eclipse 运行 它可以工作 但它会抛出一个 MessageBodyProviderNotFoundException 如果我 运行 jar 文件。
我的build.gradle:
// Apply the java plugin to add support for Java
apply plugin: 'java'
version = '1.0'
// In this section you declare where to find the dependencies of your project
repositories {
jcenter()
}
//create a single Jar with all dependencies
task createJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'MeteorDesk Whatsapp Images Parser',
'Implementation-Version': version,
'Main-Class': 'controller.ImagesParser'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
// In this section you declare the dependencies for your production and test code
dependencies {
compile 'org.slf4j:slf4j-api:1.7.12'
compile 'org.glassfish.jersey.core:jersey-client:2.22.1'
compile 'org.glassfish.jersey.containers:jersey-container-servlet-core:2.22.1'
compile 'org.glassfish.jersey.media:jersey-media-json-jackson:2.22.1'
compile 'com.google.guava:guava:19.0'
compile 'joda-time:joda-time:2.4'
}
这是例外情况:
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=class model.login.LoginResult, genericType=class model.login.LoginResult.
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:231)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:808)
at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
at org.glassfish.jersey.client.InboundJaxrsResponse.call(InboundJaxrsResponse.java:115)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:419)
at org.glassfish.jersey.client.InboundJaxrsResponse.runInScopeIfPossible(InboundJaxrsResponse.java:267)
at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:112)
at controller.MeteorDeskService.login(MeteorDeskService.java:42)
我从遇到完全相同问题的人那里读到 this post,他的解决方案是改用 Maven,所以我也尝试使用 Maven,但我遇到了同样的异常。
我还可以在生成的 jar 中看到 MessageBodyReader.class。
有人知道为什么会这样吗?
正如@peeskillet 所建议的那样,使用 Maven Shade 插件 成功了,这就是我添加到 pom.xml:
中的内容
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>your main class here</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
+1 给@peeskillet 的啤酒。与构建阴影 jar 的 JMH 性能基准的 Maven 构建有同样的问题。这是pom.xml的相关部分:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${uberjar.name}</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<!-- Shading signed JARs will fail without this. -->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
对于在 gradle 本身寻找解决方案的人,请使用 Shadow plugin。
在 build.gradle.
中添加以下行
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "com.github.jengelman.gradle.plugins:shadow:1.2.4"
}
}
apply plugin: "com.github.johnrengelman.shadow"
shadowJar {
baseName = '__Title__'
mergeServiceFiles() //For Merging Service Descriptor Files
}
我已经编写了一个与第三方服务通信的 Jersey 客户端,如果我从 Eclipse 运行 它可以工作 但它会抛出一个 MessageBodyProviderNotFoundException 如果我 运行 jar 文件。
我的build.gradle:
// Apply the java plugin to add support for Java
apply plugin: 'java'
version = '1.0'
// In this section you declare where to find the dependencies of your project
repositories {
jcenter()
}
//create a single Jar with all dependencies
task createJar(type: Jar) {
manifest {
attributes 'Implementation-Title': 'MeteorDesk Whatsapp Images Parser',
'Implementation-Version': version,
'Main-Class': 'controller.ImagesParser'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
// In this section you declare the dependencies for your production and test code
dependencies {
compile 'org.slf4j:slf4j-api:1.7.12'
compile 'org.glassfish.jersey.core:jersey-client:2.22.1'
compile 'org.glassfish.jersey.containers:jersey-container-servlet-core:2.22.1'
compile 'org.glassfish.jersey.media:jersey-media-json-jackson:2.22.1'
compile 'com.google.guava:guava:19.0'
compile 'joda-time:joda-time:2.4'
}
这是例外情况:
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=application/json, type=class model.login.LoginResult, genericType=class model.login.LoginResult.
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:231)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:808)
at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
at org.glassfish.jersey.client.InboundJaxrsResponse.call(InboundJaxrsResponse.java:115)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:419)
at org.glassfish.jersey.client.InboundJaxrsResponse.runInScopeIfPossible(InboundJaxrsResponse.java:267)
at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:112)
at controller.MeteorDeskService.login(MeteorDeskService.java:42)
我从遇到完全相同问题的人那里读到 this post,他的解决方案是改用 Maven,所以我也尝试使用 Maven,但我遇到了同样的异常。
我还可以在生成的 jar 中看到 MessageBodyReader.class。
有人知道为什么会这样吗?
正如@peeskillet 所建议的那样,使用 Maven Shade 插件 成功了,这就是我添加到 pom.xml:
中的内容<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>your main class here</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
+1 给@peeskillet 的啤酒。与构建阴影 jar 的 JMH 性能基准的 Maven 构建有同样的问题。这是pom.xml的相关部分:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${uberjar.name}</finalName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<!-- Shading signed JARs will fail without this. -->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
对于在 gradle 本身寻找解决方案的人,请使用 Shadow plugin。 在 build.gradle.
中添加以下行buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "com.github.jengelman.gradle.plugins:shadow:1.2.4"
}
}
apply plugin: "com.github.johnrengelman.shadow"
shadowJar {
baseName = '__Title__'
mergeServiceFiles() //For Merging Service Descriptor Files
}