在开发过程中发现如下的代码在某些情况会出现 java.io.FileNotFoundException: JAR entry lib/bds-portal-1.0.6.jar!/ not found in异常
URI location = RatelTracePortal.class.getProtectionDomain().getCodeSource().getLocation().toURI();
String rootJarPath = location.getSchemeSpecificPart();
if(rootJarPath.indexOf("!/") != -1){
rootJarPath = "jar:" + rootJarPath;
}else {
rootJarPath = "file:" + rootJarPath;
}
JarInputStream jaris = new JarInputStream(new URL(rootJarPath).openConnection().getInputStream());
例如这样的URL: jar:file:/.m2/repository/middleware-plugin-base-1.2.9-SNAPSHOT.jar!/lib/bds-portal-1.0.6.jar!/
java官方默认是不支持嵌套jar的,所以上面的URL默认会报告这个错误,URL的openConnection()实际上被委托给了URLStreamHandler处理,针对不同的协议比如jar,file,http,调用不同的hander。
那么嵌套jar当然需要注册特殊的hander。这段逻辑在JarFile.registerUrlProtocolHandler,代码如下
private static final String PROTOCOL_HANDLER = "java.protocol.handler.pkgs";
private static final String HANDLERS_PACKAGE = "com.alipay.sofa.ark.loader";
public static void registerUrlProtocolHandler() {
String handlers = System.getProperty(PROTOCOL_HANDLER, "");
System.setProperty(PROTOCOL_HANDLER, ("".equals(handlers) ? HANDLERS_PACKAGE
: handlers + "|" + HANDLERS_PACKAGE));
resetCachedUrlHandlers();
}
在应用初始化之前执行JarFile.registerUrlProtocolHandler();就不会再抛java.io.FileNotFoundException了
网友评论