Pascal Knüppel created SUREFIRE-2296: ----------------------------------------
Summary: Classpath-Resource is not correctly resolved Key: SUREFIRE-2296 URL: https://issues.apache.org/jira/browse/SUREFIRE-2296 Project: Maven Surefire Issue Type: Bug Reporter: Pascal Knüppel We got a multi-module project (no jigsaw), and we have a module named "constants". We are using this module as dependency in all other sub-modules. the "constants"-module holds some css-files that we are sharing across two UI modules. And now we wrote unit-tests that prove, that we can serve these resources without authentication by calling the appropriate URL (springboot test). This does not work if the tests are executed with maven. It works from the IDE and I will shortly show some code parts, and explain what is happening: # We start with reading all available css and javascript files that should be accessible. We have standard URL paths for these so we read them dynamically in the unit tests so that the unit tests will adjust themselves: {code:java} public static Stream<Arguments> getAllLoadableResources() { List<String> resourceUrls = new ArrayList<>(); BiConsumer<String, String> addFileUrls = (path, resourceType) -> { final String resourcesPath = path + "/" + resourceType; URL url = ThymeleafConfigTest.class.getResource(resourcesPath); log.warn("\nresourcePath: {}\nurl.path(): {}", resourceType, url == null ? null : url.getPath()); Optional.ofNullable(url).ifPresent(resourceUrl -> { File resourceDirectory = new File(resourceUrl.getPath()); for ( File resourceFile : Objects.requireNonNull(resourceDirectory.listFiles()) ) { resourceUrls.add("/" + resourceType + "/" + resourceFile.getName()); } }); }; final String testResourcesClasspath = "/de/governikus/autent/consent/ui/custom/resources"; addFileUrls.accept(DefaultPaths.COMMON_RESOURCES_PATH, "css"); addFileUrls.accept(ConsentUi.BASE_PATH + "/resources", "css"); addFileUrls.accept(testResourcesClasspath, "css"); addFileUrls.accept(DefaultPaths.COMMON_RESOURCES_PATH, "js"); addFileUrls.accept(ConsentUi.BASE_PATH + "/resources", "js"); addFileUrls.accept(testResourcesClasspath, "js"); addFileUrls.accept(DefaultPaths.COMMON_RESOURCES_PATH, "images"); addFileUrls.accept(ConsentUi.BASE_PATH + "/resources", "images"); addFileUrls.accept(testResourcesClasspath, "images"); MatcherAssert.assertThat(resourceUrls, Matchers.containsInAnyOrder(Matchers.equalTo("/css/bootstrap.min.css"), ...); return resourceUrls.stream().map(Arguments::arguments); } /** * verifies that the expected javascript, images and css files are loadable */ @ParameterizedTest @MethodSource("getAllLoadableResources") void testResourceHandler(String location) { HttpResponse<String> response = getUnirestClient().get(location).asString(); Assertions.assertEquals(HttpStatus.OK, response.getStatus()); }{code} The problematic line is this one: {code:java} ThymeleafConfigTest.class.getResource(resourcesPath); {code} *Why?* The test is part of our module "consent-ui" and it tries to access resources of the module "constants" * If we execute the test within the IDE, the resources are read from the target-directory created when built. * If we execute the test with the maven-surefire-plugin, we get a problem because it tries to read the resources from the jar-file within the ".m2/repository"-directory. _jar:file:/C:/Users/${user-name}/.m2/repository/de/.../constants/3.1.2-SNAPSHOT/constants-3.1.2-SNAPSHOT.jar!/de/.../constants/resources/css_ I am of course not able to retrieve the files from there. _We have added the base-jar and the test-jar of this module to our module:_ {code:java} <dependency> <groupId>de.governikus.autent.crucis</groupId> <artifactId>constants</artifactId> </dependency> <!-- test-dependencies --> <dependency> <groupId>de.governikus.autent.crucis</groupId> <artifactId>constants</artifactId> <type>test-jar</type> <scope>test</scope> </dependency>{code} {_}{_}I am wondering why I am not able to let the path resolve to "${project.parent.basedir}/constants/src/main/resources/...". To achieve that I tried the following: {code:java} <plugin> <groupId>org.apache.maven.plugins</groupId> <!--suppress MavenModelInspection --> <artifactId>maven-surefire-plugin</artifactId> <configuration> <groups>!integration-test</groups> <additionalClasspathElements> <additionalClasspathElement>${project.parent}/constants/target/classes</additionalClasspathElement> <additionalClasspathElement>${project.parent}/constants/target/classes/*</additionalClasspathElement> <additionalClasspathElement>${project.parent}/constants/target/classes/**</additionalClasspathElement> <additionalClasspathElement>${project.parent.basedir}/constants/target/classes</additionalClasspathElement> <additionalClasspathElement>${project.parent.basedir}/constants/target/classes/*</additionalClasspathElement> <additionalClasspathElement>${project.parent.basedir}/constants/target/classes/**</additionalClasspathElement> <additionalClasspathElement>${absolute-path-to-project}/constants/target/classes</additionalClasspathElement> <additionalClasspathElement>${absolute-path-to-project}\constants</additionalClasspathElement> <additionalClasspathElement>${absolute-path-to-project}/constants/target/classes/*</additionalClasspathElement> <additionalClasspathElement>${absolute-path-to-project}/constants/target/classes/**</additionalClasspathElement> </additionalClasspathElements> <useSystemClassLoader>false</useSystemClassLoader> </configuration> </plugin>{code} I tried as many variations as I could to check if it makes a difference But this does not seem to have any effect. If I look at the system-properties, I see this: {code:java} surefire.test.class.path -> ${absolute-path-to-project}\consent-ui\target\test-classes; ${absolute-path-to-project}\consent-ui\target\classes; C:\Users\${user-name}\.m2\repository\de\${class-path}\constants\3.1.2-SNAPSHOT\constants-3.1.2-SNAPSHOT.jar; C:\Users\${user-name}\.m2\repository\org\springframework\boot\spring-boot-starter-web\3.4.4\spring-boot-starter-web-3.4.4.jar; C:\Users\${user-name}\.m2\repository\org\springframework\boot\spring-boot-starter\3.4.4\spring-boot-starter-3.4.4.jar; C:\Users\${user-name}\.m2\repository\org\springframework\boot\spring-boot\3.4.4\spring-boot-3.4.4.jar; C:\Users\${user-name}\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\3.4.4\spring-boot-autoconfigure-3.4.4.jar; C:\Users\${user-name}\.m2\repository\org\springframework\boot\spring-boot-starter-logging\3.4.4\spring-boot-starter-logging-3.4.4.jar; C:\Users\${user-name}\.m2\repository\org\yaml\snakeyaml\2.3\snakeyaml-2.3.jar; C:\Users\${user-name}\.m2\repository\org\springframework\boot\spring-boot-starter-json\3.4.4\spring-boot-starter-json-3.4.4.jar; C:\Users\${user-name}\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\ {code} Is there any way, to adjust the classpath in a way, that I can make surefire read the resources from the target-directory of the sibling-module? -- This message was sent by Atlassian Jira (v8.20.10#820010)