Hari Seldon
Hari Seldon

Reputation: 1060

How does the classloader find resources?

I am reviewing a small github example project (shagie/TestingWithHsqldb) and have stumbled across a convention that is new to me and was hoping someone could help me understand what I am looking at.


The project is organized under the main src directory as such...

src/main/resources/connection_config.properties
src/main/java/com/shagie/dbtest/db/DBConnection.java
src/main/java/com/shagie/dbtest/db/DataAccess.java

src/test/resources/connection_config.properties
src/test/java/com/shagie/dbtest/db/DataAccessTest.java

The code in DBConnection.java is called both from DataAccess.java under the 'main' directory as well as the DataAccessTest.java in the 'test' directory.

In the file DBConnection.java there is the following statement that imports the connection_config.properties file:

Properties prop = new Properties();
InputStream in = GetClass().getResourceAsStream("/connection_config.properties");
prop.load(in);
in.close();

My Questions...

EDIT: Adjusting question to focus on the ClassLoader's getResource functionality instead of dependency injection

Upvotes: 0

Views: 167

Answers (1)

Mateusz Dymczyk
Mateusz Dymczyk

Reputation: 15141

This has nothing to do with dependency injection but with how ClassLoaders resolve resource paths.

1) This might be a bit confusing coming from a Linux background indeed getResourceAsStream(resource) has different rules. As per the doc:

If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'.

So the leading slash here only tells the class loader how to get the absolute name (whether the name you passed should be prepended with the package name or not), not that it should be looking "at the root" (in the test/main folders). What is the root and how resolution works depends on the class loader you are using. By default (in this case) resources are searched in the resources folder. You can write your own ClassLoader and change that behavior.

2) Again, when calling getResources() or getResourceAsStream() the class delegates it to the ClassLoader which loaded this class. If you are running unit tests (Junit or something similar) then the ClassLoader will know that it's supposed to look for resources in test folder not main.

Upvotes: 1

Related Questions