Strange behavior of Class.getResource() and ClassLoader.getResource() in executable jar Strange behavior of Class.getResource() and ClassLoader.getResource() in executable jar java java

Strange behavior of Class.getResource() and ClassLoader.getResource() in executable jar


I thought this question was already asked and answered!

getClass().getResource() searches relative to the .class file while getClass().getClassLoader().getResource() searches relative to the classpath root.

If there's an SSCCE here, I don't understand why it doesn't

1) Show the directory organization in the .jar, and...

2) Take package into consideration

Q: What (if anything) hasn't already been answered by What is the difference between Class.getResource() and ClassLoader.getResource()? (and the links it cites)?

=========================================================================

I'm still not sure what isn't clear, but this example might help:

/*  SAMPLE OUTPUT:  ClassLoader.getResource(/subdir/readme.txt): NULL  Class.getResource(/subdir/readme.txt): SUCCESS  ClassLoader.getResource(subdir/readme.txt): SUCCESS  Class.getResource(subdir/readme.txt): NULL */package com.so.resourcetest;import java.net.URL;public class ResourceTest {    public static void main(String[] args) {        ResourceTest app = new ResourceTest ();    }    public ResourceTest () {        doClassLoaderGetResource ("/subdir/readme.txt");        doClassGetResource ("/subdir/readme.txt");        doClassLoaderGetResource ("subdir/readme.txt");        doClassGetResource ("subdir/readme.txt");    }    private void doClassLoaderGetResource (String sPath) {        URL url  = getClass().getClassLoader().getResource(sPath);        if (url == null)            System.out.println("ClassLoader.getResource(" + sPath + "): NULL");        else            System.out.println("ClassLoader.getResource(" + sPath + "): SUCCESS");    }    private void doClassGetResource (String sPath) {        URL url  = getClass().getResource(sPath);        if (url == null)            System.out.println("Class.getResource(" + sPath + "): NULL");        else            System.out.println("Class.getResource(" + sPath + "): SUCCESS");    }}

Here's the corresponding directory tree. It happens to be an Eclipse project, but the directories are the same regardless if it's Eclipse, Netbeans ... or a .jar file:

C:.├───.settings├───bin│   ├───com│   │   └───so│   │       └───resourcetest│   └───subdir└───src    ├───com    │   └───so    │       └───resourcetest    └───subdir

The file being opened is "subdir/readme.txt"


ADDENDUM 11/9/12:

Hi -

I copied your code verbatim from github, re-compiled and re-ran:

ClassLoader.getResource(/subdir/readme.txt): NULLClass.getResource(/subdir/readme.txt): SUCCESSClassLoader.getResource(subdir/readme.txt): SUCCESSClass.getResource(subdir/readme.txt): NULL

If that's not the output you're getting ... I'm baffled.

For whatever it's worth, I'm running:

  • Eclipse Indigo (it shouldn't matter)

  • Running inside the IDE (it shouldn't matter if it's filesystem or .jar, inside or outside an IDE)

  • My JRE is 1.6 (if anything, this is probably the biggie)

Sorry we haven't been able to resolve what I thought was a straightforward issue :(


ADDENDUM 11/21/12 (Andreas):

Since there was no recent activity on this question, I would like to summarize what we found:

  • From our common understanding, the answer to the above question is: "No, it is not possible that Class.getResource("/path/image.png") returns a valid URL, while ClassLoader.getResource("path/image.png") returns null":
    • We're completely clear on the difference between ClassLoader.getResource() and Class.getResource()
    • Our sample outputs match, for both "SUCCESS" and for "null"
    • The sample outputs match what we'd expect
    • Conclusion: Either we oversaw something, or something different caused the "solution" described in the linked question to work. I think we can not currently prove one or the other.