如何在 JBoss EAP 7.4 上部署的应用程序中使用您自己的 Bouncy Castle 版本

问题描述 投票:0回答:1

我有一个类加载问题。 我的应用程序捆绑为 EAR,由 WAR + 一些 EJB 和 JAR 子模块组成。 EAR 捆绑了自己版本的 Bouncy Castle 库,恰好是该库的两个模块:

  • bcprov-jdk18on-1.77.jar
  • bcpg-jdk18on-1.77.jar
相反,JBoss EAP 7.4 附带了自己的 Bouncy Castle 版本,其“jdk15on”变体为 1.68。例如,对应的JAR是:

    bcprov-jdk15on-1.68.0.redhat-00005.jar
  • bcpg-jdk15on-1.68.0.redhat-00005.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)
我已经在 JBoss 中启用了类加载器详细日志记录,这就是我所看到的:

2024-02-15 14:22:48,230 TRACE [org.jboss.modules] (Weld Thread Pool -- 1) Finding class org.bouncycastle.openpgp.PGPSecretKey from Module "deployment.myapp-ear.ear.myapp-ejb.jar" from Service Module Loader 2024-02-15 14:22:48,230 TRACE [org.jboss.modules] (Weld Thread Pool -- 1) Finding local class org.bouncycastle.openpgp.PGPSecretKey from Module "deployment.myapp-ear.ear" from Service Module Loader 2024-02-15 14:22:48,230 TRACE [org.jboss.modules] (Weld Thread Pool -- 1) Loading class org.bouncycastle.openpgp.PGPSecretKey locally from Module "deployment.myapp-ear.ear" from Service Module Loader 2024-02-15 14:27:33,162 TRACE [org.jboss.modules] (default task-35) Finding class org.bouncycastle.openpgp.operator.bc.BcImplProvider from Module "deployment.myapp-ear.ear" from Service Module Loader 2024-02-15 14:27:33,162 TRACE [org.jboss.modules] (default task-35) Finding local class org.bouncycastle.openpgp.operator.bc.BcImplProvider from Module "deployment.myapp-ear.ear" from Service Module Loader 2024-02-15 14:27:33,162 TRACE [org.jboss.modules] (default task-35) Loading class org.bouncycastle.openpgp.operator.bc.BcImplProvider locally from Module "deployment.myapp-ear.ear" from Service Module Loader 2024-02-15 14:27:33,162 TRACE [org.jboss.modules] (default task-35) Attempting to define class org.bouncycastle.openpgp.operator.bc.BcImplProvider in Module "deployment.myapp-ear.ear" from Service Module Loader 2024-02-15 14:27:33,162 TRACE [org.jboss.modules.define] (default task-35) Defined class org.bouncycastle.openpgp.operator.bc.BcImplProvider in Module "deployment.myapp-ear.ear" from Service Module Loader 2024-02-15 14:27:33,162 TRACE [org.jboss.modules] (default task-35) Finding local class org.bouncycastle.crypto.BlockCipher from Module "org.bouncycastle.bcprov" version 1.68.0.redhat-00005 from local module loader @4a11eb84 (finder: local module finder @4e858e0a (roots: /opt/rh/eap7/root/usr/share/wildfly/modules,/opt/rh/eap7/root/usr/share/wildfly/modules/system/layers/base)) 2024-02-15 14:27:33,162 TRACE [org.jboss.modules] (default task-35) Loading class org.bouncycastle.crypto.BlockCipher locally from Module "org.bouncycastle.bcprov" version 1.68.0.redhat-00005 from local module loader @4a11eb84 (finder: local module finder @4e858e0a (roots: /opt/rh/eap7/root/usr/share/wildfly/modules,/opt/rh/eap7/root/usr/share/wildfly/modules/system/layers/base)) 2024-02-15 14:27:33,163 TRACE [org.jboss.modules] (default task-35) Attempting to define class org.bouncycastle.crypto.BlockCipher in Module "org.bouncycastle.bcprov" version 1.68.0.redhat-00005 from local module loader @4a11eb84 (finder: local module finder @4e858e0a (roots: /opt/rh/eap7/root/usr/share/wildfly/modules,/opt/rh/eap7/root/usr/share/wildfly/modules/system/layers/base)) 2024-02-15 14:27:33,163 TRACE [org.jboss.modules.define] (default task-35) Defined class org.bouncycastle.crypto.BlockCipher in Module "org.bouncycastle.bcprov" version 1.68.0.redhat-00005 from local module loader @4a11eb84 (finder: local module finder @4e858e0a (roots: /opt/rh/eap7/root/usr/share/wildfly/modules,/opt/rh/eap7/root/usr/share/wildfly/modules/system/layers/base)) 2024-02-15 14:27:33,563 TRACE [org.jboss.modules] (default task-35) Finding class org.bouncycastle.crypto.engines.AESEngine from Module "deployment.myapp-ear.ear" from Service Module Loader 2024-02-15 14:27:33,563 TRACE [org.jboss.modules] (default task-35) Finding local class org.bouncycastle.crypto.engines.AESEngine from Module "org.bouncycastle.bcprov" version 1.68.0.redhat-00005 from local module loader @4a11eb84 (finder: local module finder @4e858e0a (roots: /opt/rh/eap7/root/usr/share/wildfly/modules,/opt/rh/eap7/root/usr/share/wildfly/modules/system/layers/base)) 2024-02-15 14:27:33,564 TRACE [org.jboss.modules] (default task-35) Loading class org.bouncycastle.crypto.engines.AESEngine locally from Module "org.bouncycastle.bcprov" version 1.68.0.redhat-00005 from local module loader @4a11eb84 (finder: local module finder @4e858e0a (roots: /opt/rh/eap7/root/usr/share/wildfly/modules,/opt/rh/eap7/root/usr/share/wildfly/modules/system/layers/base)) 2024-02-15 14:27:33,564 TRACE [org.jboss.modules] (default task-35) Attempting to define class org.bouncycastle.crypto.engines.AESEngine in Module "org.bouncycastle.bcprov" version 1.68.0.redhat-00005 from local module loader @4a11eb84 (finder: local module finder @4e858e0a (roots: /opt/rh/eap7/root/usr/share/wildfly/modules,/opt/rh/eap7/root/usr/share/wildfly/modules/system/layers/base))
所以,正如你所看到的:

bcpg 模块中的
  • PGPSecretKey
     是从我自己的 Bouncy Castle 版本 (1.77) 加载的,捆绑在 EAR 中
    bcprov 模块中的
  • BcImplProvider
     仍然从我自己的 Bouncy Castle 版本 (1.77) 加载,捆绑在 EAR 中
    bcprov 模块中的
  • BlockCipher
    AESEngine
     是从 JBoss 版本的 Bouncy Castle (1.68) 加载的
我怀疑 JBoss 本身的一些代码正在使用 Bouncy Castle 1.68,这导致 JBoss 类加载器在它们已经在内存中时重用其中的类。但我想要实现的是加载运行 JBoss 的类和加载运行我的应用程序的类之间的完全隔离(至少对于这个库而言)。或者在搜索我自己的应用程序尚未请求的课程时至少采用“儿童优先”的方法。

请注意:

    EAR是用Maven构建的; Bouncy Castle 依赖项是编译依赖项,而不是提供的依赖项; BC 1.77 JAR 已正确捆绑在 EAR 中
  • 我已经尝试将
  • org.bouncycastle.bcprov
    org.bouncycastle.bcpg
     放入 
    jboss-deployment-structure.xml
     中排除的依赖项中,但没有成功;但我不希望它被需要,因为 Bouncy Castle 没有被列在
    隐式模块依赖项中,并且似乎是一个私有模块
  • 按照另一个
  • StackOverflow答案给出的建议,我尝试将两个JAR添加为资源根,并将use-physical-code-source
    设置为
    true
    ,再次在
    jboss-deployment-structure.xml
    中,但没有运气
  • 请不要建议将较新的 Bouncy Castle 版本放在 JBoss EAP 的类路径上:我希望我的应用程序使用其捆绑版本而不触及服务器配置,特别是因为其他应用程序可能仍然受益于使用捆绑(和较旧的)Bouncy JBoss EAP 提供的 Castle 版本
jboss wildfly classloader bouncycastle jboss-eap-7
1个回答
0
投票
我的解决方案是为

整个 Bouncy Castle 模块添加排除项,而不仅仅是我正在使用的 Bouncy Castle 子模块(org.bouncycastle.bcprov

org.bouncycastle.bcpg
):

所以在

META-INF/jboss-deployment-structure.xml

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.3"> <ear-exclusions-cascaded-to-subdeployments>true</ear-exclusions-cascaded-to-subdeployments> <deployment> <exclusions> <module name="org.bouncycastle"/> </exclusions> </deployment> </jboss-deployment-structure>

<ear-exclusions-cascaded-to-subdeployments>

 设置为 
true
 我还确保排除适用于所有子模块。

我想这可能是因为在我们的 JBoss EAP 安装中,Bouncy Castle 模块

作为一个整体似乎可用于所有已部署的应用程序。

© www.soinside.com 2019 - 2024. All rights reserved.