JarInputStream:getNextJarEntry始终返回null [英] JarInputStream: getNextJarEntry always returns null

查看:142
本文介绍了JarInputStream:getNextJarEntry始终返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个I18n助手类,可以通过查看应用程序Jar中文件的名称来找到可用的Locale.

I have an I18n helper class that can find out the available Locales by looking at the name of the files inside the application's Jar.

private static void addLocalesFromJar(List<Locale> locales) throws IOException {
    ProtectionDomain domain = I18n.class.getProtectionDomain();
    CodeSource src = domain.getCodeSource();
    URL url = src.getLocation();
    JarInputStream jar = new JarInputStream(url.openStream());
    while (true) {
        JarEntry entry = jar.getNextJarEntry();
        if (entry == null) {
            break;
        }
        String name = entry.getName();
        // ...
    }
}

当前,这不起作用-jar.getNextJarEntry()似乎总是返回null.我不知道为什么会这样,我只知道url设置为rsrc:./.我从未见过该协议,也找不到任何相关信息.

Currently, this isn't working - jar.getNextJarEntry() seems to always return null. I have no idea why that's happening, all I know is that url is set to rsrc:./. I have never seen that protocol, and couldn't find anything about it.

奇怪的是,这可行:

class Main {
    public static void main(String[] args) {
        URL url = Main.class.getProtectionDomain().getCodeSource().getLocation();
        JarInputStream jar = new JarInputStream(url.openStream());
        while (true) {
            JarEntry entry = jar.getNextJarEntry();
            if (entry == null) {
                break;
            }
            System.out.println(entry.getName());
        }
    }
}

在此版本中,即使它们之间实际上没有区别,url仍正确设置为Jar文件的路径.

In this version, even though there is practically no difference between them, the url is correctly set to the path of the Jar file.

为什么第一个版本不起作用,有什么破坏它?

Why doesn't the first version work, and what is breaking it?

更新:

仅当我不使用Eclipse导出它时,工作示例才真正起作用.在NetBeans中它可以正常工作,但是在Eclipse版本中,URL也被设置为rsrc:./.

The working example really only works if I don't use Eclipse to export it. It worked just fine in NetBeans, but in the Eclipse version the URL got set to rsrc:./ too.

由于我使用Package required libraries into generated JAR库处理功能将其导出,因此Eclipse将其jarinjarloader放入了我的Jar中,因此可以在其中包含所有依赖项.可以与其他设置配合使用,但是有什么方法可以使它们独立于其他设置吗?

Since I exported it with Package required libraries into generated JAR library handling, Eclipse put its jarinjarloader in my Jar so I can have all dependencies inside it. It works fine with the other settings, but is there any way to make this work independently of them?

目前,该类是我的应用程序的一部分,但我计划将其放在单独的库中.在这种情况下,我如何确保它可以与单独的Jars一起使用?

At the moment, that class is part of my application, but I plan to put it in a separate library. In that case, how can I make sure it will work with separate Jars?

推荐答案

问题是Eclipse正在使用jarinjarloader ClassLoader.显然,它使用了自己的自定义rsrc:URL方案来指向存储在主jar文件中的jar文件. URL流处理程序工厂无法理解此方案,因此openStream()方法返回null,这会导致您遇到的问题.

The problem is the jarinjarloader ClassLoader that is being used by Eclipse. Apparently it is using its own custom rsrc: URL scheme to point to jar files stored inside the main jar file. This scheme is not understood by your URL stream handler factory, so the openStream() method returns null which causes the problem that you're seeing.

这回答了您关于独立罐子的问题的第二部分-不仅可以起作用,而且是起作用的唯一方式.您需要更改主应用程序以使用单独的jar,而不是将它们全部捆绑在主jar中.如果要构建Web应用程序,请将其复制到WEB-INF/lib目录中就可以了.如果要构建桌面应用程序,请在META-INF/MANIFEST.MF中将相对路径引用添加到其他jar,当您运行主jar时,它们将自动包含在类路径中.

This answers the second part of your question about separate jars - not only will this work, it's the only way that it will work. You need to change your main application to use separate jars instead of bundling them all up inside the main jar. If you're building a web application, copy them into the WEB-INF/lib directory and you're fine. If you're building a desktop application, add a relative path reference in the META-INF/MANIFEST.MF to the other jars, and they will automatically be included as part of the classpath when you run the main jar.

这篇关于JarInputStream:getNextJarEntry始终返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆