Java 未找到Jersy/Jetty服务器的MessageBodyWriter错误

Java 未找到Jersy/Jetty服务器的MessageBodyWriter错误,java,rest,gradle,jersey,jetty,Java,Rest,Gradle,Jersey,Jetty,我一直在跟踪,我喜欢结果。一切正常。但是,如果我运行GradleshadowJar任务来生成一个胖jar文件,这会很好地工作,文件也会运行,但在发出请求时会出现一条错误消息: $ java -jar build/libs/sample-all.jar [main] INFO org.eclipse.jetty.util.log - Logging initialized @161ms to org.eclipse.jetty.util.log.Slf4jLog [main] INFO org.

我一直在跟踪,我喜欢结果。一切正常。但是,如果我运行Gradle
shadowJar
任务来生成一个胖jar文件,这会很好地工作,文件也会运行,但在发出请求时会出现一条错误消息:

$ java -jar build/libs/sample-all.jar 
[main] INFO org.eclipse.jetty.util.log - Logging initialized @161ms to org.eclipse.jetty.util.log.Slf4jLog
[main] INFO org.eclipse.jetty.server.Server - jetty-9.4.z-SNAPSHOT
[main] INFO org.eclipse.jetty.server.handler.ContextHandler - Started o.e.j.s.ServletContextHandler@5824a83d{/,null,AVAILABLE}
[main] INFO org.eclipse.jetty.server.AbstractConnector - Started ServerConnector@2ddc9a9f{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
[main] INFO org.eclipse.jetty.server.Server - Started @1547ms
Dez 12, 2018 10:05:07 PM org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor aroundWriteTo
SCHWERWIEGEND: MessageBodyWriter not found for media type=application/json, type=class com.dovydasvenckus.jersey.greeting.Greeting, genericType=class com.dovydasvenckus.jersey.greeting.Greeting.
所以在我看来,在编译过的JAR中,一些如lib的文件丢失了。我在网上四处查看,每个人都建议添加
org.glassfish.jersey.media:jersey-media-json-jackson:2.27
(或一些变体)使其生效。但这对我不起作用。我的
build.gradle
看起来像:

apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'

sourceCompatibility = 1.8
mainClassName = 'com.dovydasvenckus.jersey.JerseyApplication'

ext {
    slf4jVersion = '1.7.25'
    jettyVersion = '9.4.6.v20170531'
    jerseyVersion = '2.27'
}

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.1'
    }
}

repositories {
    jcenter()
}

dependencies {
    compile "org.slf4j:slf4j-api:${slf4jVersion}"
    compile "org.slf4j:slf4j-simple:${slf4jVersion}"

    compile "org.eclipse.jetty:jetty-server:${jettyVersion}"
    compile "org.eclipse.jetty:jetty-servlet:${jettyVersion}"

    compile "org.glassfish.jersey.core:jersey-server:${jerseyVersion}"
    compile "org.glassfish.jersey.containers:jersey-container-servlet-core:${jerseyVersion}"
    compile "org.glassfish.jersey.containers:jersey-container-jetty-http:${jerseyVersion}"
    compile "org.glassfish.jersey.media:jersey-media-json-jackson:${jerseyVersion}"
    compile "org.glassfish.jersey.inject:jersey-hk2:${jerseyVersion}"

    compile 'org.glassfish.jersey.media:jersey-media-json-jackson:2.27'

    compile "org.glassfish.jersey.media:jersey-media-moxy:2.27"

    compile 'org.glassfish.jersey.media:jersey-media-json-jackson:2.27'

}

jar { manifest { attributes 'Main-Class': "${mainClassName}" } }
有什么想法可以让它工作吗?

如中所述,有一个“服务文件”,即
org.glassfish.jersey.internal.spi.AutoDiscoverable
,它包含在许多jar中。此文件的目的是允许Jersey(和其他第三方)JAR为这些JAR中包含的功能提供一些自动注册。这包括注册
JacksonFeature
,它注册处理(反)序列化的JSON提供程序

创建fat(uber)JAR的问题是这些文件中只能有一个(不能有多个同名文件)。因此,在fat jar中包含所有jar之后,只会包含一个服务文件

对于Maven,我们将使用Maven shade插件,它具有允许转换构建部分的转换器。shade插件有一个
ServicesResourceTransformer
,负责将服务文件的内容连接到一个服务文件中。您用于Gradle的插件具有相同的功能。您可以通过在配置中调用
mergeServiceFiles()
来配置它。我并不真正使用Gradle,但在中也提到,处理服务文件转换和主类清单转换的推荐配置如下

shadowJar{
合并服务文件()
显示{
属性'Main Class':'com.my.Application'
}
}
因此,我假设,通过上述配置,您还可以删除

jar{manifest{attributes'Main Class':“${mainClassName}}”

因为影子插件将负责构建清单。再说一遍,我并没有真正使用Gradle,所以这只是一个假设;但听起来不错。

你在建优步罐吗?如果是这样,那么您需要在应用程序中注册JacksonFeature。有了Maven,我们会的。我不确定格拉德尔的情况会是怎样。我知道有东西在那里,只是不确定它是什么。如果是你正在使用的插件,尝试按照问题中给出的说明。主要是
mergeServiceFiles()
似乎就是您所需要的。从它的名字来看,它听起来像是maven shade插件中的同一个变压器。@PaulSamsotha:是的,我正在构建一个uber jar(或尝试)。我正在使用这个插件:com.github.johnrengelman.shadow,这是非常标准的。这相当于我在链接帖子中提到的Maven插件的服务文件转换器。你可以阅读我的答案,看看为什么需要它。这就是诀窍。谢谢。附言:对于所有其他寻找这个的人来说:确保清除构建文件的缓存。否则它可能无法正常工作。