Reputation: 1
I apologize in advance if the answer to this question is a simple one. It seems I don't have enough knowledge about classloading in Java.
Say I have a file called "properties" in my application. My application uses an external JAR and inside that JAR, there's also a file called "properties".
Question:
If the external JAR file attempts to open that file with getClass().getClassLoader().getResourceAsStream("properties")
, why doesn't it load the one from my application. Not that I want it to, but wouldn't the ClassLoader in this case be the one that loaded my application? I thought that method would use the absolute path for finding the resource. Do classes in external JARs get loaded with a different classloader?
Upvotes: 0
Views: 2127
Reputation: 2003
No, it loads the first found in that class' classloader. If you want to open a file using an absolute path, you open an InputStream
pointing at the file.
Classes in external JAR might be loaded using different classloaders (e.g. in a Java EE container) but then classloaders need to be chained in order for you to see them.
Upvotes: 0
Reputation: 10433
ThClassLoader#getResourceAsStream(String)
calls getResource(String)
and this as getResource() on the parent. If this does not find anything, then it will ask the classloaders findResource(String)
.
It depends on this implementation what it does return, in case of the URLClassLoader
this will be URLClassPath.findResource()
which steps through all loaders (one loader for each search path entry) and returns the first find.
In a normal application your JARs as well as all libraries are loaded by the same (Application) class loader. In case of the Sun launcher this is sun.misc.Launcher$AppClassLoader
which extends URLClassLoader
. It puts all JAR and classes from the classpath in the search list.
It is a good idea to make resources either unique (putting them in your packages) or retrieve all resources and pick the right one (or all). The later is for example used by the ServiceLoader when it finds all implementations for a given service.
Upvotes: 0
Reputation: 75426
The class loading mechanism is the same for classes and resources (but the bytes found are treated differently).
See http://docs.oracle.com/javase/tutorial/ext/basics/load.html for the official explanation.
It is the first class loader actually asked which has the resource that wins. If the class loader does not have its resource, try again with the parent.
(Note that for web applications - WAR files - this is deliberately slightly different about which one is asked first).
Upvotes: 2