Reputation: 1060
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...
How is the properties file being found in the "resources" directory if the call is structured as getResourceAsStream("/connection_config.properties")
? Doesn't that path mean it should look at the root directory (main or test) for the properties file?
Since DBConnection.java
doesn't change it's root 'main' directory, how is it that the properties file comes from the 'test' directory when executing DataAccessTest.java
I assume this pattern is related to dependency injection and unit testing. Is there a name for this specific pattern? Where is a good place to learn more about it?
EDIT: Adjusting question to focus on the ClassLoader
's getResource
functionality instead of dependency injection
Upvotes: 0
Views: 167
Reputation: 15141
This has nothing to do with dependency injection but with how ClassLoader
s 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