I have a Java project using Gradle to build. The folder structure is as below:
<project name>
|- app
|- bin/
|- build/
|- src/
| |- main/
| |- java
| | |- <package path>
| |- resources/
| |- <.json files>
|- build.gradle
In my app/build.gradle
file, I use the Gradle plugin org.graalvm.buildtools.native
to build a binary file using GraalVM:
plugins {
id 'application'
id 'org.graalvm.buildtools.native' version '0.9.4'
}
nativeBuild {
imageName = <image name>
mainClass = "<package path>.App"
verbose = true
fallback = false
buildArgs.add('-H:IncludeResources=".*\\.json$"')
}
The plugin supports adding extra build arguments to GraalVM. So I use -H:IncludeResources
to try to include all JSON files located in src/main/resources/
.
When building using the command ./gradlew nativeBuild
, the build process finished successfully. But when running, the getResourceAsStream
function returns null
which means it couldn't find those JSON files.
My code to load file content:
import org.apache.commons.io.IOUtils;
private String loadTextResourcesFile(String filePath) {
try {
String fileText = IOUtils.toString(getClass().getClassLoader()
.getResourceAsStream(filePath), "UTF-8");
return fileText;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
String fileContent = loadTextResourcesFile("a.json");
I think the problem is at buildArgs.add('-H:IncludeResources=".*\\.json$"')
. Maybe the pattern I used .*\\.json$
doesn't point to my app/src/main/resources/*.json
files. But I couldn't find a correct pattern works for my case. Could you please help?
I removed the nativeBuild
section in build.gradle
and then add the following:
graalvmNative {
binaries.all {
resources.autodetect()
}
toolchainDetection = false
}
This command helps to generate binary file:
./gradlew nativeCompile --warning-mode all
And the plugin also generates the resource-config.json
file used for native-image
. You can find the list of resources included:
cat app/build/native/generated/generateResourcesConfigFile/resource-config.json
If you're using Picocli you may also need this in the build.gradle
file:
compileJava {
options.compilerArgs += [
"-Aproject=${project.group}/${project.name}",
"-Aother.resource.patterns=.*"
]
}
(.*
will include all files under src/main/resources
that you want to embed into the binary. For more details about other.resource.patterns
, please refer to https://github.com/remkop/picocli/tree/main/picocli-codegen#222-other-options)