同一个依赖的多个版本可以在一个Maven仓库中使用吗?

q7solyqu  于 2023-05-28  发布在  Maven
关注(0)|答案(6)|浏览(515)

Maven repo中是否可以声明同一个依赖的多个版本
我需要这些依赖项一次完成:

<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任何变通方法,也许?

fcipmucu

fcipmucu1#

不可以。Maven只会解析模块中的一个依赖项,并会忽略其他版本以避免任何冲突。即使在整个依赖关系层次结构中使用了同一依赖关系的多个版本,Maven也会使用 “依赖关系树中最近的” 策略来选择一个版本。
可以使用不同的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>
34gzjxbg

34gzjxbg2#

尝试欺骗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>
des4xlb0

des4xlb03#

以下是Maven文档的相关部分,它解释了当存在多个可能性时,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
idv4meu8

idv4meu84#

不,通常情况下,您不能依赖同一工件的两个版本。
但是你可以包括它们,这样它们就可以在最终的应用程序中结束。
这个需求有时候是有效的--例如,当库的维护很差时,他们会重命名一些包,并将其作为同一工件的次要版本发布。然后,其他项目将其作为第三方依赖项,并在不同的FQCN下需要相同的类。
在这种情况下,您可以使用maven-shade-plugin

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

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

m4pnthwp

m4pnthwp5#

我还是个新手,但我在axis2上遇到的问题是,个别模块有时需要一个早期版本,因为它们对类进行了更改,所以顶层依赖只捕获了大约一半。剩下的我不得不单独纠正pom对不同版本的显式依赖。
也许这种方法对你也有效?使插件具有用于其特定依赖关系的模块化组件。

nzk0hqpo

nzk0hqpo6#

我就是这么解决的。FYI:在我的情况下,我正在构建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的过程中,我在rpm-maven-pluginconfiguration部分包含了这个scriptlet。这将把文件复制到RPM的暂存区域:

<installScriptlet>
  <script>cp ${project.build.directory}/older-dependencies/* ${project.build.directory}/rpm/${artifactId}/buildroot${installBase}/</script>
</installScriptlet>

相关问题