Preferred way of loading resources in Java












92















I would like to know the best way of loading a resource in Java:





  • this.getClass().getResource() (or getResourceAsStream()),


  • Thread.currentThread().getContextClassLoader().getResource(name),


  • System.class.getResource(name).










share|improve this question





























    92















    I would like to know the best way of loading a resource in Java:





    • this.getClass().getResource() (or getResourceAsStream()),


    • Thread.currentThread().getContextClassLoader().getResource(name),


    • System.class.getResource(name).










    share|improve this question



























      92












      92








      92


      51






      I would like to know the best way of loading a resource in Java:





      • this.getClass().getResource() (or getResourceAsStream()),


      • Thread.currentThread().getContextClassLoader().getResource(name),


      • System.class.getResource(name).










      share|improve this question
















      I would like to know the best way of loading a resource in Java:





      • this.getClass().getResource() (or getResourceAsStream()),


      • Thread.currentThread().getContextClassLoader().getResource(name),


      • System.class.getResource(name).







      java resources






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Oct 5 '10 at 8:38









      Michael Petrotta

      51.9k13127171




      51.9k13127171










      asked Oct 5 '10 at 8:27









      PomCompotPomCompot

      1,92222328




      1,92222328
























          5 Answers
          5






          active

          oldest

          votes


















          124














          Work out the solution according to what you want...



          There are two things that getResource/getResourceAsStream() will get from the class it is called on...




          1. The class loader

          2. The starting location


          So if you do



          this.getClass().getResource("foo.txt");


          it will attempt to load foo.txt from the same package as the "this" class and with the class loader of the "this" class. If you put a "/" in front then you are absolutely referencing the resource.



          this.getClass().getResource("/x/y/z/foo.txt")


          will load the resource from the class loader of "this" and from the x.y.z package (it will need to be in the same directory as classes in that package).



          Thread.currentThread().getContextClassLoader().getResource(name)


          will load with the context class loader but will not resolve the name according to any package (it must be absolutely referenced)



          System.class.getResource(name)


          Will load the resource with the system class loader (it would have to be absolutely referenced as well, as you won't be able to put anything into the java.lang package (the package of System).



          Just take a look at the source. Also indicates that getResourceAsStream just calls "openStream" on the URL returned from getResource and returns that.






          share|improve this answer


























          • AFAIK packages names don't matter, it's the classpath of the class loader that does.

            – Bart van Heukelom
            Oct 5 '10 at 9:47











          • @Bart if you look at the source code you'll notice that the class name does matter when you call getResource on a class. The first thing this call does is call "resolveName" which adds the package prefix if appropriate. Javadoc for resolveName is "Add a package name prefix if the name is not absolute Remove leading "/" if name is absolute"

            – Michael Wiles
            Oct 5 '10 at 10:22








          • 9





            Ah, I see. Absolute here means relative to the classpath, rather than filesystem absolute.

            – Bart van Heukelom
            Oct 5 '10 at 11:55






          • 1





            I just want to add that you should always check that the stream returned from getResourceAsStream() is not null, because it will be if the resource is not within the classpath.

            – stenix
            Oct 22 '15 at 11:25











          • Also worth noting is that using the context class loader allows the classloader to be changed at runtime via Thread#setContextClassLoader. This is useful if you need to modify the classpath while the program is executing.

            – Max
            Jan 26 '16 at 17:06



















          13














          Well, it partly depends what you want to happen if you're actually in a derived class.



          For example, suppose SuperClass is in A.jar and SubClass is in B.jar, and you're executing code in an instance method declared in SuperClass but where this refers to an instance of SubClass. If you use this.getClass().getResource() it will look relative to SubClass, in B.jar. I suspect that's usually not what's required.



          Personally I'd probably use Foo.class.getResourceAsStream(name) most often - if you already know the name of the resource you're after, and you're sure of where it is relative to Foo, that's the most robust way of doing it IMO.



          Of course there are times when that's not what you want, too: judge each case on its merits. It's just the "I know this resource is bundled with this class" is the most common one I've run into.






          share|improve this answer


























          • skeet: a doubt in the statement "you're executing code in an instance method of SuperClass but where this refers to an instance of SubClass" if we are executing statements inside instance method of super class then "this" will refer to the superclass not the subclass.

            – Dead Programmer
            Oct 5 '10 at 8:55











          • @Suresh: No it won't. Try it! Create two classes, making one derive from the other, and then in the superclass print out this.getClass(). Create an instance of the subclass and call the method... it'll print out the name of the subclass, not the superclass.

            – Jon Skeet
            Oct 5 '10 at 9:01











          • thanks subclass instance method calls the method of superclass.

            – Dead Programmer
            Oct 5 '10 at 9:15






          • 1





            What I'm wondering about is whether using this.getResourceAsStream will only be able to load a resource from the same jar as the this clas is from and not from another jar. By my reckoning, it's the class loader that loads the resource and surely won't be confined from loading from only the one jar?

            – Michael Wiles
            Oct 5 '10 at 12:44



















          9














          I search three places as shown below. Comments welcome.



          public URL getResource(String resource){

          URL url ;

          //Try with the Thread Context Loader.
          ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
          if(classLoader != null){
          url = classLoader.getResource(resource);
          if(url != null){
          return url;
          }
          }

          //Let's now try with the classloader that loaded this class.
          classLoader = Loader.class.getClassLoader();
          if(classLoader != null){
          url = classLoader.getResource(resource);
          if(url != null){
          return url;
          }
          }

          //Last ditch attempt. Get the resource from the classpath.
          return ClassLoader.getSystemResource(resource);
          }





          share|improve this answer
























          • Thanks, this is a great idea. Just what I needed.

            – devo
            May 9 '12 at 17:31






          • 1





            I was looking at the comments in your code and the last one sounds interesting. Aren't all resources loaded from the classpath? And what cases would the ClassLoader.getSystemResource() cover that the above didn't succeeded?

            – nyxz
            Feb 15 '15 at 12:25













          • In all honesty, I don't get why you would want to load files from 3 different places. Don't you know where your files are stored ?

            – bvdb
            Jun 7 '17 at 11:46



















          1














          I know it really late for another answer but I just wanted to share what helped me at the end. It will also load resources/files from the absolute path of the file system (not only the classpath's).



          public class ResourceLoader {

          public static URL getResource(String resource) {
          final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
          classLoaders.add(Thread.currentThread().getContextClassLoader());
          classLoaders.add(ResourceLoader.class.getClassLoader());

          for (ClassLoader classLoader : classLoaders) {
          final URL url = getResourceWith(classLoader, resource);
          if (url != null) {
          return url;
          }
          }

          final URL systemResource = ClassLoader.getSystemResource(resource);
          if (systemResource != null) {
          return systemResource;
          } else {
          try {
          return new File(resource).toURI().toURL();
          } catch (MalformedURLException e) {
          return null;
          }
          }
          }

          private static URL getResourceWith(ClassLoader classLoader, String resource) {
          if (classLoader != null) {
          return classLoader.getResource(resource);
          }
          return null;
          }

          }





          share|improve this answer































            -1














            I tried a lot of ways and functions that suggested above, but they didn't work in my project. Anyway I have found solution and here it is:



            try {
            InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png");
            img = ImageIO.read(path);
            } catch (IOException e) {
            e.printStackTrace();
            }





            share|improve this answer
























            • You should better use this.getClass().getResourceAsStream() in this case. If you get a look at the source of the getResourceAsStream method, you will notice that it does the same thing than you but in a smarter way (fallback if no ClassLoader can be found on the class). It also indicates that you can encounter a potential null on getClassLoader in your code …

              – PomCompot
              May 26 '17 at 7:33













            • @PromCompot, as I said this.getClass().getResourceAsStream() is not working for me, so I use that works. I think there are some people who can face with problem like mine.

              – Vladislav
              May 27 '17 at 23:03











            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3861989%2fpreferred-way-of-loading-resources-in-java%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            5 Answers
            5






            active

            oldest

            votes








            5 Answers
            5






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            124














            Work out the solution according to what you want...



            There are two things that getResource/getResourceAsStream() will get from the class it is called on...




            1. The class loader

            2. The starting location


            So if you do



            this.getClass().getResource("foo.txt");


            it will attempt to load foo.txt from the same package as the "this" class and with the class loader of the "this" class. If you put a "/" in front then you are absolutely referencing the resource.



            this.getClass().getResource("/x/y/z/foo.txt")


            will load the resource from the class loader of "this" and from the x.y.z package (it will need to be in the same directory as classes in that package).



            Thread.currentThread().getContextClassLoader().getResource(name)


            will load with the context class loader but will not resolve the name according to any package (it must be absolutely referenced)



            System.class.getResource(name)


            Will load the resource with the system class loader (it would have to be absolutely referenced as well, as you won't be able to put anything into the java.lang package (the package of System).



            Just take a look at the source. Also indicates that getResourceAsStream just calls "openStream" on the URL returned from getResource and returns that.






            share|improve this answer


























            • AFAIK packages names don't matter, it's the classpath of the class loader that does.

              – Bart van Heukelom
              Oct 5 '10 at 9:47











            • @Bart if you look at the source code you'll notice that the class name does matter when you call getResource on a class. The first thing this call does is call "resolveName" which adds the package prefix if appropriate. Javadoc for resolveName is "Add a package name prefix if the name is not absolute Remove leading "/" if name is absolute"

              – Michael Wiles
              Oct 5 '10 at 10:22








            • 9





              Ah, I see. Absolute here means relative to the classpath, rather than filesystem absolute.

              – Bart van Heukelom
              Oct 5 '10 at 11:55






            • 1





              I just want to add that you should always check that the stream returned from getResourceAsStream() is not null, because it will be if the resource is not within the classpath.

              – stenix
              Oct 22 '15 at 11:25











            • Also worth noting is that using the context class loader allows the classloader to be changed at runtime via Thread#setContextClassLoader. This is useful if you need to modify the classpath while the program is executing.

              – Max
              Jan 26 '16 at 17:06
















            124














            Work out the solution according to what you want...



            There are two things that getResource/getResourceAsStream() will get from the class it is called on...




            1. The class loader

            2. The starting location


            So if you do



            this.getClass().getResource("foo.txt");


            it will attempt to load foo.txt from the same package as the "this" class and with the class loader of the "this" class. If you put a "/" in front then you are absolutely referencing the resource.



            this.getClass().getResource("/x/y/z/foo.txt")


            will load the resource from the class loader of "this" and from the x.y.z package (it will need to be in the same directory as classes in that package).



            Thread.currentThread().getContextClassLoader().getResource(name)


            will load with the context class loader but will not resolve the name according to any package (it must be absolutely referenced)



            System.class.getResource(name)


            Will load the resource with the system class loader (it would have to be absolutely referenced as well, as you won't be able to put anything into the java.lang package (the package of System).



            Just take a look at the source. Also indicates that getResourceAsStream just calls "openStream" on the URL returned from getResource and returns that.






            share|improve this answer


























            • AFAIK packages names don't matter, it's the classpath of the class loader that does.

              – Bart van Heukelom
              Oct 5 '10 at 9:47











            • @Bart if you look at the source code you'll notice that the class name does matter when you call getResource on a class. The first thing this call does is call "resolveName" which adds the package prefix if appropriate. Javadoc for resolveName is "Add a package name prefix if the name is not absolute Remove leading "/" if name is absolute"

              – Michael Wiles
              Oct 5 '10 at 10:22








            • 9





              Ah, I see. Absolute here means relative to the classpath, rather than filesystem absolute.

              – Bart van Heukelom
              Oct 5 '10 at 11:55






            • 1





              I just want to add that you should always check that the stream returned from getResourceAsStream() is not null, because it will be if the resource is not within the classpath.

              – stenix
              Oct 22 '15 at 11:25











            • Also worth noting is that using the context class loader allows the classloader to be changed at runtime via Thread#setContextClassLoader. This is useful if you need to modify the classpath while the program is executing.

              – Max
              Jan 26 '16 at 17:06














            124












            124








            124







            Work out the solution according to what you want...



            There are two things that getResource/getResourceAsStream() will get from the class it is called on...




            1. The class loader

            2. The starting location


            So if you do



            this.getClass().getResource("foo.txt");


            it will attempt to load foo.txt from the same package as the "this" class and with the class loader of the "this" class. If you put a "/" in front then you are absolutely referencing the resource.



            this.getClass().getResource("/x/y/z/foo.txt")


            will load the resource from the class loader of "this" and from the x.y.z package (it will need to be in the same directory as classes in that package).



            Thread.currentThread().getContextClassLoader().getResource(name)


            will load with the context class loader but will not resolve the name according to any package (it must be absolutely referenced)



            System.class.getResource(name)


            Will load the resource with the system class loader (it would have to be absolutely referenced as well, as you won't be able to put anything into the java.lang package (the package of System).



            Just take a look at the source. Also indicates that getResourceAsStream just calls "openStream" on the URL returned from getResource and returns that.






            share|improve this answer















            Work out the solution according to what you want...



            There are two things that getResource/getResourceAsStream() will get from the class it is called on...




            1. The class loader

            2. The starting location


            So if you do



            this.getClass().getResource("foo.txt");


            it will attempt to load foo.txt from the same package as the "this" class and with the class loader of the "this" class. If you put a "/" in front then you are absolutely referencing the resource.



            this.getClass().getResource("/x/y/z/foo.txt")


            will load the resource from the class loader of "this" and from the x.y.z package (it will need to be in the same directory as classes in that package).



            Thread.currentThread().getContextClassLoader().getResource(name)


            will load with the context class loader but will not resolve the name according to any package (it must be absolutely referenced)



            System.class.getResource(name)


            Will load the resource with the system class loader (it would have to be absolutely referenced as well, as you won't be able to put anything into the java.lang package (the package of System).



            Just take a look at the source. Also indicates that getResourceAsStream just calls "openStream" on the URL returned from getResource and returns that.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jul 5 '16 at 21:02









            mkobit

            21.2k689103




            21.2k689103










            answered Oct 5 '10 at 8:48









            Michael WilesMichael Wiles

            14.8k165692




            14.8k165692













            • AFAIK packages names don't matter, it's the classpath of the class loader that does.

              – Bart van Heukelom
              Oct 5 '10 at 9:47











            • @Bart if you look at the source code you'll notice that the class name does matter when you call getResource on a class. The first thing this call does is call "resolveName" which adds the package prefix if appropriate. Javadoc for resolveName is "Add a package name prefix if the name is not absolute Remove leading "/" if name is absolute"

              – Michael Wiles
              Oct 5 '10 at 10:22








            • 9





              Ah, I see. Absolute here means relative to the classpath, rather than filesystem absolute.

              – Bart van Heukelom
              Oct 5 '10 at 11:55






            • 1





              I just want to add that you should always check that the stream returned from getResourceAsStream() is not null, because it will be if the resource is not within the classpath.

              – stenix
              Oct 22 '15 at 11:25











            • Also worth noting is that using the context class loader allows the classloader to be changed at runtime via Thread#setContextClassLoader. This is useful if you need to modify the classpath while the program is executing.

              – Max
              Jan 26 '16 at 17:06



















            • AFAIK packages names don't matter, it's the classpath of the class loader that does.

              – Bart van Heukelom
              Oct 5 '10 at 9:47











            • @Bart if you look at the source code you'll notice that the class name does matter when you call getResource on a class. The first thing this call does is call "resolveName" which adds the package prefix if appropriate. Javadoc for resolveName is "Add a package name prefix if the name is not absolute Remove leading "/" if name is absolute"

              – Michael Wiles
              Oct 5 '10 at 10:22








            • 9





              Ah, I see. Absolute here means relative to the classpath, rather than filesystem absolute.

              – Bart van Heukelom
              Oct 5 '10 at 11:55






            • 1





              I just want to add that you should always check that the stream returned from getResourceAsStream() is not null, because it will be if the resource is not within the classpath.

              – stenix
              Oct 22 '15 at 11:25











            • Also worth noting is that using the context class loader allows the classloader to be changed at runtime via Thread#setContextClassLoader. This is useful if you need to modify the classpath while the program is executing.

              – Max
              Jan 26 '16 at 17:06

















            AFAIK packages names don't matter, it's the classpath of the class loader that does.

            – Bart van Heukelom
            Oct 5 '10 at 9:47





            AFAIK packages names don't matter, it's the classpath of the class loader that does.

            – Bart van Heukelom
            Oct 5 '10 at 9:47













            @Bart if you look at the source code you'll notice that the class name does matter when you call getResource on a class. The first thing this call does is call "resolveName" which adds the package prefix if appropriate. Javadoc for resolveName is "Add a package name prefix if the name is not absolute Remove leading "/" if name is absolute"

            – Michael Wiles
            Oct 5 '10 at 10:22







            @Bart if you look at the source code you'll notice that the class name does matter when you call getResource on a class. The first thing this call does is call "resolveName" which adds the package prefix if appropriate. Javadoc for resolveName is "Add a package name prefix if the name is not absolute Remove leading "/" if name is absolute"

            – Michael Wiles
            Oct 5 '10 at 10:22






            9




            9





            Ah, I see. Absolute here means relative to the classpath, rather than filesystem absolute.

            – Bart van Heukelom
            Oct 5 '10 at 11:55





            Ah, I see. Absolute here means relative to the classpath, rather than filesystem absolute.

            – Bart van Heukelom
            Oct 5 '10 at 11:55




            1




            1





            I just want to add that you should always check that the stream returned from getResourceAsStream() is not null, because it will be if the resource is not within the classpath.

            – stenix
            Oct 22 '15 at 11:25





            I just want to add that you should always check that the stream returned from getResourceAsStream() is not null, because it will be if the resource is not within the classpath.

            – stenix
            Oct 22 '15 at 11:25













            Also worth noting is that using the context class loader allows the classloader to be changed at runtime via Thread#setContextClassLoader. This is useful if you need to modify the classpath while the program is executing.

            – Max
            Jan 26 '16 at 17:06





            Also worth noting is that using the context class loader allows the classloader to be changed at runtime via Thread#setContextClassLoader. This is useful if you need to modify the classpath while the program is executing.

            – Max
            Jan 26 '16 at 17:06













            13














            Well, it partly depends what you want to happen if you're actually in a derived class.



            For example, suppose SuperClass is in A.jar and SubClass is in B.jar, and you're executing code in an instance method declared in SuperClass but where this refers to an instance of SubClass. If you use this.getClass().getResource() it will look relative to SubClass, in B.jar. I suspect that's usually not what's required.



            Personally I'd probably use Foo.class.getResourceAsStream(name) most often - if you already know the name of the resource you're after, and you're sure of where it is relative to Foo, that's the most robust way of doing it IMO.



            Of course there are times when that's not what you want, too: judge each case on its merits. It's just the "I know this resource is bundled with this class" is the most common one I've run into.






            share|improve this answer


























            • skeet: a doubt in the statement "you're executing code in an instance method of SuperClass but where this refers to an instance of SubClass" if we are executing statements inside instance method of super class then "this" will refer to the superclass not the subclass.

              – Dead Programmer
              Oct 5 '10 at 8:55











            • @Suresh: No it won't. Try it! Create two classes, making one derive from the other, and then in the superclass print out this.getClass(). Create an instance of the subclass and call the method... it'll print out the name of the subclass, not the superclass.

              – Jon Skeet
              Oct 5 '10 at 9:01











            • thanks subclass instance method calls the method of superclass.

              – Dead Programmer
              Oct 5 '10 at 9:15






            • 1





              What I'm wondering about is whether using this.getResourceAsStream will only be able to load a resource from the same jar as the this clas is from and not from another jar. By my reckoning, it's the class loader that loads the resource and surely won't be confined from loading from only the one jar?

              – Michael Wiles
              Oct 5 '10 at 12:44
















            13














            Well, it partly depends what you want to happen if you're actually in a derived class.



            For example, suppose SuperClass is in A.jar and SubClass is in B.jar, and you're executing code in an instance method declared in SuperClass but where this refers to an instance of SubClass. If you use this.getClass().getResource() it will look relative to SubClass, in B.jar. I suspect that's usually not what's required.



            Personally I'd probably use Foo.class.getResourceAsStream(name) most often - if you already know the name of the resource you're after, and you're sure of where it is relative to Foo, that's the most robust way of doing it IMO.



            Of course there are times when that's not what you want, too: judge each case on its merits. It's just the "I know this resource is bundled with this class" is the most common one I've run into.






            share|improve this answer


























            • skeet: a doubt in the statement "you're executing code in an instance method of SuperClass but where this refers to an instance of SubClass" if we are executing statements inside instance method of super class then "this" will refer to the superclass not the subclass.

              – Dead Programmer
              Oct 5 '10 at 8:55











            • @Suresh: No it won't. Try it! Create two classes, making one derive from the other, and then in the superclass print out this.getClass(). Create an instance of the subclass and call the method... it'll print out the name of the subclass, not the superclass.

              – Jon Skeet
              Oct 5 '10 at 9:01











            • thanks subclass instance method calls the method of superclass.

              – Dead Programmer
              Oct 5 '10 at 9:15






            • 1





              What I'm wondering about is whether using this.getResourceAsStream will only be able to load a resource from the same jar as the this clas is from and not from another jar. By my reckoning, it's the class loader that loads the resource and surely won't be confined from loading from only the one jar?

              – Michael Wiles
              Oct 5 '10 at 12:44














            13












            13








            13







            Well, it partly depends what you want to happen if you're actually in a derived class.



            For example, suppose SuperClass is in A.jar and SubClass is in B.jar, and you're executing code in an instance method declared in SuperClass but where this refers to an instance of SubClass. If you use this.getClass().getResource() it will look relative to SubClass, in B.jar. I suspect that's usually not what's required.



            Personally I'd probably use Foo.class.getResourceAsStream(name) most often - if you already know the name of the resource you're after, and you're sure of where it is relative to Foo, that's the most robust way of doing it IMO.



            Of course there are times when that's not what you want, too: judge each case on its merits. It's just the "I know this resource is bundled with this class" is the most common one I've run into.






            share|improve this answer















            Well, it partly depends what you want to happen if you're actually in a derived class.



            For example, suppose SuperClass is in A.jar and SubClass is in B.jar, and you're executing code in an instance method declared in SuperClass but where this refers to an instance of SubClass. If you use this.getClass().getResource() it will look relative to SubClass, in B.jar. I suspect that's usually not what's required.



            Personally I'd probably use Foo.class.getResourceAsStream(name) most often - if you already know the name of the resource you're after, and you're sure of where it is relative to Foo, that's the most robust way of doing it IMO.



            Of course there are times when that's not what you want, too: judge each case on its merits. It's just the "I know this resource is bundled with this class" is the most common one I've run into.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Oct 5 '10 at 9:01

























            answered Oct 5 '10 at 8:31









            Jon SkeetJon Skeet

            1088k68979388435




            1088k68979388435













            • skeet: a doubt in the statement "you're executing code in an instance method of SuperClass but where this refers to an instance of SubClass" if we are executing statements inside instance method of super class then "this" will refer to the superclass not the subclass.

              – Dead Programmer
              Oct 5 '10 at 8:55











            • @Suresh: No it won't. Try it! Create two classes, making one derive from the other, and then in the superclass print out this.getClass(). Create an instance of the subclass and call the method... it'll print out the name of the subclass, not the superclass.

              – Jon Skeet
              Oct 5 '10 at 9:01











            • thanks subclass instance method calls the method of superclass.

              – Dead Programmer
              Oct 5 '10 at 9:15






            • 1





              What I'm wondering about is whether using this.getResourceAsStream will only be able to load a resource from the same jar as the this clas is from and not from another jar. By my reckoning, it's the class loader that loads the resource and surely won't be confined from loading from only the one jar?

              – Michael Wiles
              Oct 5 '10 at 12:44



















            • skeet: a doubt in the statement "you're executing code in an instance method of SuperClass but where this refers to an instance of SubClass" if we are executing statements inside instance method of super class then "this" will refer to the superclass not the subclass.

              – Dead Programmer
              Oct 5 '10 at 8:55











            • @Suresh: No it won't. Try it! Create two classes, making one derive from the other, and then in the superclass print out this.getClass(). Create an instance of the subclass and call the method... it'll print out the name of the subclass, not the superclass.

              – Jon Skeet
              Oct 5 '10 at 9:01











            • thanks subclass instance method calls the method of superclass.

              – Dead Programmer
              Oct 5 '10 at 9:15






            • 1





              What I'm wondering about is whether using this.getResourceAsStream will only be able to load a resource from the same jar as the this clas is from and not from another jar. By my reckoning, it's the class loader that loads the resource and surely won't be confined from loading from only the one jar?

              – Michael Wiles
              Oct 5 '10 at 12:44

















            skeet: a doubt in the statement "you're executing code in an instance method of SuperClass but where this refers to an instance of SubClass" if we are executing statements inside instance method of super class then "this" will refer to the superclass not the subclass.

            – Dead Programmer
            Oct 5 '10 at 8:55





            skeet: a doubt in the statement "you're executing code in an instance method of SuperClass but where this refers to an instance of SubClass" if we are executing statements inside instance method of super class then "this" will refer to the superclass not the subclass.

            – Dead Programmer
            Oct 5 '10 at 8:55













            @Suresh: No it won't. Try it! Create two classes, making one derive from the other, and then in the superclass print out this.getClass(). Create an instance of the subclass and call the method... it'll print out the name of the subclass, not the superclass.

            – Jon Skeet
            Oct 5 '10 at 9:01





            @Suresh: No it won't. Try it! Create two classes, making one derive from the other, and then in the superclass print out this.getClass(). Create an instance of the subclass and call the method... it'll print out the name of the subclass, not the superclass.

            – Jon Skeet
            Oct 5 '10 at 9:01













            thanks subclass instance method calls the method of superclass.

            – Dead Programmer
            Oct 5 '10 at 9:15





            thanks subclass instance method calls the method of superclass.

            – Dead Programmer
            Oct 5 '10 at 9:15




            1




            1





            What I'm wondering about is whether using this.getResourceAsStream will only be able to load a resource from the same jar as the this clas is from and not from another jar. By my reckoning, it's the class loader that loads the resource and surely won't be confined from loading from only the one jar?

            – Michael Wiles
            Oct 5 '10 at 12:44





            What I'm wondering about is whether using this.getResourceAsStream will only be able to load a resource from the same jar as the this clas is from and not from another jar. By my reckoning, it's the class loader that loads the resource and surely won't be confined from loading from only the one jar?

            – Michael Wiles
            Oct 5 '10 at 12:44











            9














            I search three places as shown below. Comments welcome.



            public URL getResource(String resource){

            URL url ;

            //Try with the Thread Context Loader.
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            if(classLoader != null){
            url = classLoader.getResource(resource);
            if(url != null){
            return url;
            }
            }

            //Let's now try with the classloader that loaded this class.
            classLoader = Loader.class.getClassLoader();
            if(classLoader != null){
            url = classLoader.getResource(resource);
            if(url != null){
            return url;
            }
            }

            //Last ditch attempt. Get the resource from the classpath.
            return ClassLoader.getSystemResource(resource);
            }





            share|improve this answer
























            • Thanks, this is a great idea. Just what I needed.

              – devo
              May 9 '12 at 17:31






            • 1





              I was looking at the comments in your code and the last one sounds interesting. Aren't all resources loaded from the classpath? And what cases would the ClassLoader.getSystemResource() cover that the above didn't succeeded?

              – nyxz
              Feb 15 '15 at 12:25













            • In all honesty, I don't get why you would want to load files from 3 different places. Don't you know where your files are stored ?

              – bvdb
              Jun 7 '17 at 11:46
















            9














            I search three places as shown below. Comments welcome.



            public URL getResource(String resource){

            URL url ;

            //Try with the Thread Context Loader.
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            if(classLoader != null){
            url = classLoader.getResource(resource);
            if(url != null){
            return url;
            }
            }

            //Let's now try with the classloader that loaded this class.
            classLoader = Loader.class.getClassLoader();
            if(classLoader != null){
            url = classLoader.getResource(resource);
            if(url != null){
            return url;
            }
            }

            //Last ditch attempt. Get the resource from the classpath.
            return ClassLoader.getSystemResource(resource);
            }





            share|improve this answer
























            • Thanks, this is a great idea. Just what I needed.

              – devo
              May 9 '12 at 17:31






            • 1





              I was looking at the comments in your code and the last one sounds interesting. Aren't all resources loaded from the classpath? And what cases would the ClassLoader.getSystemResource() cover that the above didn't succeeded?

              – nyxz
              Feb 15 '15 at 12:25













            • In all honesty, I don't get why you would want to load files from 3 different places. Don't you know where your files are stored ?

              – bvdb
              Jun 7 '17 at 11:46














            9












            9








            9







            I search three places as shown below. Comments welcome.



            public URL getResource(String resource){

            URL url ;

            //Try with the Thread Context Loader.
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            if(classLoader != null){
            url = classLoader.getResource(resource);
            if(url != null){
            return url;
            }
            }

            //Let's now try with the classloader that loaded this class.
            classLoader = Loader.class.getClassLoader();
            if(classLoader != null){
            url = classLoader.getResource(resource);
            if(url != null){
            return url;
            }
            }

            //Last ditch attempt. Get the resource from the classpath.
            return ClassLoader.getSystemResource(resource);
            }





            share|improve this answer













            I search three places as shown below. Comments welcome.



            public URL getResource(String resource){

            URL url ;

            //Try with the Thread Context Loader.
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            if(classLoader != null){
            url = classLoader.getResource(resource);
            if(url != null){
            return url;
            }
            }

            //Let's now try with the classloader that loaded this class.
            classLoader = Loader.class.getClassLoader();
            if(classLoader != null){
            url = classLoader.getResource(resource);
            if(url != null){
            return url;
            }
            }

            //Last ditch attempt. Get the resource from the classpath.
            return ClassLoader.getSystemResource(resource);
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Oct 5 '10 at 8:51









            dogbanedogbane

            191k65318374




            191k65318374













            • Thanks, this is a great idea. Just what I needed.

              – devo
              May 9 '12 at 17:31






            • 1





              I was looking at the comments in your code and the last one sounds interesting. Aren't all resources loaded from the classpath? And what cases would the ClassLoader.getSystemResource() cover that the above didn't succeeded?

              – nyxz
              Feb 15 '15 at 12:25













            • In all honesty, I don't get why you would want to load files from 3 different places. Don't you know where your files are stored ?

              – bvdb
              Jun 7 '17 at 11:46



















            • Thanks, this is a great idea. Just what I needed.

              – devo
              May 9 '12 at 17:31






            • 1





              I was looking at the comments in your code and the last one sounds interesting. Aren't all resources loaded from the classpath? And what cases would the ClassLoader.getSystemResource() cover that the above didn't succeeded?

              – nyxz
              Feb 15 '15 at 12:25













            • In all honesty, I don't get why you would want to load files from 3 different places. Don't you know where your files are stored ?

              – bvdb
              Jun 7 '17 at 11:46

















            Thanks, this is a great idea. Just what I needed.

            – devo
            May 9 '12 at 17:31





            Thanks, this is a great idea. Just what I needed.

            – devo
            May 9 '12 at 17:31




            1




            1





            I was looking at the comments in your code and the last one sounds interesting. Aren't all resources loaded from the classpath? And what cases would the ClassLoader.getSystemResource() cover that the above didn't succeeded?

            – nyxz
            Feb 15 '15 at 12:25







            I was looking at the comments in your code and the last one sounds interesting. Aren't all resources loaded from the classpath? And what cases would the ClassLoader.getSystemResource() cover that the above didn't succeeded?

            – nyxz
            Feb 15 '15 at 12:25















            In all honesty, I don't get why you would want to load files from 3 different places. Don't you know where your files are stored ?

            – bvdb
            Jun 7 '17 at 11:46





            In all honesty, I don't get why you would want to load files from 3 different places. Don't you know where your files are stored ?

            – bvdb
            Jun 7 '17 at 11:46











            1














            I know it really late for another answer but I just wanted to share what helped me at the end. It will also load resources/files from the absolute path of the file system (not only the classpath's).



            public class ResourceLoader {

            public static URL getResource(String resource) {
            final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
            classLoaders.add(Thread.currentThread().getContextClassLoader());
            classLoaders.add(ResourceLoader.class.getClassLoader());

            for (ClassLoader classLoader : classLoaders) {
            final URL url = getResourceWith(classLoader, resource);
            if (url != null) {
            return url;
            }
            }

            final URL systemResource = ClassLoader.getSystemResource(resource);
            if (systemResource != null) {
            return systemResource;
            } else {
            try {
            return new File(resource).toURI().toURL();
            } catch (MalformedURLException e) {
            return null;
            }
            }
            }

            private static URL getResourceWith(ClassLoader classLoader, String resource) {
            if (classLoader != null) {
            return classLoader.getResource(resource);
            }
            return null;
            }

            }





            share|improve this answer




























              1














              I know it really late for another answer but I just wanted to share what helped me at the end. It will also load resources/files from the absolute path of the file system (not only the classpath's).



              public class ResourceLoader {

              public static URL getResource(String resource) {
              final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
              classLoaders.add(Thread.currentThread().getContextClassLoader());
              classLoaders.add(ResourceLoader.class.getClassLoader());

              for (ClassLoader classLoader : classLoaders) {
              final URL url = getResourceWith(classLoader, resource);
              if (url != null) {
              return url;
              }
              }

              final URL systemResource = ClassLoader.getSystemResource(resource);
              if (systemResource != null) {
              return systemResource;
              } else {
              try {
              return new File(resource).toURI().toURL();
              } catch (MalformedURLException e) {
              return null;
              }
              }
              }

              private static URL getResourceWith(ClassLoader classLoader, String resource) {
              if (classLoader != null) {
              return classLoader.getResource(resource);
              }
              return null;
              }

              }





              share|improve this answer


























                1












                1








                1







                I know it really late for another answer but I just wanted to share what helped me at the end. It will also load resources/files from the absolute path of the file system (not only the classpath's).



                public class ResourceLoader {

                public static URL getResource(String resource) {
                final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
                classLoaders.add(Thread.currentThread().getContextClassLoader());
                classLoaders.add(ResourceLoader.class.getClassLoader());

                for (ClassLoader classLoader : classLoaders) {
                final URL url = getResourceWith(classLoader, resource);
                if (url != null) {
                return url;
                }
                }

                final URL systemResource = ClassLoader.getSystemResource(resource);
                if (systemResource != null) {
                return systemResource;
                } else {
                try {
                return new File(resource).toURI().toURL();
                } catch (MalformedURLException e) {
                return null;
                }
                }
                }

                private static URL getResourceWith(ClassLoader classLoader, String resource) {
                if (classLoader != null) {
                return classLoader.getResource(resource);
                }
                return null;
                }

                }





                share|improve this answer













                I know it really late for another answer but I just wanted to share what helped me at the end. It will also load resources/files from the absolute path of the file system (not only the classpath's).



                public class ResourceLoader {

                public static URL getResource(String resource) {
                final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
                classLoaders.add(Thread.currentThread().getContextClassLoader());
                classLoaders.add(ResourceLoader.class.getClassLoader());

                for (ClassLoader classLoader : classLoaders) {
                final URL url = getResourceWith(classLoader, resource);
                if (url != null) {
                return url;
                }
                }

                final URL systemResource = ClassLoader.getSystemResource(resource);
                if (systemResource != null) {
                return systemResource;
                } else {
                try {
                return new File(resource).toURI().toURL();
                } catch (MalformedURLException e) {
                return null;
                }
                }
                }

                private static URL getResourceWith(ClassLoader classLoader, String resource) {
                if (classLoader != null) {
                return classLoader.getResource(resource);
                }
                return null;
                }

                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Jan 29 '16 at 17:18









                nyxznyxz

                3,59573054




                3,59573054























                    -1














                    I tried a lot of ways and functions that suggested above, but they didn't work in my project. Anyway I have found solution and here it is:



                    try {
                    InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png");
                    img = ImageIO.read(path);
                    } catch (IOException e) {
                    e.printStackTrace();
                    }





                    share|improve this answer
























                    • You should better use this.getClass().getResourceAsStream() in this case. If you get a look at the source of the getResourceAsStream method, you will notice that it does the same thing than you but in a smarter way (fallback if no ClassLoader can be found on the class). It also indicates that you can encounter a potential null on getClassLoader in your code …

                      – PomCompot
                      May 26 '17 at 7:33













                    • @PromCompot, as I said this.getClass().getResourceAsStream() is not working for me, so I use that works. I think there are some people who can face with problem like mine.

                      – Vladislav
                      May 27 '17 at 23:03
















                    -1














                    I tried a lot of ways and functions that suggested above, but they didn't work in my project. Anyway I have found solution and here it is:



                    try {
                    InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png");
                    img = ImageIO.read(path);
                    } catch (IOException e) {
                    e.printStackTrace();
                    }





                    share|improve this answer
























                    • You should better use this.getClass().getResourceAsStream() in this case. If you get a look at the source of the getResourceAsStream method, you will notice that it does the same thing than you but in a smarter way (fallback if no ClassLoader can be found on the class). It also indicates that you can encounter a potential null on getClassLoader in your code …

                      – PomCompot
                      May 26 '17 at 7:33













                    • @PromCompot, as I said this.getClass().getResourceAsStream() is not working for me, so I use that works. I think there are some people who can face with problem like mine.

                      – Vladislav
                      May 27 '17 at 23:03














                    -1












                    -1








                    -1







                    I tried a lot of ways and functions that suggested above, but they didn't work in my project. Anyway I have found solution and here it is:



                    try {
                    InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png");
                    img = ImageIO.read(path);
                    } catch (IOException e) {
                    e.printStackTrace();
                    }





                    share|improve this answer













                    I tried a lot of ways and functions that suggested above, but they didn't work in my project. Anyway I have found solution and here it is:



                    try {
                    InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png");
                    img = ImageIO.read(path);
                    } catch (IOException e) {
                    e.printStackTrace();
                    }






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered May 24 '17 at 0:44









                    VladislavVladislav

                    719918




                    719918













                    • You should better use this.getClass().getResourceAsStream() in this case. If you get a look at the source of the getResourceAsStream method, you will notice that it does the same thing than you but in a smarter way (fallback if no ClassLoader can be found on the class). It also indicates that you can encounter a potential null on getClassLoader in your code …

                      – PomCompot
                      May 26 '17 at 7:33













                    • @PromCompot, as I said this.getClass().getResourceAsStream() is not working for me, so I use that works. I think there are some people who can face with problem like mine.

                      – Vladislav
                      May 27 '17 at 23:03



















                    • You should better use this.getClass().getResourceAsStream() in this case. If you get a look at the source of the getResourceAsStream method, you will notice that it does the same thing than you but in a smarter way (fallback if no ClassLoader can be found on the class). It also indicates that you can encounter a potential null on getClassLoader in your code …

                      – PomCompot
                      May 26 '17 at 7:33













                    • @PromCompot, as I said this.getClass().getResourceAsStream() is not working for me, so I use that works. I think there are some people who can face with problem like mine.

                      – Vladislav
                      May 27 '17 at 23:03

















                    You should better use this.getClass().getResourceAsStream() in this case. If you get a look at the source of the getResourceAsStream method, you will notice that it does the same thing than you but in a smarter way (fallback if no ClassLoader can be found on the class). It also indicates that you can encounter a potential null on getClassLoader in your code …

                    – PomCompot
                    May 26 '17 at 7:33







                    You should better use this.getClass().getResourceAsStream() in this case. If you get a look at the source of the getResourceAsStream method, you will notice that it does the same thing than you but in a smarter way (fallback if no ClassLoader can be found on the class). It also indicates that you can encounter a potential null on getClassLoader in your code …

                    – PomCompot
                    May 26 '17 at 7:33















                    @PromCompot, as I said this.getClass().getResourceAsStream() is not working for me, so I use that works. I think there are some people who can face with problem like mine.

                    – Vladislav
                    May 27 '17 at 23:03





                    @PromCompot, as I said this.getClass().getResourceAsStream() is not working for me, so I use that works. I think there are some people who can face with problem like mine.

                    – Vladislav
                    May 27 '17 at 23:03


















                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3861989%2fpreferred-way-of-loading-resources-in-java%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    鏡平學校

                    ꓛꓣだゔៀៅຸ໢ທຮ໕໒ ,ໂ'໥໓າ໼ឨឲ៵៭ៈゎゔit''䖳𥁄卿' ☨₤₨こゎもょの;ꜹꟚꞖꞵꟅꞛေၦေɯ,ɨɡ𛃵𛁹ޝ޳ޠ޾,ޤޒޯ޾𫝒𫠁သ𛅤チョ'サノބޘދ𛁐ᶿᶇᶀᶋᶠ㨑㽹⻮ꧬ꧹؍۩وَؠ㇕㇃㇪ ㇦㇋㇋ṜẰᵡᴠ 軌ᵕ搜۳ٰޗޮ޷ސޯ𫖾𫅀ल, ꙭ꙰ꚅꙁꚊꞻꝔ꟠Ꝭㄤﺟޱސꧨꧼ꧴ꧯꧽ꧲ꧯ'⽹⽭⾁⿞⼳⽋២៩ញណើꩯꩤ꩸ꩮᶻᶺᶧᶂ𫳲𫪭𬸄𫵰𬖩𬫣𬊉ၲ𛅬㕦䬺𫝌𫝼,,𫟖𫞽ហៅ஫㆔ాఆఅꙒꚞꙍ,Ꙟ꙱エ ,ポテ,フࢰࢯ𫟠𫞶 𫝤𫟠ﺕﹱﻜﻣ𪵕𪭸𪻆𪾩𫔷ġ,ŧآꞪ꟥,ꞔꝻ♚☹⛵𛀌ꬷꭞȄƁƪƬșƦǙǗdžƝǯǧⱦⱰꓕꓢႋ神 ဴ၀க௭எ௫ឫោ ' េㇷㇴㇼ神ㇸㇲㇽㇴㇼㇻㇸ'ㇸㇿㇸㇹㇰㆣꓚꓤ₡₧ ㄨㄟ㄂ㄖㄎ໗ツڒذ₶।ऩछएोञयूटक़कयँृी,冬'𛅢𛅥ㇱㇵㇶ𥄥𦒽𠣧𠊓𧢖𥞘𩔋цѰㄠſtʯʭɿʆʗʍʩɷɛ,əʏダヵㄐㄘR{gỚṖḺờṠṫảḙḭᴮᵏᴘᵀᵷᵕᴜᴏᵾq﮲ﲿﴽﭙ軌ﰬﶚﶧ﫲Ҝжюїкӈㇴffצּ﬘﭅﬈軌'ffistfflſtffतभफɳɰʊɲʎ𛁱𛁖𛁮𛀉 𛂯𛀞నఋŀŲ 𫟲𫠖𫞺ຆຆ ໹້໕໗ๆทԊꧢꧠ꧰ꓱ⿝⼑ŎḬẃẖỐẅ ,ờỰỈỗﮊDžȩꭏꭎꬻ꭮ꬿꭖꭥꭅ㇭神 ⾈ꓵꓑ⺄㄄ㄪㄙㄅㄇstA۵䞽ॶ𫞑𫝄㇉㇇゜軌𩜛𩳠Jﻺ‚Üမ႕ႌႊၐၸဓၞၞၡ៸wyvtᶎᶪᶹစဎ꣡꣰꣢꣤ٗ؋لㇳㇾㇻㇱ㆐㆔,,㆟Ⱶヤマފ޼ޝަݿݞݠݷݐ',ݘ,ݪݙݵ𬝉𬜁𫝨𫞘くせぉて¼óû×ó£…𛅑הㄙくԗԀ5606神45,神796'𪤻𫞧ꓐ㄁ㄘɥɺꓵꓲ3''7034׉ⱦⱠˆ“𫝋ȍ,ꩲ軌꩷ꩶꩧꩫఞ۔فڱێظペサ神ナᴦᵑ47 9238їﻂ䐊䔉㠸﬎ffiﬣ,לּᴷᴦᵛᵽ,ᴨᵤ ᵸᵥᴗᵈꚏꚉꚟ⻆rtǟƴ𬎎

                    Why https connections are so slow when debugging (stepping over) in Java?