Search code examples
javajarclassloaderarchiveembedded-resource

Can't Retrieve Resources from External Jar File


NOTE: This is a followup to my question here.


I have a program that takes the contents of a directory and bundles everything into a JAR file. The code I use to do this is here:

    try
    {
        FileOutputStream stream = new FileOutputStream(target);
        JarOutputStream jOS = new JarOutputStream(stream);

        LinkedList<File> fileList = new LinkedList<File>();
        buildList(directory, fileList);

        JarEntry jarAdd;

        String basePath = directory.getAbsolutePath();
        byte[] buffer = new byte[4096];
        for(File file : fileList)
        {
            String path = file.getPath().substring(basePath.length() + 1);
            path.replaceAll("\\\\", "/");
            jarAdd = new JarEntry(path);
            jarAdd.setTime(file.lastModified());
            jOS.putNextEntry(jarAdd);

            FileInputStream in = new FileInputStream(file);
            while(true)
            {
                int nRead = in.read(buffer, 0, buffer.length);
                if(nRead <= 0)
                    break;
                jOS.write(buffer, 0, nRead);
            }
            in.close();
        }
        jOS.close();
        stream.close();

So, all is well and good and the jar gets created, and when I explore its contents with 7-zip it has all the files I need. However, when I try to access the contents of the Jar via a URLClassLoader (the jar is not on the classpath and I don't intend it to be), I get null pointer exceptions.

The odd thing is, when I use a Jar that I've exported from Eclipse, I can access the contents of it in the way I want. This leads me to believe that I'm somehow not creating the Jar correctly, and am leaving something out. Is there anything missing from the method up above?


Solution

  • I figured it out based on this question - the problem was me not properly handling backslashes.

    Fixed code is here:

            FileOutputStream stream = new FileOutputStream(target);
            JarOutputStream jOS = new JarOutputStream(stream);
    
            LinkedList<File> fileList = new LinkedList<File>();
            buildList(directory, fileList);
    
            JarEntry entry;
    
            String basePath = directory.getAbsolutePath();
            byte[] buffer = new byte[4096];
            for(File file : fileList)
            {
                String path = file.getPath().substring(basePath.length() + 1);
                path = path.replace("\\", "/");
                entry = new JarEntry(path);
                entry.setTime(file.lastModified());
                jOS.putNextEntry(entry);
                FileInputStream in = new FileInputStream(file);
                while(true)
                {
                    int nRead = in.read(buffer, 0, buffer.length);
                    if(nRead <= 0)
                        break;
                    jOS.write(buffer, 0, nRead);
                }
                in.close();
                jOS.closeEntry();
            }
            jOS.close();
            stream.close();