Maven中相同依赖项的多个版本

时间:2014-07-25 18:51:01

标签: maven

是否可以在Maven回购中声明同一依赖的多个版本

我需要同时使用这些依赖项:

    <dependency>
        <groupId>org.bukkit</groupId>
        <artifactId>craftbukkit</artifactId>
        <version>1.7.9-R0.2</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.bukkit</groupId>
        <artifactId>craftbukkit</artifactId>
        <version>1.7.2-R0.3</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.bukkit</groupId>
        <artifactId>craftbukkit</artifactId>
        <version>1.6.4-R2.0</version>
        <scope>compile</scope>
    </dependency>

因为每个包含我关心的不同包:

  

org.bukkit.craftbukkit.v1_6_R3

     

org.bukkit.craftbukkit.v1_7_R1

     

org.bukkit.craftbukkit.v1_7_R3

如果我在第一个片段中声明了依赖关系,则只有最后一个生效。有没有办法在Maven中实现这个目标?

@Edit可能有任何解决方法吗?

6 个答案:

答案 0 :(得分:22)

没有。 Maven将仅解析模块中的一个依赖项,并将省略其他版本以避免任何冲突。即使在整个依赖关系层次结构中使用了相同依赖关系的多个版本,Maven也会使用依赖关系树&#34; 策略中最近的&#34;来选择一个版本。

可以使用不同的profiles指定不同的依赖关系版本。对于Bukkit的每个版本,可以定义和激活配置文件。如果您激活多个配置文件,仍然只使用一个版本。

<profiles>
    <profile>
        <id>Bukkit_1_7_9_R02</id>
        <activation>
            ...
        </activation>
        <dependencies>
            <dependency>
                <groupId>org.bukkit</groupId>
                <artifactId>craftbukkit</artifactId>
                <version>1.7.9-R0.2</version>
                <scope>compile</scope>
            </dependency>
        </dependencies>
    </profile>
    <profile>
        <id>Bukkit_1_7_2_R03</id>
        <activation>
            ...
        </activation>
        <dependencies>
            <dependency>
                <groupId>org.bukkit</groupId>
                <artifactId>craftbukkit</artifactId>
                <version>1.7.2-R0.3</version>
                <scope>compile</scope>
            </dependency>
        </dependencies>
    </profile>
    ...
</profiles>

答案 1 :(得分:1)

不,通常情况下,你不能依赖同一个工件的2个版本 但是你可以包含它们,以便它们最终出现在最终的应用程序中。

该要求有时是有效的 - 例如,当该库的维护很差时,它们会重命名某些包并将其作为同一工件的次要版本发布。然后,其他项目将其作为第三方依赖项,并且在不同的FQCN下需要相同的类。

对于此类情况,您可以使用maven-shade-plugin

  • 使用单个依赖项创建一个maven项目,这是您需要的一个版本。
  • 添加shade插件,让它创建一个带阴影的jar。它基本上会在不同的工件G:A:V。
  • 下重新包装类
  • 为您需要的所有版本执行此操作。
  • 您可以使用分类器来区分着色版本。
  • 在您的项目中,依赖于这些工件。
  • 最后,排除原始依赖项,为其提供“提供”范围。

您可以使用相同的不同变体,最后将这些类放到您的类路径中。例如,使用dependency:copy-dependency插件/目标,并在构建期间将该jar安装到本地存储库。或者将类解压缩到${project.build.outputDirectory}(目标/类)。

答案 2 :(得分:0)

我还很新,但我遇到过与axis2相关的问题是,由于对类进行了更改,各个模块有时需要更早的版本,所以只有顶级依赖项大约有一半。其余的我不得不单独更正poms以获得对不同版本的显式依赖。

也许这种方法对你也有用?让插件具有针对其特定依赖项的模块化组件。

答案 3 :(得分:0)

尝试欺骗行家:

<dependency>
    <groupId>org.bukkit</groupId>
    <artifactId>craftbukkit</artifactId>
    <version>1.7.9-R0.2</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.bukkit.</groupId>
    <artifactId>craftbukkit</artifactId>
    <version>1.7.2-R0.3</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.bukkit..</groupId>
    <artifactId>craftbukkit</artifactId>
    <version>1.6.4-R2.0</version>
    <scope>compile</scope>
</dependency>

答案 4 :(得分:0)

这就是我的解决方法。仅供参考:就我而言,我正在构建RPM。

我使用maven-dependency-plugin将被忽略的较早的依赖项复制到构建目录中的文件夹,然后将该文件复制到暂存区,以便将其包含在RPM中。

以下是复制较早依赖项的代码:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.1.1</version>
    <executions>
      <execution>
        <id>copy-dependencies</id>
        <phase>prepare-package</phase>
        <goals>
          <goal>copy</goal>
        </goals>
        <configuration>
          <artifactItems>
            <artifactItem>
              <groupId>some.package.group.id</groupId>
              <artifactId>someartifact-id</artifactId>
              <version>1.2.3</version>
              <overWrite>false</overWrite>
              <outputDirectory>${project.build.directory}/older-dependencies</outputDirectory>
            </artifactItem>
          </artifactItems>
        </configuration>
      </execution>
    </executions>
  </plugin>

然后,在构建RPM的过程中,我将此脚本集包含在configuration的{​​{1}}部分中。这会将文件复制到RPM的暂存区域:

rpm-maven-plugin

答案 5 :(得分:0)

这里是the Maven documentation的相关部分,它解释了当存在多种可能性时,Maven如何选择依赖项的版本:

依赖性中介-这确定了工件的哪个版本 当遇到多个版本作为依赖项时,将选择。 Maven选择了“最近的定义”。也就是说,它使用的版本 依赖关系树中最接近您的项目的依赖关系。 您始终可以通过在您的显式声明中保证版本 项目的POM。请注意,如果两个依赖项版本相同 在依赖关系树的深度中,第一个声明获胜。 “最近 定义”表示所用版本将是最接近的版本 您的项目在依赖树中。考虑这棵树 依赖项:

A
├── B
│   └── C
│       └── D 2.0
└── E
    └── D 1.0

在文本中,将A,B和C的依赖项定义为A-> B-> C-> D 2.0和A-> E-> D 1.0,然后在构建A时使用D 1.0,因为路径从A到D到E的时间较短。您 可以在A中向D 2.0显式添加一个依赖项以强制使用D 2.0,如下所示:

A
├── B
│   └── C
│       └── D 2.0
├── E
│   └── D 1.0
│
└── D 2.0