首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何包含同一依赖项的两个不同版本?

如何包含同一依赖项的两个不同版本?
EN

Stack Overflow用户
提问于 2014-09-23 07:31:38
回答 2查看 2.4K关注 0票数 4

我正在为Java的ERP系统进行定制。在我的定制中,我想使用ApachePOI3.10.1。因此,我已经集成了jars poi-3.10.1-20140818.jar和poi-ooxml-3.10.1-20140818.jar。

然而,这些jars包含了几个类,这些类已经包含在ERP系统的核心代码中,但是有差异。

如果核心ERP类覆盖POI类,则自定义抛出一个Runtime异常。如果POI类覆盖核心类,那么核心功能可能也会发生同样的情况。

处理这种问题的最佳做法是什么?

我的定制是一个相对独立的功能。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-23 08:04:33

解决这个问题有两种方法:

  1. 您可以将库与加载其他版本POI的ClassLoader隔离开来。现在,我假设ERP系统在类路径上,因此需要将库与系统类加载程序隔离开来。您可以通过创建一个URLClassLoader的新实例来做到这一点,然后指向包含更新版本的POI的jar文件。确保还添加了所有瞬态依赖,例如commons,以避免类加载问题。此外,请注意,瞬态依赖可以有瞬态依赖本身。 为了向类加载器隐藏类路径,您可以将引导类加载器设置为由null表示的直接父类: new URLClassLoader(new URL[]{ null(“poi-3.10.1-20140818.jar”),. },null); 使用这个类加载器,您可以通过以下方式查询更新版本的POI类 Class.forName("org.apache.poi.hssf.usermodel.HSSFWorkbook",true,urlClassLoader); 用于撤回新版本的HSSFWorkbook。但是,请注意,任何文本对HSSFWorkbook的直接引用都将由执行类的类加载器解析,这当然会链接到类的旧的、不兼容的版本。因此,您需要对所有代码使用反射。或者,将一个类添加到包含所有逻辑的URLCLassLoader中,并且只通过反射调用该类。一般来说,这是一种更清洁的方法。例如,您可以添加一个实现引导类(如Callable )的类,然后可以从任何不同的上下文中使用该类,例如: 可调用子=(可调用) Class.forName("pkg.Subroutine",true,urlClassLoader);文件convertedFile = sub.call();
  2. 或者,您可以将第二个POI依赖项重新打包到另一个名称空间中。这样做后,类不再冲突,因为它们的名称不再相等。这可能是一种更干净的方法,因为您可以使用来自同一个类加载器的两个库,并且避免反射。 要将依赖项重新打包到另一个名称空间,可以使用像Maven Shade插件这样的工具来帮助您完成此任务。替代方案是扎贾尔 ( 蚂蚁 )或影子插件 ( Gradle )。
票数 10
EN

Stack Overflow用户

发布于 2014-09-23 07:58:37

如果您正在使用Servlet3.0API,并且可以更改某些配置,则可以在这种情况下使用"web片段“。以下是解释:http://www.oracle.com/technetwork/articles/javaee/javaee6overview-part2-136353.html#webfrags

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25989409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档