This is sort of a continuation of a previous post about how to integrate your own Java classes into the Maven build lifecycle. This entry described how to generate files for inclusion in the final project artifact (ie. .jar, .war etc.). It took me some time to figure out how to access these files using Java’s resource mechanism so this post will summarize my findings.

Resource locations

If you follow the Maven convention your source code is located in src/main/java/ and the source code for your tests in src/main/test/. Resource files will be in src/main/resources/ and src/test/resources/ respectively. In the final artifact the resouce files will be located in target/classes/ or target/test-classes/. Sub-directories will be preserved.

If you want to be able to access a file during runtime drop them in either of these resource folders depending on whether you want to access them during tests or in your actual application.

Packaging

Copying resources to target/ will be done automatically by Maven. After packaging to .jar etc. the contents of target/test-classes/ will not be included while the contents of target/classes/ will be found in the root directory of the artifact (for jar packaging) or in WEB-INF/classes/ (for war packaging)

Accessing resources

During runtime of the artifact you can access resources with

InputStream resource = SomeClass.class.getResourceAsStream("<file or directory name"))

or

URL resource = SomeClass.class.getResource("<file or directory name"))

where SomeClass is a class in the artifact. The first way will give you an InputStream that you can use to read the contents of the file, the second way will return a URL that you can use to find out the path of the file or directory or move along the directory tree.

Accessing a resource will be delegated to the classloader of the class you use to load the resource. So when SomeClass is a class in a dependency of your project the resource will be loaded from that dependency’s artifact.

Resource paths

Resources have a notion of absolute and relative paths. The resource /filename will be resolved to target/classes/filename whereas filename will be resolved using the package of the class ie. with org.example.SomeClass it will be resolved to target/classes/org/example/filename. Again, for test classes the base resource directory will be target/test-classes/.

Note that you do not have to give a file name at all. / for example will be resolved to just target/classes/.