当前位置: 首页 > 知识库问答 >
问题:

从命令行运行jar时的MessageBodyProviderNotFoundException

彭华皓
2023-03-14

我使用Java Jersey框架(与Maven一起使用),并使用IntelliJ作为IDE。我遇到过这个运行时异常,它只发生在尝试从命令行运行代码时(使用maven编译,然后使用Java-JAR),但在IntelliJ中运行时不会发生,这很奇怪。

我有一些Java代码,它将尝试使HTTP访问某个远程URL,并尝试将返回的JSON读入某个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);
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=text/json; charset=utf-8
<dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.23</version>
</dependency>
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class ParseResponse {

   @JsonProperty("id")
   private Integer id;

   ...Other params...
}

正如我之前提到的,奇怪的是,只有当我尝试像这样在命令行上运行时才会发生这种情况,但在IntelliJ中运行时没有错误:

mvn clean package
java -jar target/NameOfJar.jar

我是不是漏掉了一些明显的东西?我在网上看过其他有类似问题的人,但还没有找到解决办法。

谢谢是

共有1个答案

刘承悦
2023-03-14

如果查看jersey-media-json-jacksonjar内部,应该会看到一个文件

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

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

org.glassfish.jersey.jackson.internal.JacksonAutoDiscoverable

Jersey auto-discoverable机制使用该文件自动注册特性,而无需显式注册它们。简单地说,它的工作原理是,所有具有应该自动注册的组件的Jersey模块/jar都应该在jar中具有上述命名文件,其内容是自动发现组件的名称。然后,Jersey将使用服务加载器模式加载文件中命名的类,并注册它们。

当创建uber JAR时,这个问题是你只能有一个文件的副本,不能有重复的副本。那么,如果我们有多个具有上述文件的JAR呢?好吧,这些文件中只有一个将包含在uber jar中。哪一个?谁知道呢,不过只有一个幸运儿。因此,对于其余的罐子,它们的自动发现机制永远不会起作用。Jackson特性就是这种情况,其中自动发现功能注册JacksonFeature。您可以尝试显式注册您的应用程序,您应该看到它现在可以工作了。

但是其他可能有这个文件的JAR/模块呢?正是由于这个原因,在创建uber jar时,您应该使用maven-shade-plugin。这个插件允许你做的,是组合文件的内容,以便所有发现都包含在一个单一的文件中。下面是一个示例用法

<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的入门。您可以查看它以获得进一步的解释。主要的部分涉及ServicesResorteTransformer,它连接服务文件。

 类似资料:
  • 问题内容: 我正在使用Java Jersey框架(与Maven),并使用IntelliJ作为我的IDE。我遇到了这个运行时异常,仅当我尝试从命令行运行代码(使用maven进行编译,然后使用java -jar)时才发生,而在IntelliJ中运行时却没有发生。 我有一些Java代码,这些代码将尝试在某个远程URL上进行HTTP GET,并尝试将返回的JSON读取到某些Lombok POJO中: 我不

  • 问题内容: 好的,我知道这个问题以前已经被问过很多次了,但是我已经搜索了一下,查看了示例,并查看了过去一个月中关于SO的问题,我真的无法解决这个问题。我认为问题是我希望能够从Eclipse和命令行运行该程序。我也在使用OSX,我认为我正在阅读的许多示例都是针对Windows / Linux的。 如果我有一个要在命令行中运行的,在Eclipse中编译的简单程序,请执行以下操作: 我有另一个程序在Ec

  • 问题内容: 到目前为止,我主要使用eclipse。现在,我正在尝试从终端运行Java,但程序包存在问题。 这是我的文件: 我使用编译此代码,然后运行,它给我: 当我删除一切正常。我想念什么? 给出: 问题答案: 您需要在一个目录级别上运行java命令,并以完全合格的软件包名称提供它,例如: 请参阅Java Launcher如何查找用户类 以了解其工作方式。

  • 问题内容: 我开发了OSGi捆绑包,通常通过Eclipse进行测试。在导出捆绑包之后,我得到了bundle.jar文件。我希望能够从命令行运行生成的文件。就像是: C:\ java -jar bundle.jar osgi_framework路径 但是,如何在其中包含osgi框架?而且,如何立即启动捆绑包? 问题答案: 您可以从命令行启动OSGi框架,如下所示。首先是春分: 注意 用VERSION

  • 问题内容: npm 已安装并正在IntelliJ IDEA 15中被积极使用 我的目标是在IntelliJ中为我的TypeScript源代码生成类型,但是我想学习使用Windows命令行,因此我可以显式指定命令行选项,以了解每个选项的作用。我对Googling所发现的与设置和使用它有关的各种花絮感到困惑…我敢肯定,我缺少一些非常基本的知识,那些博客或回答问题的人都认为这是常识。 。 这是我尝试过的

  • 使用 Vert.x ,通常可以直接在 Maven 或 Gradle 项目中添加 Vert.x core 库依赖。 还可以直接从命令行运行 Vert.x verticles。 做到这一点,你需要下载和安装一个 Vert.x ,并将安装的bin目录添加到PATH环境变量。还要确保PATH有 Java 8 JDK. 注意! JDK是需要支持的Java代码的即时编译。 现在可以通过使用vertx run命