【问题标题】:Upgrading Jackson maven dependency issues升级 Jackson maven 依赖问题
【发布时间】:2015-07-27 15:48:27
【问题描述】:

我正在尝试在我的 Maven 托管 Spring Web 应用程序中将 Jackson 从 1.9.2 升级到 2.5.4。这一切都只是花花公子,但在我们有一个 Windows azure 集成的一个不起眼的角落里爆炸了。

pom.xml 的(我相信)相关部分是:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.5.4</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.5.4</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.5.4</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.module</groupId>
        <artifactId>jackson-module-jaxb-annotations</artifactId>
        <version>2.5.4</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-joda</artifactId>
        <version>2.5.4</version>
    </dependency>

还有:

    <dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure-servicebus</artifactId>
        <version>0.7.0</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure-storage</artifactId>
        <version>2.1.0</version>
        <scope>runtime</scope>
    </dependency>

运行时的异常是:

java.lang.NoClassDefFoundError: org/codehaus/jackson/annotate/JsonUnwrapped
        at org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector.shouldUnwrapProperty(JacksonAnnotationIntrospector.java:153) ~[jackson-mapper-asl-
1.9.2.jar:1.9.2]
        at org.codehaus.jackson.map.deser.BeanDeserializer._resolveUnwrappedProperty(BeanDeserializer.java:515) ~[jackson-mapper-asl-1.9.2.jar:1.9.2]
        at org.codehaus.jackson.map.deser.BeanDeserializer.resolve(BeanDeserializer.java:384) ~[jackson-mapper-asl-1.9.2.jar:1.9.2]
        at org.codehaus.jackson.map.deser.StdDeserializerProvider._resolveDeserializer(StdDeserializerProvider.java:438) ~[jackson-mapper-asl-1.9.2.jar:1.9.2]
        at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCache2(StdDeserializerProvider.java:383) ~[jackson-mapper-asl-1.9.2.jar:1.9.2]
        at org.codehaus.jackson.map.deser.StdDeserializerProvider._createAndCacheValueDeserializer(StdDeserializerProvider.java:321) ~[jackson-mapper-asl-1.9.2
.jar:1.9.2]
        at org.codehaus.jackson.map.deser.StdDeserializerProvider.findValueDeserializer(StdDeserializerProvider.java:167) ~[jackson-mapper-asl-1.9.2.jar:1.9.2]
        at org.codehaus.jackson.map.deser.StdDeserializerProvider.findTypedValueDeserializer(StdDeserializerProvider.java:188) ~[jackson-mapper-asl-1.9.2.jar:1
.9.2]
        at org.codehaus.jackson.map.ObjectMapper._findRootDeserializer(ObjectMapper.java:2820) ~[jackson-mapper-asl-1.9.2.jar:1.9.2]
        at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2719) ~[jackson-mapper-asl-1.9.2.jar:1.9.2]
        at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1926) ~[jackson-mapper-asl-1.9.2.jar:1.9.2]
        at com.microsoft.windowsazure.services.servicebus.implementation.BrokerPropertiesMapper.fromString(BrokerPropertiesMapper.java:37) ~[azure-servicebus-0
.7.0.jar:na]
        at com.microsoft.windowsazure.services.servicebus.implementation.ServiceBusRestProxy.receiveMessage(ServiceBusRestProxy.java:259) ~[azure-servicebus-0.
7.0.jar:na]
        at com.microsoft.windowsazure.services.servicebus.implementation.ServiceBusRestProxy.receiveQueueMessage(ServiceBusRestProxy.java:216) ~[azure-serviceb
us-0.7.0.jar:na]
        at com.microsoft.windowsazure.services.servicebus.implementation.ServiceBusExceptionProcessor.receiveQueueMessage(ServiceBusExceptionProcessor.java:137
) ~[azure-servicebus-0.7.0.jar:na]

我不明白的很大一部分是为什么 Maven 不简单地为 Azure 引入正确的依赖项——从技术上讲,这不是依赖项收敛问题,因为 groupId 和所有内容都从 org.codehaus 更改为 @987654325 @。当我将依赖项切换到运行时范围时,错误消失了,但是我们的 IDE 抱怨依赖项不可用,这是令人望而却步的。

我已尝试明确包含旧版本,但未发生错误。

    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>1.9.13</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.13</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-xc</artifactId>
        <version>1.9.13</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>1.9.13</version>
    </dependency>

我也尝试了排除:

    <!-- Honeywell: AZURE -->
    <!-- Don't let it pull in old jackson -->
    <dependency>
      <groupId>com.microsoft.azure</groupId>
      <artifactId>azure-servicebus</artifactId>
      <version>0.7.0</version>
      <exclusions>
        <exclusion>
          <groupId>org.codehaus.jackson</groupId>
          <artifactId>jackson-jaxrs</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.codehaus.jackson</groupId>
          <artifactId>jackson-mapper-asl</artifactId>
        </exclusion>
        <exclusion>
          <groupId>org.codehaus.jackson</groupId>
          <artifactId>jackson-xc</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure-storage</artifactId>
        <version>2.1.0</version>
        <exclusions>
          <exclusion>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-jaxrs</artifactId>
          </exclusion>
          <exclusion>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
          </exclusion>
          <exclusion>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-xc</artifactId>
          </exclusion>
        </exclusions>
    </dependency>

为什么 mvn 不能处理这种情况?最好的补救方法是什么?

【问题讨论】:

    标签: java spring maven azure jackson


    【解决方案1】:

    如果您查看引发异常的类BrokerPropertiesMapper 的源代码,您会发现它使用了Jackson 类的com.codehaus 版本。如果检查包含此类的 Maven 模块的依赖关系树,可以看到 Jackson 1.9.2 JAR 继承自 jersey-json 依赖关系。

    由于 Azure 服务总线明确依赖于 Jackson 1.9.2 JAR,由于 1.9.x 和 2.x 之间的包结构不同,因此您需要在运行时类路径中使用 1.9.x JAR。

    您还将看到 Azure SDK 项目的 master 分支仍然显式依赖于 Jackson 1.9.2。您可以在项目的 Github 问题跟踪器中提交问题以得到纠正。但是,目前您仍坚持将 Jackson 1.9.2 保留在运行时类路径中。如果您自己的代码直接使用 Jackson,您应该能够将 2.x 和 1.9.x JAR 添加到您的项目中,您的代码使用 Jackson 类的 2.x 版本,而第三方库使用 1.9.x 版本.

    【讨论】:

    • 这是有道理的,并且与我所看到的相吻合,但我想我更大的问题仍然存在:为什么 maven 不自动引入这种依赖关系?如果这些是同一工件的不同版本,我会理解冲突,但我的印象是,要使它们看起来是两个完全不同的工件,因此将两者同时拉入类路径应该非常高兴(就像我现在必须明确地做)。
    • 对我来说很好。我使用this pom.xml file 并在其上运行mvn clean package。在WEB-INF/lib 文件夹中生成一个带有两个Jackson 版本的WAR 文件。你能和你的 POM 比较一下,看看是否有不匹配的地方吗?
    • 不,抱歉,我想我不清楚。这确实有效。我的问题是为什么需要明确指定这两个单独的工件?似乎 azure 的依赖项应该像任何其他依赖项一样自动引入。
    • 如果你看到我的 POM 文件,1.9.x 版本没有明确声明。它们会自动拉入。
    【解决方案2】:

    根据我的经验,Azure Service Bus 使用 Jersey-Json,它的最新版本依赖于 Jackson 1.9.2 jar。您可以在此处查看这些详细信息:https://github.com/Azure/azure-sdk-for-java/blob/master/serviceBus/pom.xmlhttp://mvnrepository.com/artifact/com.sun.jersey/jersey-json/1.19

    虽然您需要在 Spring WebApp 中使用 Jackson 2.5.4,但这与 Azure 使用的 Jackson 版本没有冲突,因为它们具有不同的完整包名。所以用maven管理Java包依赖,只要搞清楚azure包信息,maven会自动安装azure依赖包,比如Jackson的老版本包。

    当我尝试在我的 Eclipse 项目中使用您的第一个 pom.xml 重现您的失败并运行 maven install 命令时,Jackson 1.9.2 jar 已安装。我运行我的程序通过 Azure 服务总线队列发送和接收消息,没有任何错误。

    这是我的 Eclipse 项目的 maven 包列表。

    如有任何疑问,请随时告诉我。

    【讨论】:

      【解决方案3】:

      尽量只保留fastxml jackson版本

      codehaus 是 Jackson 的旧版本。

      例如,在我的例子中,我使用了 documentdb,并且我已经排除了来自 azure deps 的 jackson (asl) 依赖项(它依赖于旧的 jackson codehaus 版本)。

          <dependency>
              <groupId>com.microsoft.azure</groupId>
              <artifactId>azure-documentdb</artifactId>
              <version>1.0.1</version>
              <exclusions>
                  <!-- old jackson library replaced by jackson data-bind -->
                  <exclusion>
                      <groupId>org.codehaus.jackson</groupId>
                      <artifactId>jackson-mapper-asl</artifactId>
                  </exclusion>
              </exclusions>
          </dependency>
      

      使用 Eclipse (pom.xml) 编辑器的依赖管理视图可以帮助检查依赖冲突并使用 &lt;exclude&gt; 修复它

      编辑:我用一个例子来完成我的回答,即使这不能解决你的问题;也许这可以帮助其他 Azure/Jackson 用户解决类似的问题。我不确定,但我认为 jar 冲突可能会导致 NoClassDefFound。

      【讨论】:

      • 对我来说似乎不是&lt;exclude&gt; 问题,因为错误是NoClassDefFound,并且&lt;exclude&gt; 减少了在类路径中找到的类的数量,所以它不会找到一个新课程,但我还是会试一试。
      • 是的,很遗憾,排除项仍然会发生这种情况。
      猜你喜欢
      • 1970-01-01
      • 2021-06-11
      • 2020-04-17
      • 1970-01-01
      • 2021-05-22
      • 2020-10-21
      • 1970-01-01
      • 2015-11-30
      • 2021-12-06
      相关资源
      最近更新 更多