簡體   English   中英

如何從Java應用程序中加載的jar文件中加載資源?

[英]How to load resources from within a jar file loaded in a java application?

因此,我有一個主應用程序,該應用程序應加載一個包含代碼和其他資源(即:jar文件,文本文件,java屬性等)的jar。 我用:

JarFile jar  = new JarFile(jar);
Enumeration<JarEntry> entries = jar.entries();

int URLsize = 1;
while (entries.hasMoreElements())
    if (entries.nextElement().getName().startsWith("foo/bar/foobar"))
        URLsize++;

entries = jar.entries();

URL[] urls = new URL[URLsize];
urls[0] = patch.toURI().toURL();

int count = 1;
while (entries.hasMoreElements())
{
    JarEntry nextElement = entries.nextElement();
    if (nextElement.getName().startsWith("foo/bar/foobar"))
    {               
        urls[count] = new URL("jar:file:/"+ jar.getAbsolutePath() + "!/" + nextElement.getName());

        count++;
    }
}

加載jar的資源,以及URLClassLoader加上一些反射以將所有資源聚集在一起並執行jar的主類,如下所示:

URLClassLoader loader = new URLClassLoader (urls);
Thread.currentThread().setContextClassLoader(loader);

Class<?> jarC = Class.forName ("foo.bar.barfoo.Main", true, loader);
Constructor<?> cons = jarC.getConstructor(String.class, String.class, Properties.class, Properties.class, String[].class);
Object instance = cons.newInstance (systemPath, programPath, config, some_data, args);

Method method = jarC.getMethod ("Main");

method.invoke (instance);

現在的問題是,當我嘗試從罐子內部的包(例如:/ foo / bar / foobar)中加載一堆文件(資源)時,在加載的罐子的代碼內部會引發NullPointerException

private static InputStream getResourceAsStream(String resource) {       
        try {       
            return Thread.currentThread().getContextClassLoader().getResource(resource).openStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

這就是我嘗試獲取與使用BufferedReaderInputStreamReader進行解析相比要獲取包中每個資源名稱的方法。 好的,也許有點太詳細了(這只是我使用getResourceAsStream方法的一種方式),但是我希望我自己明白了, ContextClassLoader不包含我在本身運行此jar的應用程序中加載的資源,所以我需要做些什么才能從裝好的罐子里拿到那些東西?

編輯:調用getResourceAsStream方法:

private static List<String> getResourceFiles(String path) throws IOException {
    List<String> filenames = new ArrayList<>();

    try (
            InputStream in = getResourceAsStream(path);
            BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
        String resource;

        while ((resource = br.readLine()) != null) {
            filenames.add(resource);
        }
    }

    return filenames;
}

在哪里調用getResourceFiles方法:

List<String> names = Foo.getResourceFiles("/foo/bar/foobar");

你為什么還要做這一切? 為什么不將URL從JAR添加到URLClassLoader?

例如

URLClassLoader loader = new URLClassLoader(new File(jar).toURI().toURL());

另外,您可能應該使URLClassLoader具有您當前的類加載器作為父類,例如

URLClassLoader loader = new URLClassLoader(new File(jar).toURI().toURL(), Thread.currentThread().getContextClassLoader());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM