简体   繁体   中英

How to Get List of Classpath Resources In Nested Jar?

I have a Maven project, and I am packaging it as a single fat jar using the One-Jar Maven plugin. According to this page on the One-Jar site documentation resource loading must be done in a special manner with One-Jar packaged apps, however that documentation does not cover how to list the resources in a manner which does not depend on their custom class loader.

My question is this: how to I list the contents of the root of my classpath within an inner jar in a packaging agnostic manner, meaning not assuming it will always be in such special packaging? As covered in this SO question , Spring's PathMatchingResourcePatternResolver will not work because Spring's DefaultResourceLoader ignores the classloader.

NOTE: The closest SO question I could find was this question , but this does not address the listing of classpath resources from nested jars.

It can be done in a FAT jar. Your own answer stating it's not possible has a link to a page that shows it's possible! It's not that insane of a solution. Here's a slightly modified version:

private List<String> getResourceFiles(String path) throws IOException
{
    List<String> files = new ArrayList<>();
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    URL dirURL = classLoader.getResource(path);
    if (dirURL.getProtocol().equals("jar"))
    {
        String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!"));
        try (final JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8")))
        {
            Enumeration<JarEntry> entries = jar.entries();
            while (entries.hasMoreElements())
            {
                String name = entries.nextElement().getName();
                if (name.startsWith(path + "/") && !name.endsWith("/"))
                {
                    files.add(name);
                }
            }
        }
        return files;
    }

    // return some other way when not a JAR
}

This version will return the full resource path of any file under the given resource path, recursively. For example, an input of config/rest would return files under that resource folder as:

config/rest/options.properties
config/rest/samples/data.json

With those values, one can get the resource with ClassLoader::getResource , or get the contents of the resource with ClassLoader::getResourceAsStream .

在回顾了许多文章以及博客文章, 网页 ,站点和Spring源代码之后,我得出结论,这只是Java中的一个弱点,不可能以任何理智的方式实现。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM