Search code examples
javaspringspring-bootwar

Trouble using PathMatchingResourcePatternResolver to get src/main/resources in WAR file


I'm using Spring's PathMatchingResourcePatternResolver to attempt to get a list of .jmx files (JMeter tests) that are currently in my src/main/resources directory. This will be hosted as a WAR file on AWS.

When I'm working locally, I have this code block giving me a list of the .jmx files in the resources/ directory, but I know can't use my local file path:

PathMatchingResourcePatternResolver resolver =
                   new PathMatchingResourcePatternResolver(MyClass.class.getClassLoader());
Resource[] resources = resolver.getResources("file:/C:/Users/user.name/repos/my-repo/src/main/resources/dailyTests/*.jmx")

I've been trying to use classpath*: and this actually almost works:

Resource[] resources = resolver.getResources("classpath*:*.jmx");

This will get me all of my .jmx files, with URLs that look like this:

file:/C:/Users/user.name/repos/my-repo/target/classes/my_jmeter_test.jmx

But I need to be able to handle sub directories of the resources directory as well. When I attempt to be more specific, I believe I'm entering incorrect patterns. From what I understand, when using classpath* you still need to use a root directory after classpath*:, but I'm not sure what that should be.

So far I've tried

Resource[] resources = resolver.getResources("classpath*:Users/*.jmx");
Resource[] resources = resolver.getResources("classpath*:classes/*.jmx");
Resource[] resources = resolver.getResources("classpath*:WEB-INF/*.jmx");
Resource[] resources = resolver.getResources("classpath*:com/*.jmx");

And many other guesses, all of which returned 0 resources. It seems when I just get one step more specific, I'm getting 0 resources.

I suppose I might be misunderstanding how I should navigate a WAR file, or possible just misunderstanding what classpath* gets me. Am I completely off here?


Solution

  • Turns out it was my lack of understanding about where src/main/resources ends up in a WAR file when using Maven. Any files in src/main/resources will get copied into the root directory of the WAR file. (noted in the selected answer here).

    When using Spring's PathMatchingResourcePatternResolver, classpath* gets the root of the WAR, so that's why I was getting my .jmx files with this:

     Resource[] resources = resolver.getResources("classpath*:*.jmx");
    

    From there, if my project requires more files in a nested directory such as src/main/resources/specialTest. I can use:

    Resource[] resources = resolver.getResources("classpath*:specialTest/*.jmx");
    

    One thing I'm unsure on, According to the docs:

    WARNING: Note that "classpath*:" when combined with Ant-style patterns will only work reliably with at least one root directory before the pattern starts, unless the actual target files reside in the file system. This means that a pattern like "classpath*:*.xml" will not retrieve files from the root of jar files but rather only from the root of expanded directories.

    I thought this would mean that I wouldn't be able to get files from the root of the WAR file, but that's exactly what I'm doing. Currently it seems that when I use "classpath*:*.jmx" I ONLY get .jmx files from the root directory, and if I want anything deeper, I have to add a root directory to start the pattern. I'll try to update if I fully figure out if that's correct or not.