是否可以在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可能有任何解决方法吗?
答案 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
。
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