【发布时间】:2016-03-05 12:50:39
【问题描述】:
我编写了一个 Jersey 客户端,它与 3rd 方服务通信,如果我从 Eclipse 运行它就可以工作,但如果我运行 jar,它会抛出 MessageBodyProviderNotFoundException文件。
我的 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$1.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。
有人知道为什么会这样吗?
【问题讨论】:
-
我猜 META-INF/services 文件在您创建 fat jar 时会相互覆盖。 META-INF/services 文件是 Jersey 加载许多自动注册功能的方式,包括 Jackson。如果是这种情况,我想是这样,您可以将
JacksonFeature显式注册为Client。 META/services 问题的解决方案是在创建 fat jar 时使用 shade 插件。使用 shade,您可以将同名文件的内容组合在一起,这样它们就不会相互覆盖。我不确定Gradle。我真的不会用它 -
我指的 META-INF/services 文件是
org.glassfish.jersey.internal.spi.AutoDiscoverable文件。不同的 jar 具有相同的文件,它用于自动加载特定于该 jar 的功能。也许您可以创建一个 Gradle 任务来将文件合并为一个。我不知道该怎么做。或者像我提到的那样注册JacksonFeature。但我不确定是否还有其他功能可能会丢失。但如果你只使用客户端,我想这应该不是问题 -
@peeskillet 我花了一段时间,但最后我使用了 maven 的阴影插件,现在它可以工作了。你在同一周救了我两次,我至少欠你一杯啤酒!
-
????干杯!您能否发布您的解决方案作为结束问题的答案,以便其他人受益。我会发布一个答案,但我希望它与阴影示例一起完成,但我没有时间。我相信你的解决方案也会节省其他人的时间:-)
标签: java gradle jersey gradle-eclipse