Reputation: 47
The test resources aren't been added to classpath when building the project with Maven
The structure of project:
project/pom.xml
/dist/pom.xml
/src/main/resources/db/test.sql
/test/pom.xml
/src/test/com/loader/TestLoader.java
Here is pom.xml of dist module:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>test1</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dist</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>add-test-resource</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Here is pom.xml of test module:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>test1</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>dist</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>
And the JUnit test which tries to read test.sql from dist's module
@RunWith(JUnit4.class)
public class TestLoader {
@Test
public void test() throws Exception {
Path path = Paths.get(ClassLoader.getSystemResource("db/test.sql").toURI());
System.out.println(path.toFile().exists());
}
When I run this test from IDEA, everything is OK, but when I try with command mvn clean install
, I get error that resources are not found.
What could be the error?
Upvotes: 0
Views: 1867
Reputation: 439
ClassLoader.getSystemResource()
will return a different kind of URL depending on how the test class is executed:
Path.get(uri)
is OKPath.get(uri)
throws a FileSystemNotFoundException
The URL is enough to know if the entry exists.
If so, its content can be read using url.openStream()
.
URL url = ClassLoader.getSystemResource("db/test.sql");
if (url == null) {
// File not found
} else {
try (InputStream is = url.openStream()) {
(...)
}
}
Depending on the dist
module's goal, 2 configurations are possible.
dist
is part of an API that will be tested in test
Then no need to use the test-jar
execution goal at all.
dist/pom.xml
: the entire build
section can be removedtest/pom.xml
: fine as it isdist
is dedicated to tests only (in test
module and maybe others)Then, it's more consistent to put the dist
resources in the test directory.
db/test.sql
should be moved to dist/src/test/resources
dist/pom.xml
: the test-jar
part remains, but the build-helper-maven-plugin
becomes useless and can be removedtest/pom.xml
: to make it work, a dependency classifier
is mandatory<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>dist</artifactId>
<version>${project.version}</version>
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
Upvotes: 1