在開發(fā)過程中發(fā)現(xiàn)如下的代碼在某些情況會出現(xiàn) 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處理啥繁,針對不同的協(xié)議比如jar,file,http,調(diào)用不同的hander惊畏。
那么嵌套jar當(dāng)然需要注冊特殊的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();
}
在應(yīng)用初始化之前執(zhí)行JarFile.registerUrlProtocolHandler();就不會再拋java.io.FileNotFoundException了