Preferred way of loading resources in Java
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
add a comment |
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
add a comment |
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
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
java resources
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
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
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...
- The class loader
- 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.
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 viaThread#setContextClassLoader
. This is useful if you need to modify the classpath while the program is executing.
– Max
Jan 26 '16 at 17:06
|
show 4 more comments
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.
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 outthis.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
add a comment |
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);
}
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
add a comment |
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;
}
}
add a comment |
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();
}
You should better usethis.getClass().getResourceAsStream()
in this case. If you get a look at the source of thegetResourceAsStream
method, you will notice that it does the same thing than you but in a smarter way (fallback if noClassLoader
can be found on the class). It also indicates that you can encounter a potentialnull
ongetClassLoader
in your code …
– PomCompot
May 26 '17 at 7:33
@PromCompot, as I saidthis.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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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...
- The class loader
- 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.
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 viaThread#setContextClassLoader
. This is useful if you need to modify the classpath while the program is executing.
– Max
Jan 26 '16 at 17:06
|
show 4 more comments
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...
- The class loader
- 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.
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 viaThread#setContextClassLoader
. This is useful if you need to modify the classpath while the program is executing.
– Max
Jan 26 '16 at 17:06
|
show 4 more comments
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...
- The class loader
- 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.
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...
- The class loader
- 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.
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 viaThread#setContextClassLoader
. This is useful if you need to modify the classpath while the program is executing.
– Max
Jan 26 '16 at 17:06
|
show 4 more comments
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 viaThread#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
|
show 4 more comments
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.
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 outthis.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
add a comment |
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.
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 outthis.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
add a comment |
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.
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.
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 outthis.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
add a comment |
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 outthis.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
add a comment |
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);
}
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
add a comment |
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);
}
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
add a comment |
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);
}
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);
}
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
add a comment |
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
add a comment |
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;
}
}
add a comment |
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;
}
}
add a comment |
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;
}
}
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;
}
}
answered Jan 29 '16 at 17:18


nyxznyxz
3,59573054
3,59573054
add a comment |
add a comment |
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();
}
You should better usethis.getClass().getResourceAsStream()
in this case. If you get a look at the source of thegetResourceAsStream
method, you will notice that it does the same thing than you but in a smarter way (fallback if noClassLoader
can be found on the class). It also indicates that you can encounter a potentialnull
ongetClassLoader
in your code …
– PomCompot
May 26 '17 at 7:33
@PromCompot, as I saidthis.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
add a comment |
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();
}
You should better usethis.getClass().getResourceAsStream()
in this case. If you get a look at the source of thegetResourceAsStream
method, you will notice that it does the same thing than you but in a smarter way (fallback if noClassLoader
can be found on the class). It also indicates that you can encounter a potentialnull
ongetClassLoader
in your code …
– PomCompot
May 26 '17 at 7:33
@PromCompot, as I saidthis.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
add a comment |
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();
}
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();
}
answered May 24 '17 at 0:44
VladislavVladislav
719918
719918
You should better usethis.getClass().getResourceAsStream()
in this case. If you get a look at the source of thegetResourceAsStream
method, you will notice that it does the same thing than you but in a smarter way (fallback if noClassLoader
can be found on the class). It also indicates that you can encounter a potentialnull
ongetClassLoader
in your code …
– PomCompot
May 26 '17 at 7:33
@PromCompot, as I saidthis.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
add a comment |
You should better usethis.getClass().getResourceAsStream()
in this case. If you get a look at the source of thegetResourceAsStream
method, you will notice that it does the same thing than you but in a smarter way (fallback if noClassLoader
can be found on the class). It also indicates that you can encounter a potentialnull
ongetClassLoader
in your code …
– PomCompot
May 26 '17 at 7:33
@PromCompot, as I saidthis.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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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