如何强制 JBoss 部署使用特定版本的依赖项而不是已安装的模块?

Posted

技术标签:

【中文标题】如何强制 JBoss 部署使用特定版本的依赖项而不是已安装的模块?【英文标题】:How can I force a JBoss deployment to use a specific version of a dependency instead of installed modules? 【发布时间】:2018-11-17 16:08:20 【问题描述】:

在将 *.ear 部署到 JBoss 时,它总是使用错误版本的 com.fasterxml.jackson.core

我的代码使用的是 com.fasterxml.jackson.core 版本 2.9.0 的功能并且可以正常编译,但是在 JBoss 中调用代码时,我得到了java.lang.NoSuchFieldError

在我看来,JBoss 类加载器使用已安装的 jackson 模块版本 2.5.0。

如何让 JBoss 类加载器使用 2.9.0 版进行部署?

情况

我正在为 Keycloak 开发一个插件,我通过 Keycloak Docker Image 版本 3.2.1 部署它在本地进行测试。

在启动映像之前,通过将其复制到 $JBOSS_HOME/standalone/deployments 来部署耳朵,并且该插件可以正常工作,直到我使用 jackson 2.9 中的功能。

到目前为止我所做的尝试:

我通过 pom.xml 固定版本:

<dependencyManagement>
    <dependencies>
        <dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.0</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

我在 jboss-deployment-structure.xml 中排除了 jackson-modules:

<deployment>
    <dependencies>
        <module name="org.keycloak.keycloak-core" export="true" />
        <module name="org.keycloak.keycloak-server-spi" export="true" />
        <module name="org.keycloak.keycloak-server-spi-private" export="true" />
        <module name="org.keycloak.keycloak-services" export="true" />
        <module name="org.bouncycastle" export="true" />
        <module name="com.google.guava" export="true" />
        <module name="org.jboss.logging" export="true" />
    </dependencies>
    <exclusions>
        <module name="com.fasterxml.jackson.core.jackson-core" />
        <module name="com.fasterxml.jackson.core.jackson-databind" />
        <module name="com.fasterxml.jackson.core.jackson-annotations" />
    </exclusions>
</deployment>

我检查了依赖树:

mvn dependency:tree | grep jackson
[INFO] |  +- com.fasterxml.jackson.core:jackson-core:jar:2.9.0:compile
[INFO] |  \- com.fasterxml.jackson.core:jackson-databind:jar:2.9.0:compile
[INFO] |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile
[INFO]    \- com.github.kittinunf.fuel:fuel-jackson:jar:1.12.0:runtime
[INFO]       +- com.fasterxml.jackson.module:jackson-module-kotlin:jar:2.9.0:runtime
[INFO]    |  +- com.fasterxml.jackson.core:jackson-core:jar:2.9.0:compile
[INFO]    |  \- com.fasterxml.jackson.core:jackson-databind:jar:2.9.0:compile
[INFO]    |     \- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile
[INFO]       \- com.github.kittinunf.fuel:fuel-jackson:jar:1.12.0:runtime
[INFO]          +- com.fasterxml.jackson.module:jackson-module-kotlin:jar:2.9.0:runtime

由于 Keycloak 依赖于它,所以预先安装了 jackson 2.5 库:

find $JBOSS_HOME/modules | grep jackson-core
/opt/jboss/keycloak/modules/system/layers/base/com/fasterxml/jackson/core/jackson-core
/opt/jboss/keycloak/modules/system/layers/base/com/fasterxml/jackson/core/jackson-core/main
/opt/jboss/keycloak/modules/system/layers/base/com/fasterxml/jackson/core/jackson-core/main/module.xml
/opt/jboss/keycloak/modules/system/layers/base/com/fasterxml/jackson/core/jackson-core/main/jackson-core-2.5.4.jar

当我解压缩我的 *.ear 包时,我在 libs/ 中找到正确版本的 jackson-jars(META-INF/MANIFEST.MFBundle-Version: 2.9.0

ls  lib  | grep jackson
jackson-annotations.jar
jackson-core.jar
jackson-databind.jar

谁能向我解释一下,我是否以及如何让 JBoss 使用正确版本的 jackson?

谢谢!

【问题讨论】:

【参考方案1】:

尝试将以下模块添加到&lt;exclusions&gt;

<module name="org.jboss.resteasy.resteasy-jackson2-provider" />
<module name="com.fasterxml.jackson.module.jackson-module-jaxb-annotations" />
<module name="com.fasterxml.jackson.jaxrs.jackson-jaxrs-json-provider" />
<module name="com.fasterxml.jackson.jaxrs.jackson-jaxrs-base" />

【讨论】:

以上是关于如何强制 JBoss 部署使用特定版本的依赖项而不是已安装的模块?的主要内容,如果未能解决你的问题,请参考以下文章

强制 MySQL 从 WHERE IN 子句返回重复项而不使用 JOIN/UNION?

指定 `bin_PROGRAMS` 的依赖项而不告诉 Automake 如何构建 `bin_PROGRAMS`

Leiningen 中的本地依赖项而不创建 Maven 存储库?

列出 R 包依赖项而不安装包

列出python包依赖项而不加载它们?

强制依赖使用特定的子依赖版本