Listing Resources.

Member
Posts: 67
Joined: 2006.06
Post: #1
I am trying to list all the files in a directory, regardless of the location of that directory (in a jar file, or just a plain system directory). The use of this is dynamically loading resources and not having to change a huge hard-coded list in between versions. So far my code works splendidly when launching from a jar or just launching form the filesystem. All files are found and loaded correctly.

However, when I distribute the jar file via java web start, it has trouble opening the jar file. I think perhaps my understanding of how java web start works is incorrect, and I will post this question in a more appropriate location if I can't figure out out here.

Here is the offending code:
Code:
private String[] getResourceListing(Class classs, String path) throws URISyntaxException, IOException {
        URL dirURL = classs.getResource(path);
        if (dirURL != null && dirURL.getProtocol().equals("file")) {
            /*Plain file, simple to list contents*/
            return new File(dirURL.toURI()).list();
        }
        String me = null;
        if (dirURL == null) {
            /*JAR file.*/
            me = classs.getName().replace(".", "/") + ".class";
            dirURL = classs.getClassLoader().getResource(me);

            if (dirURL.getProtocol().equals("jar")) {
                String internalJarPath = me.substring(0, me.lastIndexOf("/")) + "/" + path;
                String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!"));
                JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"));
                Enumeration<JarEntry> entries = jar.entries();
                Set<String> results = new HashSet<String>();
                JarEntry je;
                while (entries.hasMoreElements()) {
                    je = entries.nextElement();
                    String name =je.getName();
                    if (name.startsWith(internalJarPath) && !je.isDirectory()) {
                        results.add(name.substring(name.lastIndexOf("/")+1));
                    }
                }

                return results.toArray(new String[results.size()]);
            }
        }
        throw new UnsupportedOperationException("Cannot list files for URL "+dirURL);
    }


I think the offending line is:
Code:
JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8"));

I am decently sure the jarPath does not accurately point to the jar file launched when launching via a jnlp file. But finding documentation on that kind of thing, has been like pulling teeth.

Any insight into java web start would be greatly appreciated.

The machine does not run without the coin.
Quote this message in a reply
Moderator
Posts: 453
Joined: 2008.04
Post: #2
I've run into similar issues with Java Web Start. Reclaimed uses automatic class loading systems for certain parts of it's structure, it allows me to drop in new commands (as new .class files) and load them without restarting the server. For example, I implemented a ban command, dropped it into the server, and reloaded those classes when I needed to ban somebody quickly.

However, that didn't work so well on the client side.

I don't know if you're supposed to be able to access the jar files at all like that. I believe it takes all your jar files, unzips them, and allows you to forage through the contents of all of them, mixed together. There don't seem to be any methods in ClassLoader that let you list the resources available. Since time was short during the uDG contest, I never found a better way of doing it, and hardcoded a list of classes I wanted it to load.

It looks like you already know most of this, but (perhaps for others doing jnlp):

http://java.sun.com/j2se/1.5.0/docs/guid...retrieving

If you kind of read between the lines in that section, it hints how the system works.

So, did you actually find a jar file in there?

Howling Moon Software - CrayonBall for Mac and iPhone, Contract Game Dev Work
Quote this message in a reply
Member
Posts: 67
Joined: 2006.06
Post: #3
Hrm, I realize I never actually check to see if dirURL.getProtocol() spits out jar. I'll print that as well as the path and see where that leads.

Edit: OK it is crashing because the path to the jar file that it was launched from is not local. Its the one provided in the jnlp and points to where it was downloaded from. Not particularly helpful.

The machine does not run without the coin.
Quote this message in a reply
Member
Posts: 67
Joined: 2006.06
Post: #4
Double post! For anyone who cares I "resolved" this. I tried about 3 differ work arounds which were not very robust and broke depending on "how the classloader felt"

So I went with just sticking a text file in each directory with instructions about loading the resources Annoyed not ideal but it works.

The machine does not run without the coin.
Quote this message in a reply
Post Reply