Unable to get file list from standard resource dir in Maven project with Spring PathMatchingResourcePatternResolver

心已入冬 提交于 2019-12-13 01:59:48

问题


NOTE: As per the accepted solution below, this appears to be realated only to the fact that Spring's DefaultResourceLoader does not use the classloader to create URL instances for resources, thus custom classloaders are ignored

https://jira.spring.io/browse/SPR-8176

I have a standard Maven project, it looks something like this

$ tree
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   
    │   └── resources
    │       └── application.properties
    └── test
        └── java

I will have more resource files shortly in a directory tree under the resources directory, and I would like to loop over them. Following several other posts, I am using the PathMatchingResourcePatternResolver from the Spring Framework. The function I have written to grab all file names is as follows

public static List<File> getAllResourceFiles() {
    PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    Resource[] resources;
    try {
        resources = resolver.getResources("classpath*:.*");
        System.out.println(JsonUtils.objectToJson(resources));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

Where objectToJson is a function that simply uses Jackson to serialize an object. Now when I compile and run this application, I do not get any results. In particular, I do not see application.properties. How do I make this work?

$ java -jar target/MyApp.one-jar.jar
[]

UPDATE: As noted in the comment below, this is using Simon Tuffs' one jar maven plugin. However, the usual way of reading files from the classpath works. Namely

MyClass.class.getResourceAsStream("/application.properties");

UPDATE 2: I tried the following:

resources = resolver.getResources("classpath:**/*.*");

And get this stack trace

java.io.FileNotFoundException: class path resource [] cannot be resolved to URL because it does not exist
at org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java:178)
at org.springframework.core.io.support.PathMatchingResourcePatternResolver.isJarResource(PathMatchingResourcePatternResolver.java:414)
at org.springframework.core.io.support.PathMatchingResourcePatternResolver.findPathMatchingResources(PathMatchingResourcePatternResolver.java:343)
at org.springframework.core.io.support.PathMatchingResourcePatternResolver.getResources(PathMatchingResourcePatternResolver.java:282)
at com.example.utils.ResourceUtils.getAllResourceFiles(ResourceUtils.java:29)
at com.example.Starter.main(Starter.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.simontuffs.onejar.Boot.run(Boot.java:340)
at com.simontuffs.onejar.Boot.main(Boot.java:166)

The code in Starter.java is

public static void main(String[] args) { 
    System.out.println(Environment.getProperty("com.example.applicationLogPath"));
    System.out.println(JsonUtils.objectToJson(ResourceUtils.getAllResourceFiles()));
}

The first line executes successfully and prints the string value of the applicationLogPath property. The second causes the FNF stack trace. The code to get the property uses the standard method for getting an input stream to a file in the jar.

Environment.class.getResourceAsStream("/application.properties");

回答1:


I think the problem is with OneJar. Your project runs just fine if it's used outside the "one-jar" jar, I've tested it (after I commented the JsonUtils parts which were breaking) and I can see the files it's scanning. And it seems others have hit this or similar issue, as well. Also, I am not so sure Spring (through that JIRA issue) will be changed so that the resources will be loaded to please OneJar.




回答2:


What I think you're looking for is

resources = resolver.getResources("classpath:**/*.*");
                                        // ^ don't need the * here

which matches every resource in any nested level with any extension.

What you have

resources = resolver.getResources("classpath*:.*");

matches resources at the root of the classpath with no name but any extension.



来源:https://stackoverflow.com/questions/23094931/unable-to-get-file-list-from-standard-resource-dir-in-maven-project-with-spring

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!