user3352357
user3352357

Reputation: 1

How does the Classloader in Java know which file resource to load if there are duplicates?

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

Answers (3)

Alessandro Santini
Alessandro Santini

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

eckes
eckes

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

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

Related Questions