Including and accessing files without bundling them inside JAR


(Arvid Fahlström Myrman) #1

Hi,

I want to include some resource files with my project that I can access easily from Java, no matter what the current working directory is when running the main class. Using the Java plugin support for resources in Gradle this is easy, as the files will be bundled inside the JAR and it is only a matter of running getResource() on an appropriate class object.

However, included in my resources are files such as HTML templates and images that would be nice to be able to easily edit even after installing the project with gradle install, as well as large files that I want to avoid having to repeatedly unpack; as such I would prefer to not have to include the files inside a JAR.

As an example, consider the following set of files:

src/main/java/Test.java
src/main/files/hello.txt
build.gradle

where Test.java simply reads and prints the first line of hello.txt:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Test {
	public static void main(String[] args) throws Exception {
		InputStream is = findFile("hello.txt");
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		System.out.println(reader.readLine());
	}
	
	public static InputStream findFile(String path) throws Exception {
		return ???;
		// If bundling file with JAR, the below works:
		// return Test.class.getClassLoader().getResourceAsStream(path);
	}
}

What’s the best way to copy hello.txt and make sure it’s easily accessible from Java, without packing it inside a JAR file? It needs to be accessible in the same way regardless of whether I’m using Eclipse (with Buildship), IntelliJ IDEA, gradle run, or the startup script generated when running gradle install. What would the findFile function look like?