从命令行运行jar时出现MessageBodyProviderNotFoundException [英] MessageBodyProviderNotFoundException while running jar from command line

查看:347
本文介绍了从命令行运行jar时出现MessageBodyProviderNotFoundException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Java Jersey框架(使用Maven),并使用IntelliJ作为我的IDE。我遇到过这个运行时异常,只有在我尝试从命令行运行代码时才会发生(使用maven编译然后运行java -jar)但是在IntelliJ中运行时却没有,这很奇怪。

I am using the Java Jersey framework(with Maven), and use IntelliJ as my IDE. I have encountered this runtime exception that ONLY happens when I try to run the code from the command line (using maven to compile and then java -jar ) but NOT when running within IntelliJ, which is strange.

我有一些Java代码会尝试在某个远程URL上进行HTTP GET并尝试将返回的JSON读入某些Lombok POJO:

I have some Java code that will try to make an HTTP GET on some remote URL and try to read the returned JSON into some Lombok POJO :

String targetUrl = "some valid URL";

WebTarget webTarget = client.target(targetUrl);

Response response = webTarget.request(MediaType.APPLICATION_JSON_TYPE).get();

ParseResponse parseResponse = response.readEntity(ParseResponse.class);

我不知道为什么,但是当它击中执行readEntity()的最后一行时方法,我将得到以下错误:

I am not sure why, but when it hits that last line that does the "readEntity()" method, I will get the error below:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=text/json; charset=utf-8

这很奇怪,因为我肯定有jersey-media-json-jackson我的pom.xml中指定的依赖项:

This is strange, because I definitely have the jersey-media-json-jackson dependency specified in my pom.xml :

<dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.23</version>
</dependency>

这是我尝试将readEntity()转换为我的POJO类:

and this is my POJO class that I was trying to readEntity() into :

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class ParseResponse {

   @JsonProperty("id")
   private Integer id;

   ...Other params...
}

就像我之前提到的那样,奇怪的是,这只发生在我尝试在命令行上运行时,但在IntelliJ中运行时没有错误:

And like I mentioned before, it is strange that this only happens when I try to run on the command line like this but there is no error when running in IntelliJ:

mvn clean package
java -jar target/NameOfJar.jar



<我错过了一些明显的东西吗?我已经在网上看过其他有类似问题的人,但还没有找到解决方案。

Did I miss something obvious here? I have looked at other people with similar issues like this online but haven't found a solution.

谢谢
IS

Thanks IS

推荐答案

如果查看 jersey-media-json-jackson jar,你应该看到一个文件

If you look inside the jersey-media-json-jackson jar you should see a file

META-INF/services/org.glassfish.jersey.internal.spi.AutoDiscoverable

此文件的内容应该是实现文件名的类的单个完全限定名称,即

The contents of this file should be a single fully qualified name of a class that implements the name of the file, namely

org.glassfish.jersey.jackson.internal.JacksonAutoDiscoverable

Jersey 自动发现机制使用此文件自动注册没有我们必须明确注册它们的功能。简而言之,它的工作原理是,所有具有应该自动注册的组件的Jersey模块/ jar应该具有位于jar中的上述命名文件,其内容是可自动发现的组件的名称。然后,Jersey将使用服务加载程序模式加载文件中指定的类,并且注册它们。

This file is used by Jersey auto-discoverable mechanism to automatically register features without us having to explicitly register them. Briefly, how it works, is that all Jersey modules/jars that have components that should be automatically registered, should have the above named file located in the jar, with the contents being the name(s) of the auto-discoverable component. Jersey will then use the Service Loader pattern to load the classes named in the file, and register them.

创建超级罐时导致的问题是你只能拥有一个文件副本,你不能重复。那么如果我们有多个上述文件的罐子怎么办?那么只有其中一个文件将包含在超级jar中。哪一个?谁知道,但只有一个幸运的赢家。因此,对于其余的罐子,他们的自动发现机制永远不会开始。这就是你的Jackson功能的情况,其中可自动发现的注册 JacksonFeature 。您可以尝试显式注册您的应用程序,您应该看到它现在可以正常工作。

The problem this causes when creating uber jars is that you can only have one copy of a file, you can't have duplicates. So what if we have multiple jars with the above file? Well only one of those files will be included in the uber jar. Which one? Who knows, but there is only one lucky winner. So for the rest of the jars, their auto-discover mechanism never kicks in. This is the case with your Jackson feature, where the auto-discoverable registers the JacksonFeature. You can try to explicitly register with your application, and you should see that it now works.

但是可能有这个文件的其他jar /模块怎么样?出于这个原因,在创建超级罐时,您应该使用 maven-shade-plugin 。此插件允许您执行的操作是合并文件的内容,以便所有可发现的内容都包含在该单个文件中。以下是一个示例用法

But what about other jars/modules that may have this file? It's for this reason that when creating uber jars, you should use the maven-shade-plugin. What this plugin allows you to do, is combine the contents of the files so that all the discoverables get included into that one single file. Below is an example usage

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.3</version>
    <configuration>
        <createDependencyReducedPom>true</createDependencyReducedPom>
        <filters>
            <filter>
                <artifact>*:*</artifact>
                <excludes>
                    <exclude>META-INF/*.SF</exclude>
                    <exclude>META-INF/*.DSA</exclude>
                    <exclude>META-INF/*.RSA</exclude>
                </excludes>
            </filter>
        </filters>
    </configuration>
    <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>com.example.YourApp</mainClass>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

这个例子实际上取自 Dropwizard的入门。您可以查看它以获得进一步的解释。关注 ServicesResorceTransformer 的主要部分是连接服务文件的内容。

This example was actually taken from Dropwizard's Getting Started. You can check it out for further explanation. The main part of concern the ServicesResorceTransformer, which is what concatenates the services files.

这篇关于从命令行运行jar时出现MessageBodyProviderNotFoundException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆