URLStreamHandler 那些事

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home...
    光剑书架上的书阅读 3,918评论 2 8
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,837评论 18 139
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom阅读 2,718评论 0 3
  • 1、【每日一思】建议:问题可以相对有牵引,一方面让大家感受到每日一思对自己的作用,另一方面匹配百日成长营的方向;提...
    我是木心阅读 194评论 0 0
  • 你的前世,是我朝夕相伴的影子。 那一世,我们是人世间最亲密的伴侣,天涯海角,形影不离。 虽然我们相隔着世界上最遥远...
    墨灵卷阅读 133评论 0 0