URLStreamHandler 那些事

2018-11-15  本文已影响0人  三云_16d2

在开发过程中发现如下的代码在某些情况会出现 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了

参考:
http://mercyblitz.iteye.com/blog/735529

上一篇下一篇

猜你喜欢

热点阅读