Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Open resource folder inside a lib

ckg
2013-03-06
2013-05-23
  • ckg
    ckg
    2013-03-06

    I'm having trouble accessing resources within one of the packaged libs. I'm attempting to read the entries of a directory inside a jar in the One-Jar's lib folder (i.e. myOneJar.jar!/lib/libjar.jar/folder)

    When the One-Jar is loading, I can see the JarClassLoader informing me that it has found all the files in the folder via a debug message that looks like:

    JarClassLoader: cached bytes for local name lib/libjar.jar/…

    I've tried several ways to access the folder and read the contents with no success:

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    Enumeration<URL> urls = null;
    try {
        urls = classLoader.getResources("folder");
    } catch (Exception e) { e.printStackTrace(); }
    URL testUrl = classLoader.getResources('folder");
    

    None of these work. If I use a path like "folder.fileName.xml", I do get a reference to a file, however, I want to be dynamic about the contents here and not have to change code every time a new resource is added.

    Any suggestions?

     
  • P. Simon Tuffs
    P. Simon Tuffs
    2013-03-07

    I've looked at the code in JarClassLoader and it does seem to be lacking a mechanism to let you do this.  One reason this happens is that JarClassLoader extends ClassLoader and ClassLoader doesn't do anything with the findResources method. URLClassLoader does, and I am now of the opinion that JarClassLoader should actually extend URLClassLoader to straighten out these idiosyncracies.  I will try to retrofit an appropriate discovery mechanism to the findResources method to let you list the files in a path, specified with or without the name of the library jar.

    Simon.

     
  • ckg
    ckg
    2013-03-07

    Thank you for the response.

    For the time being, I'm using the following solution I stumbled across on StackOverflow:

                CodeSource src = ErrorCodeMapping.class.getProtectionDomain().getCodeSource();
                URL url = src.getLocation();
                zip = new ZipInputStream(url.openStream());
                ZipEntry entry = null;
                while ((entry = zip.getNextEntry()) != null) {
                    String entryName = entry.getName();
                    // process as necessary
                }
    
     
  • ckg
    ckg
    2013-03-07

    Where "ErrorCodeMapping" is replaced by your class name :-)

     
  • P. Simon Tuffs
    P. Simon Tuffs
    2013-03-08

    ah, this is a good trick, which works because I made the codesource mechanism work properly with the onejar: protocol handler.  I will look at making the findResources method work in a useful way.