You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JBoss EAP 7.4部署的应用中使用自定义Bouncy Castle版本

JBoss EAP 7.4 解决Bouncy Castle版本冲突方案

问题背景

应用打包为EAR(包含WAR、EJB及JAR子模块),内置Bouncy Castle 1.77版本的bcprov-jdk18on-1.77.jar和bcpg-jdk18on-1.77.jar;JBoss EAP 7.4自带1.68版本的对应JAR。版本混合加载触发NoSuchMethodError,栈跟踪如下:

Caused by: java.lang.NoSuchMethodError: org.bouncycastle.crypto.engines.AESEngine.newInstance()Lorg/bouncycastle/crypto/MultiBlockCipher;
at org.bouncycastle.openpgp.operator.bc.BcImplProvider.createBlockCipher(Unknown Source)
at org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder$1.recoverKeyData(Unknown Source)
at org.bouncycastle.openpgp.PGPSecretKey.extractKeyData(Unknown Source)
at org.bouncycastle.openpgp.PGPSecretKey.extractPrivateKey(Unknown Source)

类加载日志确认:

  • bcpg模块的PGPSecretKey、bcprov模块的BcImplProvider来自应用内置1.77版本
  • bcprov模块的BlockCipher和AESEngine来自JBoss自带1.68版本

推测JBoss自身代码先加载了1.68版本类,导致类加载器复用该版本。需要实现类隔离或子优先加载,且满足:

  • Maven构建,BC依赖为compile范围,已正确打包进EAR
  • 已尝试常规jboss-deployment-structure.xml排除模块、设置资源根无效
  • 不修改JBoss服务器配置、不替换自带BC版本

解决方案

1. 修正EAR级jboss-deployment-structure.xml配置

常规排除模块无效,是因为子模块(WAR/EJB)可能未继承排除规则,需要在EAR的META-INF/jboss-deployment-structure.xml中统一配置所有子模块,强制加载应用内置JAR:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
    <!-- 主EAR部署配置 -->
    <deployment>
        <exclude-subsystems>
            <subsystem name="org.bouncycastle"/>
        </exclude-subsystems>
        <exclusions>
            <module name="org.bouncycastle.bcprov"/>
            <module name="org.bouncycastle.bcpg"/>
        </exclusions>
        <!-- 指定应用内置BC JAR为资源根,强制物理源码加载 -->
        <resources>
            <resource-root path="lib/bcprov-jdk18on-1.77.jar" use-physical-code-source="true"/>
            <resource-root path="lib/bcpg-jdk18on-1.77.jar" use-physical-code-source="true"/>
        </resources>
    </deployment>

    <!-- WAR子模块单独配置,确保继承排除规则并依赖EAR的资源 -->
    <sub-deployment name="your-web-module.war">
        <exclusions>
            <module name="org.bouncycastle.bcprov"/>
            <module name="org.bouncycastle.bcpg"/>
        </exclusions>
        <dependencies>
            <module name="deployment.your-ear-name.ear" export="true"/>
        </dependencies>
    </sub-deployment>

    <!-- EJB子模块同理 -->
    <sub-deployment name="your-ejb-module.jar">
        <exclusions>
            <module name="org.bouncycastle.bcprov"/>
            <module name="org.bouncycastle.bcpg"/>
        </exclusions>
        <dependencies>
            <module name="deployment.your-ear-name.ear" export="true"/>
        </dependencies>
    </sub-deployment>
</jboss-deployment-structure>

注意替换your-web-module.war、your-ejb-module.jar、your-ear-name.ear为实际模块名和EAR文件名。

2. 确保Maven打包时BC JAR位置正确

在EAR的pom.xml中,通过maven-ear-plugin将BC JAR打包到EAR的lib目录(对应上述配置的path="lib/..."):

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-ear-plugin</artifactId>
            <version>3.3.0</version>
            <configuration>
                <defaultLibBundleDir>lib</defaultLibBundleDir>
                <modules>
                    <webModule>
                        <groupId>your.group.id</groupId>
                        <artifactId>your-web-module</artifactId>
                        <contextRoot>/your-app</contextRoot>
                    </webModule>
                    <ejbModule>
                        <groupId>your.group.id</groupId>
                        <artifactId>your-ejb-module</artifactId>
                    </ejbModule>
                </modules>
            </configuration>
        </plugin>
    </plugins>
</build>

3. 备选:EAR内部自定义模块隔离

如果上述配置仍无效,可在EAR内部创建自定义模块完全隔离BC版本:

  1. 在EAR的META-INF/modules/org/bouncycastle/main目录下放入bcprov-jdk18on-1.77.jar、bcpg-jdk18on-1.77.jar,并添加module.xml:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.3" name="org.bouncycastle">
    <resources>
        <resource-root path="bcprov-jdk18on-1.77.jar"/>
        <resource-root path="bcpg-jdk18on-1.77.jar"/>
    </resources>
    <dependencies>
        <module name="javax.api"/>
        <module name="javax.security.auth.message.api"/>
    </dependencies>
</module>
  1. 修改jboss-deployment-structure.xml让应用依赖这个自定义模块:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
    <deployment>
        <dependencies>
            <module name="org.bouncycastle" slot="main" export="true" />
        </dependencies>
        <exclusions>
            <module name="org.bouncycastle.bcprov"/>
            <module name="org.bouncycastle.bcpg"/>
        </exclusions>
    </deployment>
</jboss-deployment-structure>

4. 验证效果

部署后,通过JBoss CLI开启类加载日志验证:

/subsystem=logging/logger=org.jboss.modules:write-attribute(name=level,value=DEBUG)

触发业务场景后,检查日志中所有org.bouncycastle开头的类加载来源,确认均来自应用内置的1.77版本JAR。


内容的提问来源于stack exchange,提问作者Mauro Molinari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 18:38:11