Affects: spring version 5.1.5
Description
Given file /validation/api#test.json within a.jar which is in the classpath...
a project dependent a.jar, in project code
ResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
Resource[] resources22 = resourceLoader.getResources("classpath*:/validation/**/api#test.json");
InputStream inputStream = resources[0].getInputStream();
error:
Exception in thread "main" java.io.FileNotFoundException: JAR entry validation/api not found in a.jar
at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:142)
at sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:150)
at java.net.URL.openStream(URL.java:1038)
Analysis
The URL created in org.springframework.core.io.UrlResource.createRelative(String) treats everything after # as the URL fragment, causing the file path to be incorrect when the file is last read.
URL object:
- file:
a.jar!/validation/api
- path:
a.jar!/validation/api
- ref:
test.json
Solutions
Solution 1
extends PathMatchingResourcePatternResolver
@Override
protected Set<Resource> doFindPathMatchingJarResources() {
....
result.add(rootDirResource.createRelative(ParseUtil.encodePath(relativePath)))
...
}
Solution 2
URL url = resources[0].getURL();
if (ResourceUtils.isJarURL(url) || ResourceUtils.isJarFileURL(url)) {
String parent = url.toExternalForm().substring(0, url.toExternalForm().indexOf("!/validation/") + 13);
String encodeFileName = url.toExternalForm().substring(url.toExternalForm().indexOf("!/validation/") + 13);
String encodeFile = ParseUtil.encodePath(encodeFileName);
URL url21 = new URL(parent + encodeFile);
inputStream = url21.openStream();
} else {
inputStream = resources[0].getInputStream();
}
Question
Is there any other better solution, or is there a problem with my use?
Affects: spring version 5.1.5
Description
Given file
/validation/api#test.jsonwithina.jarwhich is in the classpath...a project dependent a.jar, in project code
error:
Analysis
The
URLcreated inorg.springframework.core.io.UrlResource.createRelative(String)treats everything after#as the URL fragment, causing the file path to be incorrect when the file is last read.URL object:
a.jar!/validation/apia.jar!/validation/apitest.jsonSolutions
Solution 1
Solution 2
Question
Is there any other better solution, or is there a problem with my use?