简体   繁体   English

在一个Maven项目中使用三个版本的第三方Jar的两个版本(存在代码冲突)

[英]using two versions (with code conflicts) of a 3rd party jar in one maven project

Our maven project includes one 3rd third jar, which has two different versions. 我们的maven项目包括一个三分之一的jar,其中有两个不同的版本。

  • A-1.0.jar (with function A() removed in version 2) A-1.0.jar(在版本2中删除了函数A()
  • A-2.0.jar (with function B() added (not in version 1)) A-2.0.jar(添加了函数B() (版本1中未提供))

How to organize my codes to support 1.0's api and 2.0's api at the same time ? 如何组织我的代码以同时支持1.0的api和2.0的api?

A possible way of doing this is to have no dependency on library A (not version 1.0, nor version 2.0) in your project. 一种可行的方法是在项目中不依赖库A(既不是版本1.0,也不是版本2.0)。

You need to create three other build (maven for example) projects / artifacts, which will be wrappers for the different library versions. 您需要创建其他三个构建(例如,Maven)项目/工件,这将是不同库版本的包装。

You'll have : 您将拥有:

  • AbstractWrapper project artifact AbstractWrapper项目工件
  • Wrapper of version 1 artifact 版本1工件的包装
  • Wrapper of version 2 artifact 版本2工件的包装

In the AbstractWrapper, you'll have an interface / abstract class, that reproduce the api from the library A you want to use. 在AbstractWrapper中,您将有一个接口/抽象类,该类从要使用的库A中重现api。 This is the only [of the 3] artifacts that will be declared in the dependencies of your main project. 这是将在主项目的依赖项中声明的[3个项目中的]唯一项目。 This abstract wrapper do not depend on your project, nor on lib A . 这个抽象包装器不依赖于您的项目,也不依赖于lib A

Then each wrapper will depend on AbstractWrapper (to get the interface definition), and on the A library, either version 1 or version 2. 然后,每个包装器将依赖于AbstractWrapper(以获取接口定义)以及A库(版本1或版本2)。

The tricky point now is to get the wrapper implementation (that will be available at runtime) to register in your main project. 现在的棘手点是获取包装器实现(将在运行时提供)以在主项目中注册。 It depends a lot on the packaging and the runtime environnements (standalone jar, osgi bundle, servlet spec 2.5-, servlet spec 3.0+, springframework...), i let you do some research on plugin registration for your specific environnement. 这在很大程度上取决于打包和运行时环境(独立的jar,osgi捆绑包,servlet规范2.5-,servlet规范3.0 +,springframework ...),我让您对特定环境的插件注册进行一些研究。

The ugliest thing you could come up with is a Class.forName() trying both implementation you did, and using the first it finds (casting the class you get to the abstract wrapper interface). 您可能想到的最丑陋的事情是Class.forName()尝试您实现的两个实现,并使用找到的第一个实现(将获得的类广播到抽象包装器接口)。

Finally for the clients using the version 1.0 of the lib A , you tell them to depends on your main project and your wrapper of lib version 1, and the others on your main project and lib version 2. 最后,对于使用lib A版本1.0的客户端,您告诉他们取决于您的主项目和lib版本1的包装器,其他取决于您的主项目和lib版本2。

You can't. 你不能 But you can exclude one or the other version with the tag like this: 但是您可以使用以下标记排除一个或另一个版本:

<dependency>
  <groupId>sample.ProjectB</groupId>
  <artifactId>Project-B</artifactId>
  <version>1.0-SNAPSHOT</version>
  <exclusions>
    <exclusion>
      <groupId>sample.ProjectD</groupId> <!-- Exclude Project-D from Project-B -->
      <artifactId>Project-D</artifactId>
    </exclusion>
  </exclusions>
</dependency>

See the documentation here: https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html 请参阅此处的文档: https : //maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM