1

我先给你讲个短篇。如果我在 Eclipse 中使用 jar 文件导出我的 jar 文件(Runnable Jar 向导并选择“Package required libraries...”)而不是“Extract required libraries”,那么一切正常,但运行起来非常缓慢。如果我使用提取方法构建我的 jar,代码将导致最终

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/json

我没有使用 Maven。我还不知道。在大多数情况下,我大多对 Eclipse 缺乏经验,但我已经到了那里。我以为 Genson 会给我创建 JSON 所需的东西。

如果我列出我的 jar 文件和 grep 的 MessageBodyWriter,我会得到

1220 Tue Nov 15 10:29:02 CST 2016 javax/ws/rs/ext/MessageBodyWriter.class             
  47 Tue Nov 15 10:29:02 CST 2016 META-INF/services/javax.ws.rs.ext.MessageBodyWriter 

为了获得更长的故事,我在 Eclipse 中创建了一个简单的 Java 项目,将外部 jars 添加到我的构建路径中。Eclipse 不会抱怨缺少任何东西。我的代码中只有一两个关于未使用的 this-and-thats 的警告。无论我怎么做,导出都很好,没有问题。只有处决才会显示出一些恼怒。

在我的请求课程中,我相信我已经正确设置了所有内容。这是可以想象到的最简单的 POST 客户端。我有必要的空构造函数,正确的注释。

@XmlRootElement
@Produces(MediaType.APPLICATION_JSON)

public class QQNotificationRequest {

    @JsonProperty("id")
    private int id;
    @JsonProperty("subId")
    private int subId;
    @JsonProperty("type")
    private int type;
    @JsonProperty("scode")
    private int scode;
    @JsonProperty("datetime")
    private String datetime;
    ...

这是我失败的终极召唤

Response resp = m_webTarget.request(MediaType.APPLICATION_JSON).post(Entity.json(message));

这些是我的外部罐子

javax.ws.rs-api-2.0.1.jar
aopalliance-repackaged-2.5.0-b05.jar
hk2-api-2.5.0-b05.jar
hk2-locator-2.5.0-b05.jar
hk2-utils-2.5.0-b05.jar
javassist-3.20.0-GA.jar
javax.annotation-api-1.2.jar
javax.inject-2.5.0-b05.jar
javax.servlet-api-3.0.1.jar
jaxb-api-2.2.7.jar
jersey-guava-2.24.jar
org.osgi.core-4.2.0.jar
osgi-resource-locator-1.0.1.jar
persistence-api-1.0.jar
validation-api-1.1.0.Final.jar
jersey-client.jar
jersey-common.jar
jersey-container-servlet.jar
jersey-container-servlet-core.jar
jersey-media-jaxb.jar
jersey-server.jar
jargs.jar
genson-1.4.jar
jt400.jar
log4j-api-2.7.jar
log4j-core-2.7.jar

我觉得罐子里有些东西没有正确“导出”,但我不确定。只是在这里猜测,因为 Java 必须经历分解大 jar 中所有 jar 的过程,它会找到开始执行所需的内容,而对于大 jar 中的 .classes,它不会。

暂时迷路了,但还是坚持了下来。我很感激任何指示。

4

1 回答 1

2

问题是META-INF/services每个 Jersey jar 的目录中都有文件,需要在运行时存在。这些文件用于自动加载和注册提供程序类。

当所有的 jars 都分开保存并添加到类路径中时,所有文件都保持完好。但是当您创建一个 jar 时,这些文件会重叠(它们都具有相同的名称),因此每个具有相同名称的文件中只会包含一个。所以 Genson 的文件可能不包括在内。

您可以将 Genson 显式注册为应用程序的提供者。我并没有真正使用 Genson,所以我不确定这样做的正确方法。但是快速浏览代码库,看起来您需要注册GensonJsonConverter.

这可能有效,但不能解决有关服务文件不被包含的主要问题。可能还有其他未注册的自动注册组件。

我不是真正的 Eclipse 用户,所以我不确定如何解决这个问题。我知道,如果您使用的是 Maven,您将使用,如此maven-shade-plugin所述。这个插件所做的是将所有文件内容连接到一个文件中。这将解决问题。

所以我想这只是答案的一半,因为我不确定在使用 Eclipse 时如何做类似的事情。但至少你现在知道问题所在了。

仅供参考,此文件是您主要关心的文件。如果您查看其他 Jersey jars,您会看到有类似的文件。当我说只会使用一个时,这就是我所说的。在构建 jar 时,您需要找到一种方法将它们的内容连接到一个文件中

于 2016-11-15T18:05:33.653 回答