KIC
KIC

Reputation: 6081

getResourceAsStream() hell

Can someone explain me please how .getResourceAsStream() is really working. I try to figure out the painful facts, that in some cases getClass().getResourceAsStream(name); will work fine in eclipse but not in the deployed version (NPE). Another fact I am facing is, that sometimes getClass().getResource(name); returns a perfectly valid url but getClass().getResourceAsStream(name); returns null. Has someone written a library where I just pass the package (path) and filename and receive the stream without nagging?

EDIT: This is something general which affects me everytime I have to use getResourceAsStream(). Yes I could provide a code snipped for the actual situation but this is not helping me for the next time until I do not understand how getResourceAsStream is working.

EDIT 2: And what is the difference between:

MyClass.class.getResourceAsStream(...)
this.getClass().getResourceAsStream(...),    
MyClass.class.getClassLoader().getResourceAsStream(...)
Thread.currentThread().getContextClassLoader().getResourceAsStream(...)

EDIT 3: Also, while some.package.SomeClass.class.getResourceAsStream("/path/only/holding/resource.files") is not able to load resources in a classpath holding no classes but only files. This variant is able to do so: ClassLoader.class.getResourceAsStream("/path/only/holding/resource.files") this confuses me a lot so I would really prefere something like spring does with URI the schema classpath:

Upvotes: 3

Views: 2985

Answers (3)

The performance is better when the resource you are searching for is in the same jar of the class.

Ex: mypackagenumber1.jar/xsl/test.xsl and the class in mypackagenumber1.jar/com.foo/TestGetResourceAsStream("/xsl/test.xsl");

I had performance problem when packing resources is in different jars, when the project has very packages jar.

Ex:mypackagenumber1.jar/xsl/test.xsl and the class in mypackagenumber42.jar/com.foo/TestGetResourceAsStream("/xsl/test.xsl");

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 692121

The rule is quite simple. Let's say your class is in the package com.foo.

Calling getResource("bar/bla.txt") (no leading /) on this class will look for a file in bla.txt in the package com.foo.bar. The path is thus relative to the package of the class. The classpath is used to find the file, just as the classpath would be used to find a class.

Calling getResource("/bar/bla.txt") (leading /) on this class will look for a file in bla.txt in the package bar. The path is thus an absolute path, starting at the root of the classpath. The classpath is used to find the file, just as the classpath would be used to find a class.

And you may not have paths containing . or .. like you would have with filesystem paths.

Upvotes: 4

Kayaman
Kayaman

Reputation: 73568

You have to understand that it works in relation to the classpath.

If you have a different classpath when running on eclipse as opposed to when running as a deployed version, you can get different results.

The javadocs are quite explanatory as well.

Upvotes: -1

Related Questions