BouncyCastle版本冲突,厂商不合作

BouncyCastle version conflict, vendors not cooperating

由于与 BouncyCastle 的版本冲突,我目前无法集成 Java 个包。

我们内部开发了一个组件来处理使用官方 Java API 发送到我们当地税务局(不是“美国国税局”,而是另一个欧洲国家的同等税务机关)的数据文件由他们提供和维护。我们平台的另一个模块使用来自证书颁发机构的组件来执行文件的认证时间戳。两者都必须集成到部署在客户站点的单个 Web 应用程序中。

如您所知,两个包所依赖的 BouncyCastle 包已经经历了几次 public API 更改,因此后续版本不再与二进制兼容。

Revenue Service 提供“cryptotools.jar”包,它依赖于以下内容:

<dependency org="org.bouncycastle" name="bcprov-jdk15on" rev="1.49"/>
<dependency org="org.bouncycastle" name="bcpkix-jdk15on" rev="1.49"/>

认证机构提供“jades-kernel”时间戳包,它依赖于

<dependency org="org.bouncycastle" name="bcmail-jdk15"     rev="1.45"/>
<dependency org="org.bouncycastle" name="bcprov-jdk15"     rev="1.45"/>
<dependency org="org.bouncycastle" name="bcprov-ext-jdk15" rev="1.45"/>
<dependency org="org.bouncycastle" name="bctsp-jdk15"      rev="1.45"/>

将两个包都放在 classpath 上会导致所有 BouncyCastle 包都被转储到我的 WEB-INF/lib 文件夹中,这通常听起来不错

但是如果我尝试启动包含所有这些包的 Web 应用程序,我会得到一个 Error 说 class 扩展了一个 final 方法。我不会 post 堆栈跟踪,它与我的问题无关

如果我删除 BC 的两个版本(1.45 或 1.49)中的任何一个,其中一个模块将无法编译。好吧,它们都已经编译好了,所以它们不会简单地 link 到它们引用的 classes/methods.

我已将此情况报告给 CA(我们与 Java APIs 签订了维护合同),使用较旧的 BC 版本(存在由 Black Duck 发现的安全漏洞) ,以至于我的客户让我的生活变得痛苦)。 CA 尚未合作。他们需要发布与最新版本的 BouncyCastle 兼容的新版本的密码学API。

我和我的老板(C 级老板)正在将问题升级到 CA 层次结构,根据我们当地的幽默,很快我们将升级到 Francis

说到幽默,请允许我用视觉的方式分享一下我现在的感受

提问时间,现在回到严肃的讨论

假设我们的供应商不合作,或者至少没有及时赶上我们的监管期限。税务局显然不会将他们的 Java API 降级到旧的 BC 版本。

我们如何摆脱这种依赖地狱? 例如,我知道 log4j 有一个“桥接”包来减轻API [之间的中断变化] =57=] 和 2.x 那些尚未升级的软件包的版本。两个依赖不同BC版本的模块如何共存?

我会 post 一个可能的解决方法,但这不是我们的首选解决方案。

解决方法可能是将 Web 应用程序拆分为多个应用程序,每个应用程序部署在不同的上下文中并通过 Web 服务进行通信。辅助应用程序将只是私有的。

时间戳模块将具有旧 BC 版本的类路径,而税务服务模块将具有不同的类路径。 "main" 前端 Web 应用程序将完全不依赖于 BC。

这并不能解决 Black Duck 问题,因为客户将要求升级或需要大量文书工作才能允许策略例外。

本质上 Java 不是为此而构建的,Maven 当然不是(因为有一个潜在的假设,即在解决此类冲突时,任何较新的版本都是旧版本的完美替代品)。

据我了解,您有一个单体应用程序,因此您无法在物理上拆分类路径,您可以从逻辑上进行拆分。

处理此问题的一种方法是 运行 您的应用程序在多个类加载器中,这样 jar 文件就不会 "touch"。我之前问了一个 "how to run in multiple classloaders" 问题 - Want to run non-threadsafe library in parallel - can it be done using multiple classloaders? - 这种方法结合加载一个在类路径上 不是 的 jar 可能是可行的。