Java resource loading explained.
2016-01-15 13:12
309 查看
Understanding how Java finds resources is important. Resource loading in Java is “location independent”, Java also differentiates between absolute and relative resource names. And these names are processed by Java ResourceLoader differently. That last little
issue may cause problems, especially because the “wrong” resource names really work under some circumstances.
How java locates resources
Java loads resources from the “environment”, in many cases it uses all jars in Classpath to retrieve the resource. Resource loading in java is called location independent because it is not relevant
where your code is running, it just needs correct environment to find the resources.
Given all jars and paths in Classpath, java will search relatively to each tone to find the resource you specified. You specify resources using resource names.
Absolute and relative resource names
Resources are referred using resource name:
“/path/resource.xml” is the resource name here.
The resource name can be:
absolute like “/path/resource.xml”;
relative like “path/resource.xml”;
Relative means, relative to the location, where the method was called. The path will be appended if needed.
Absolute will be used as is, only first / will be removed before the search.
Example:
➕ In this case, stream1 will get the resource, located in classpath
➕ stream2 will get the resource, located in classpath
to package where the search was initiated).
ClassLoader and Class apply resource names differently
There are
they work differently!!!
java docu:
The methods in ClassLoader use the given String as the name of the
resource without applying any absolute/relative transformation (cf. the
methods in Class). The name should not have a leading “/”.
So, to extend our example:
➕ stream3 will become resource in classpath under
⚠ stream4 resource name
wrong!
Where it is important. Example
I was assessing Maven3 against Maven2 build. Same big project, just call m3.
Following code has worked well in my previous environment:
But after I changed the environment (maven2 build -> maven3 build) the
Following worked:
It is a speculation as of how the first snippet could have worked, but it deed. Going to new clean environment triggered the bug.
Links
1) http://download.oracle.com/docs/cd/E17476_01/javase/1.4.2/docs/guide/resources/resources.html
2) http://stackoverflow.com/questions/3238562/getresourceasstream-fails-under-new-environment
3) http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/lang/ClassLoader.html
4) http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/lang/Class.html
issue may cause problems, especially because the “wrong” resource names really work under some circumstances.
1 |
Java loads resources from the “environment”, in many cases it uses all jars in Classpath to retrieve the resource. Resource loading in java is called location independent because it is not relevant
where your code is running, it just needs correct environment to find the resources.
Given all jars and paths in Classpath, java will search relatively to each tone to find the resource you specified. You specify resources using resource names.
2 |
Resources are referred using resource name:
getResourceAsStream("/path/resource.xml");
“/path/resource.xml” is the resource name here.
The resource name can be:
absolute like “/path/resource.xml”;
relative like “path/resource.xml”;
Relative means, relative to the location, where the method was called. The path will be appended if needed.
Absolute will be used as is, only first / will be removed before the search.
Example:
package my.location; |
class ResourceFinder { |
... |
public void findResources(){ |
InputStream stream1 = |
getClass().getResourceAsStream( "/path/resource.xml" ); |
InputStream stream2 = |
getClass().getResourceAsStream( "path/resource.xml" ); |
} |
... |
} |
➕ In this case, stream1 will get the resource, located in classpath
path/resource.xml.
➕ stream2 will get the resource, located in classpath
my/location/path/resource.xml(Relative
to package where the search was initiated).
3 |
There are
ClassLoader.getResource()and
Class.getResource()and
they work differently!!!
java docu:
The methods in ClassLoader use the given String as the name of the
resource without applying any absolute/relative transformation (cf. the
methods in Class). The name should not have a leading “/”.
So, to extend our example:
package my.location; |
class ResourceFinder { |
... |
public void findResources(){ |
InputStream stream1 = |
getClass().getResourceAsStream( "/path/resource.xml" ); |
InputStream stream2 = |
getClass().getResourceAsStream( "path/resource.xml" ); |
InputStream stream3 = |
getClass().getClassLoader().getResourceAsStream( "path/resource.xml" ); |
InputStream stream4 = |
getClass().getClassLoader().getResourceAsStream( "/path/resource.xml" ); |
} |
... |
} |
➕ stream3 will become resource in classpath under
path/resource.xml.
⚠ stream4 resource name
/path/resource.xmlis
wrong!
4 |
I was assessing Maven3 against Maven2 build. Same big project, just call m3.
Following code has worked well in my previous environment:
InputStream exportFileInputStream = |
getClass().getClassLoader().getResourceAsStream( "/com/thinkplexx/lang/de/general.xml" ); |
But after I changed the environment (maven2 build -> maven3 build) the
general.xmlwas missing. I know that resource is there.
Following worked:
InputStream exportFileInputStream = |
getClass().getClassLoader().getResourceAsStream( "com/thinkplexx/lang/de/general.xml" ); |
It is a speculation as of how the first snippet could have worked, but it deed. Going to new clean environment triggered the bug.
Links
1) http://download.oracle.com/docs/cd/E17476_01/javase/1.4.2/docs/guide/resources/resources.html
2) http://stackoverflow.com/questions/3238562/getresourceasstream-fails-under-new-environment
3) http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/lang/ClassLoader.html
4) http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/lang/Class.html
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树