How to Verify Java Resource Paths with the Compiler
Code like Hello.class.getResourceAsStream("foo.bin")
does not get evaluated until runtime.
Worse, the method returns null
if the resource is not found.
This is not robust.
Better to catch problems in the build process and get a meaningful error message.
Steps
-
Check out the base project
Follow the steps in How to Set Up, Compile and Run an AutoRes.uk Project
-
Load some bytes using a stream
Replace the contents of
Hello.java
with:package com.example;
import uk.autores.handling.ResourceFiles;
import java.io.IOException; import java.io.InputStream;@ResourceFiles(Hello.FOO)
public class Hello { static final String FOO = "foo.bin"; public static void main(String[] args) throws IOException { try (InputStream in = Hello.class.getResourceAsStream(FOO)) { byte[] buffer = new byte[64]; int r; while ((r = in.read(buffer)) >= 0) { System.out.write(buffer, 0, r); } } } }Compile and run the application:
./mvnw --quiet clean compile exec:java
The contents of the file will be printed to the console.
-
Cause an error condition
Edit the constant to be a non-existant file:
static final String FOO = "fooX.bin";
Recompile and run the application.
Maven emits an error about the file not existing.
-
Make it simpler
The
FOO
constant was added to avoid putting the string in two places. This ensures they are always the same but is not ideal. Replace the code with:package com.example;
import uk.autores.InputStreams;
import java.io.IOException; import java.io.InputStream;@InputStreams("foo.bin")
public class Hello { public static void main(String[] args) throws IOException { try (InputStream in =Example.foo()
) { byte[] buffer = new byte[64]; int r; while ((r = in.read(buffer)) >= 0) { System.out.write(buffer, 0, r); } } } }Compile and run the application.
The package name is used to generate the class name. Try altering how the resource class is generated by setting some annotation properties:
@InputStreams( value = {"foo.bin", "world.txt"}, name = "ExampleResources", isPublic = true )