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

was*_*sup 27 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>
Run Code Online (Sandbox Code Playgroud)

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

org.bukkit.craftbukkit.v1_6_R3

org.bukkit.craftbukkit.v1_7_R1

org.bukkit.craftbukkit.v1_7_R3

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

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

man*_*uti 25

不会.Maven只会解析您模块中的一个依赖项,并会省略其他版本以避免任何冲突.即使在整个依赖关系层次结构中使用了相同依赖关系的多个版本,Maven也会使用"依赖关系树中最近的"策略选择一个版本.

可以使用不同的配置文件指定不同的依赖关系版本.对于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>
Run Code Online (Sandbox Code Playgroud)


小智 16

尝试欺骗 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>
Run Code Online (Sandbox Code Playgroud)

  • 这实在是太可怕了。只是不要这样做。有很多更清洁的解决方案。 (5认同)
  • @Dmitri 你能解释一下这个作弊行家是怎么回事吗?为什么你在 groupId 中添加了一个额外的点?最终的结果会是什么?人们应该期待什么? (4认同)

Ste*_*ers 16

以下是Maven 文档的相关部分,它解释了当存在多种可能性时 Maven 如何选择依赖项的版本:

\n
\n

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

\n
A\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 B\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 C\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 D 2.0\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 E\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 D 1.0\n
Run Code Online (Sandbox Code Playgroud)\n

在文本中,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\n2.0,如下所示:

\n
A\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 B\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 C\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 D 2.0\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 E\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 D 1.0\n\xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 D 2.0\n
Run Code Online (Sandbox Code Playgroud)\n
\n


Ond*_*žka 5

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

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

对于这种情况,您可以例如使用maven-shade-plugin.

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

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