在Java中解决传递依赖冲突

6
我正在尝试构建一个Dropwizard(Jersey)REST端点,以与HBase通信。虽然这是我唯一的两个顶级依赖项,但这两个依赖项都加载了许多冲突的传递依赖项。这样冲突的一个简单例子是Google的Guava:
  • HBase客户端指定版本11
  • Dropwizard指定版本18

Dropwizard无法与版本11配合使用,而HBase无法与版本18配合使用。

我已经检查了Maven shade插件文档,但它似乎不能让您重定位在依赖关系中找到的类。因此,除了将这两个组件分离到单独的JVM之外,我不知道如何解决此问题。


你能否提供更多细节,说明为什么每个程序不能运行在升级/降级版本的guava上? - Steve Skrla
冲突非常多,但其中一个让我受不了的是 com.google.common.base.Stopwatch。在版本17和18之间,API发生了变化,却没有任何形式的弃用。 - Dmitry Minkovsky
没有机会分叉HBase并升级依赖吗? - Steve Skrla
2
我发现这篇文章非常有帮助 https://www.elastic.co/blog/to-shade-or-not-to-shade。一直想在这里发布很长时间了。 - Dmitry Minkovsky
2个回答

1

这是一个不太优美的解决方案。但是你可以...

创建一个项目/模块,定义一组服务接口,用于与HBase通信的dropwizard应用程序。

创建另一个模块/项目,实现这些接口并使用HBase类。对此项目进行阴影处理。

在Dropwizard项目中仅包括接口jar,但创建一个任务将阴影处理后的工件复制到资源文件中。

为您的阴影处理的HBase客户端工件创建JARClassLoader。您可能需要创建一个特殊的子类,它不委托给父类,因为默认情况下,类加载器将要求父类解决链接,并可能从外部类加载器中获取更新版本的guava。

向Jar加载器请求服务合同的实例...

Businessing api = Class.forName("com.awesome.Businessing", true, jarLoader).newInstance();


0

尝试在pom.xml文件的<dependencyManagement/>部分中指定这些依赖项的具体版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接