我有3个罐子,即jar1,jar2,jar3。
在jar1中有一些代码从类路径中读取文件。但是该文件不会出现在jar1的类路径中。相反,jar2将被插入,因为jar1和jar2类路径的依赖将包含该文件。
我有jar3,它的类路径中也包含相同的文件,但我会在jar1的test
中为jar3声明范围为pom.xml
。
现在,当执行测试用例时,我们怎么能告诉maven始终从jar3(作为测试的范围)类路径获取文件,尽管jar2是作为主要依赖项给出的(范围不是测试)?
这可以通过maven配置文件吗?如果是,我们如何指定它? 或者我们可以使用maven-resources-plugin在测试范围内复制文件吗?
如果在作为依赖项的多个jar中存在相同的文件,那么将如何设置classpath?
示例jar1 pom.xml
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>jar2</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.test</groupId>
<artifactId>jar3</artifactId>
<version>0.1-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
jar2和jar3都有资源文件。
问题:哪个会被接收?为什么?
答案 0 :(得分:1)
如果依赖关系在依赖关系树中处于同一级别,则根据Maven Dependency Mediation doc,pom中的声明顺序将获胜:
请注意,如果两个依赖项版本在依赖关系树中处于相同的深度,那么直到Maven 2.0.8没有定义哪一个会赢,但是从Maven 2.0.9开始,它就是声明中的顺序。计数:第一个声明获胜
因此,在您的情况下,两个依赖项在依赖关系树中处于同一级别(第一级,在POM中声明),compile
范围将在test
范围内出现,因此jar2
会赢,因为你在你的POM中首先声明它(根据你发布的剪辑)。
如果您希望始终从jar3
加载文件,但仅在测试期间加载,只需先在依赖项中声明jar3
即可。它不会影响最终的可交付成果(位于test
范围内),但它会定义类路径的顺序以进行测试,从而为您提供预期的方案。你不需要Maven配置文件。
一个简单的测试用例来验证它:
让我们将属性file.properties
定义为Maven项目的src\main\resources
。项目resource-provider
(artifactId)的文件如下所示:
property=from-resource-provider
如下面的项目resource-provider2
(artifactId):
property=from-resource-provider2
注意:将相同的文件名分成两个具有不同内容的不同项目。
然后在一个消费者项目(resource-consumer
)中,我们可以得到以下示例JUnit测试用例:
public class MainTest {
@Test
public void checkClassPath() {
InputStream is = MainTest.class.getResourceAsStream("/file.properties");
Scanner s = new Scanner(is);
System.out.println(s.nextLine());
}
}
对于resource-consumer
的以下依赖关系:
<dependencies>
<dependency>
<groupId>com.sample</groupId>
<artifactId>resource-provider2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sample</groupId>
<artifactId>resource-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
测试执行的输出将是:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.sample.MainTest
property=from-resource-provider2
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.051 sec
因此,声明的第一个依赖项resource-provider2
赢了(注意范围,test
)。
将依赖关系顺序更改为:
<dependencies>
<dependency>
<groupId>com.sample</groupId>
<artifactId>resource-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.sample</groupId>
<artifactId>resource-provider2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
而是提供以下输出:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.sample.MainTest
property=from-resource-provider
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.07 sec
注意:这次resource-provider
赢了,因为它首先被声明,因为compile
范围也是test
范围的一部分,而事实恰恰相反。