How should I use getResource() in Java?

16,349

Solution 1

String clipName = "Chook.wav";

When using getResource, the string you pass in must be either an absolute name or be valid relative to a certain class. Since you're using ClassLoader.getResource() and not Class.getResource(), it must be an absolute path.

Without seeing your actual file hierarchy, I can only guess that "bin" is the root of your compiled classes and resources, and "ibm1260" is a package/folder within that path, and "Chook.wav" exists in that folder. If that's the case, then you need to use /ibm1260/Chook.wav (or potentially ibm1260/Chook.wav, I don't typically use the class loader for resource lookups) as the name of the file that you pass in to getResource().

Either way, you need to make sure that the file is copied into the location of your compiled code and that the root folder is on the classpath.

Solution 2

The getResource and getResourceAsStream methods are for accessing resources on the classpath. You seem to be trying to access some resource that is not on the classpath.

The logic that getResource and getResourceAsStream use to locate resources is essentially the same. The difference between the methods is that one returns a URL, and the other an InputStream.


It just can't be this hard. Any clues?

This is not that hard at all. You just need to understand how classpaths work ... and make sure that you use a resource name that resolves to a resource that you've put in the correct location in one of the directories or JAR files on the classpath.

Or if the resource is not "part of" your application, don't access it this way.

Share:
16,349
Chap
Author by

Chap

Systems Architect

Updated on June 04, 2022

Comments

  • Chap
    Chap almost 2 years

    This question is asked in numerous places, with myriad small variations. (Such as Java - getClassLoader().getResource() driving me bonkers among others.) I still can't make it work.
    Here's a code snippet:

            String clipName = "Chook.wav";
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            // URL url = classLoader.getResource(clipName);
            URL url = new URL("file:///Users/chap/Documents/workspace/the1620/bin/ibm1620/" + clipName);
            ais = AudioSystem.getAudioInputStream(url);
    

    This works -- note that I've hard-coded the path to the directory containing the clip file, which is there, and is in the same directory as my .class file. Alas, the commented-out code just returns a null value for url.

    Most other posts seem to deal with getResourceAsStream(). I think I'm supposed to be using getResource(). Is that making the difference?

    It just can't be this hard. Any clues?

  • Chap
    Chap almost 13 years
    bin/ is the root (it's the default dir created by Eclipse). bin/ibm1620/ is the dir that contains the *.class files, as you correctly guessed. And bin/ibm1620/Chook.wav is the resource. Eclipse copies it to that location. I picked up the "classloader.getResource()" jazz from some other post in SO. That's apparently not what I should be using. Could you flesh out how to use Class.getResource() for me?
  • Mark Peters
    Mark Peters almost 13 years
    @Chap: It should be fine. Did you try my suggestion of using /ibm1260/Chook.wav? What was the result? Note that when I say "it needs to be an absolute path" what I meant was it needs to be fully qualified, just like the fully qualified path of Integer.class would be /java/lang/Integer.class.
  • Mark Peters
    Mark Peters almost 13 years
    On further reading it seems that ibm1260/Chook.wav is the absolute resource name you want.
  • Chap
    Chap almost 13 years
    Well, according to Eclipse settings, the classpath is "the1620". My resources and my class files are all in /Users/chap/Documents/workspace/the1620/bin/ibm1620/. So, are they on the classpath or not?
  • Chap
    Chap almost 13 years
    Yes!! "ibm1620/Chook.wav" worked. So classloader apparently takes one to the root directory for compilation output. Actually I'd prefer to cordon off my "resources" into a separate subdirectory from my .class files, but how I tell Eclipse and/or NetBeans that's what I want is a headache for another evening.
  • Chap
    Chap almost 13 years
    The classpath is "the1620". The ClassLoader seems to look at "the1620/bin". My .class files and resource files are in "the1620/bin/ibm1620". It may not be "hard", but it's sure confusing! ;-)
  • Andrew Thompson
    Andrew Thompson almost 13 years
    @Chap: If Mark's answer solved the problem, please mark it as 'correct'.
  • Stephen C
    Stephen C almost 13 years
    In that case, you should call getResource("/ibm1620/Chook.wav").
  • Chap
    Chap almost 13 years
    I've lost track of what approach we're talking about here, but in the following: ` ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); say(classLoader.toString()); URL url = classLoader.getResource(clipName); ` clipName has to be "ibm1620/Chook.wav" and NOT "/ibm1620/Chook.wav". The latter results in setting url to null. Apologies for the horrific formatting here. I've made my feelings about the editing tools known in META. :-)
  • user3414734
    user3414734 over 9 years
    @MarkPeters can you explain me how this code works ImageIcon icon = new ImageIcon(getClass().getResource("exit.png")) what does getResource and getClass really does in this code .? @Chap