简写了这样的程序:
import java.io.IOException; import java.net.JarURLConnection; import java.net.URL; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile;
public class TestJar {
public static void main(String[] args) throws IOException { String path = "file:/D:/unpkg/xxx-1.0.jar!/BOOT-INF/classes!/"; String path2 = "file:/D:/Program%20Files%20(x86)/xx/bin/xxx-1.0.jar!/BOOT-INF/classes!/"; invokeRegisterAllConfigToMap(path); System.out.println("--------------"); invokeRegisterAllConfigToMap(path2); } public static void invokeRegisterAllConfigToMap(String path) throws IOException { URL url = new URL("jar:" + path); JarURLConnection jarURLConnection = (JarURLConnection)url.openConnection(); JarFile jarFile = jarURLConnection.getJarFile(); Enumeration entries = jarFile.entries();
while(entries.hasMoreElements()) { JarEntry jarEntry = (JarEntry)entries.nextElement(); String fileName = jarEntry.getName(); //if (fileName.endsWith("properties") && fileName.indexOf("_message_") > 0) { System.out.println(fileName); //} }
}
}
发现不支持最后的!/,去掉就可以。 而在springboot工程里,最后有!/却可以,莫名其妙。
研究半天,发现不一样。
----------------------
(1)参考: https://docs.oracle.com/javase/7/docs/api/java/net/JarURLConnection.html JarURLConnection是A URL Connection to a Java ARchive (JAR) file or an entry in a JAR file.
A Jar entry jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class
A Jar file jar:http://www.foo.com/bar/baz.jar!/
A Jar directory jar:http://www.foo.com/bar/baz.jar!/COM/foo/
!/ 是分隔符。
只有jar后面有个!/。
(2)spring扩展了它,org.springframework.boot.loader.jar.JarURLConnection 支持俩!/吗? jar:http://www.foo.com/bar/baz.jar!/COM/foo!/这种?
(3) 在spring boot里执行时 URL url = new URL("jar:" + path); JarURLConnection jarURLConnection = (JarURLConnection)url.openConnection();
实际走的: org.springframework.boot.loader.jar.Handler --------------- @Override protected URLConnection openConnection(URL url) throws IOException { if (this.jarFile != null && isUrlInJarFile(url, this.jarFile)) { return JarURLConnection.get(url, this.jarFile); } try { return JarURLConnection.get(url, getRootJarFileFromUrl(url)); } catch (Exception ex) { return openFallbackConnection(url, ex); } } --------------- 大概意思,应该是出错了,就转为兜底的Connection了,也就是java的 sun.net.www.protocol.jar.JarURLConnection
(4)当路径没有空格时,是没问题的,正常执行。 jarURLConnection实际是org.springframework.boot.loader.jar.JarURLConnection。
(5)当路径有空格时,转为兜底的sun.net.www.protocol.jar.JarURLConnection。 然后它不支持两个分隔符,就会报错。坑爹。
(6)怎么解决?
|