Boot places application classes and resources inside an executable archive; code that assumes every classpath resource is a normal file can fail after packaging.
Spring Boot executable jar: load resources through the classpath, not a file path
The archive is a different filesystem view
A receipt rules document under application resources may be a visible file in an IDE and an entry inside the packaged jar in production. Calling getFile on a classpath resource assumes an ordinary filesystem path. Use getResourceAsStream or Spring Resource input streams for read-only content, and copy to a managed temporary path only when a third-party library strictly requires a File. Layering] changes image construction, not this resource-access contract.
Do not write back into the jar
An executable archive is a deployable artifact. Generated reports, uploaded receipts and caches need explicit external storage. A relative working-directory path can change between an IDE, a container and a service manager; bind a writable location through validated configuration. Check permissions, quota and cleanup. External config validation] can reject a missing output directory at startup.
Run the packaged artifact
Package the app and invoke the exact executable archive used for deployment. Read a small rules resource, then run the same feature from an IDE. Assert identical parsed values. If a dependency uses system class loading or demands a real file, exercise that integration under java -jar before release rather than trusting a unit test classpath.
Implementation contract
try (InputStream rules = ReceiptApplication.class
.getResourceAsStream("/receipt-rules.json")) {
if (rules == null) throw new IllegalStateException("Receipt rules missing");
receiptRules = objectMapper.readValue(rules, ReceiptRules.class);
}Cost and verification
Stream access reads only the requested bytes. Copying large bundled assets to a temporary directory adds startup I/O and storage pressure; avoid it unless the library requires a real file.
Common Mistakes
- Do not call getFile on every classpath resource.
- Do not attempt to write generated receipts into the executable jar.
- Do not rely only on IDE execution to validate resource loading.
Read next
Spring Boot layered jar: keep dependency changes out of the application layer, Spring Boot buildpack image: separate build settings from deployed secrets, Spring Boot config validation: separate valid syntax from a safe relay setting, Spring Boot configuration validation: reject an unusable relay before work starts, Spring Boot startup timeline: measure context work before extending probes.
Related Boot contract
Spring Boot DevTools restart: reproduce classloader failures without it.
Related Boot contract
Spring Boot layered jar: keep dependency changes out of the application layer.
Related delivery contract
Spring MVC versioned static assets: cache immutable bytes by content.
