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)

Reply via email to