Spring 引导和 GraalVM 本机映像
Spring Boot and GraalVM native-image
使用最新版本 Spring Boot 2.3.0
、spring-graalvm-native 0.7.0.BUILD-SNAPSHOT
、GraalVM 20.1.0.r11
和相应的博文
- https://spring.io/blog/2020/04/16/spring-tips-the-graalvm-native-image-builder-feature
- https://blog.codecentric.de/en/2020/05/spring-boot-graalvm
我也开始玩我的一款应用程序。
幸运的是,我能够毫无障碍地编译我的应用程序。我的 compile.sh
脚本如下所示
#!/usr/bin/env bash
echo "[-->] Detect artifactId from pom.xml"
ARTIFACT=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${project.artifactId}' \
--non-recursive \
exec:exec);
echo "artifactId is '$ARTIFACT'"
echo "[-->] Detect artifact version from pom.xml"
VERSION=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${project.version}' \
--non-recursive \
exec:exec);
echo "artifact version is '$VERSION'"
echo "[-->] Detect Spring Boot Main class ('start-class') from pom.xml"
MAINCLASS=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${start-class}' \
--non-recursive \
exec:exec);
echo "Spring Boot Main class ('start-class') is '$MAINCLASS'"
GREEN='3[0;32m'
RED='3[0;31m'
NC='3[0m'
echo "[-->] Cleaning target directory & creating new one"
rm -rf target
mkdir -p target/native-image
echo "Packaging $ARTIFACT with Maven"
mvn -ntp package > target/native-image/output.txt
echo "[-->] Expanding the Spring Boot fat jar"
JAR="$ARTIFACT-$VERSION.jar"
rm -f $ARTIFACT
echo "Unpacking $JAR"
cd target/native-image
jar -xvf ../$JAR >/dev/null 2>&1
cp -R META-INF BOOT-INF/classes
LIBPATH=`find BOOT-INF/lib | tr '\n' ':'`
CP=BOOT-INF/classes:$LIBPATH
GRAALVM_VERSION=`native-image --version`
echo "Compiling $ARTIFACT with $GRAALVM_VERSION"
{ time native-image \
--verbose \
--no-server \
--no-fallback \
--enable-all-security-services \
-H:Name=$ARTIFACT \
-Dspring.native.remove-unused-autoconfig=true \
-Dspring.native.remove-yaml-support=true \
-Dspring.native.remove-xml-support=true \
-Dspring.native.remove-spel-support=true \
-Dspring.native.remove-jmx-support=true \
-cp $CP $MAINCLASS >> output.txt ; } 2>> output.txt
if [[ -f $ARTIFACT ]]
then
printf "${GREEN}SUCCESS${NC}\n"
mv ./$ARTIFACT ..
exit 0
else
cat output.txt
printf "${RED}FAILURE${NC}: an error occurred when compiling the native-image.\n"
exit 1
fi
但现在我的麻烦开始了:我的应用程序在启动期间依赖于一些 CSV 来加载数据。
数据是这样加载的
InputStream is = CSVUtil.class.getResourceAsStream("/myData.csv");
文件位于 /src/main/resources/myData.csv
如前所述,编译工作没有问题,但是一旦我启动应用程序,它就找不到 CSV。
Caused by: java.lang.NullPointerException: null
at java.io.Reader.<init>(Reader.java:167) ~[na:na]
at java.io.InputStreamReader.<init>(InputStreamReader.java:113) ~[na:na]
at ch.aaap.raw.CSVUtil.getData(CSVUtil.java:33) ~[na:na]
...
好像不是编译的一部分。有什么提示可以让 native-image
命令意识到我需要这些 CSV 吗?
看起来添加以下参数有帮助
-H:IncludeResources='.*/*.csv$'
使用最新版本 Spring Boot 2.3.0
、spring-graalvm-native 0.7.0.BUILD-SNAPSHOT
、GraalVM 20.1.0.r11
和相应的博文
- https://spring.io/blog/2020/04/16/spring-tips-the-graalvm-native-image-builder-feature
- https://blog.codecentric.de/en/2020/05/spring-boot-graalvm
我也开始玩我的一款应用程序。
幸运的是,我能够毫无障碍地编译我的应用程序。我的 compile.sh
脚本如下所示
#!/usr/bin/env bash
echo "[-->] Detect artifactId from pom.xml"
ARTIFACT=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${project.artifactId}' \
--non-recursive \
exec:exec);
echo "artifactId is '$ARTIFACT'"
echo "[-->] Detect artifact version from pom.xml"
VERSION=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${project.version}' \
--non-recursive \
exec:exec);
echo "artifact version is '$VERSION'"
echo "[-->] Detect Spring Boot Main class ('start-class') from pom.xml"
MAINCLASS=$(mvn -q \
-Dexec.executable=echo \
-Dexec.args='${start-class}' \
--non-recursive \
exec:exec);
echo "Spring Boot Main class ('start-class') is '$MAINCLASS'"
GREEN='3[0;32m'
RED='3[0;31m'
NC='3[0m'
echo "[-->] Cleaning target directory & creating new one"
rm -rf target
mkdir -p target/native-image
echo "Packaging $ARTIFACT with Maven"
mvn -ntp package > target/native-image/output.txt
echo "[-->] Expanding the Spring Boot fat jar"
JAR="$ARTIFACT-$VERSION.jar"
rm -f $ARTIFACT
echo "Unpacking $JAR"
cd target/native-image
jar -xvf ../$JAR >/dev/null 2>&1
cp -R META-INF BOOT-INF/classes
LIBPATH=`find BOOT-INF/lib | tr '\n' ':'`
CP=BOOT-INF/classes:$LIBPATH
GRAALVM_VERSION=`native-image --version`
echo "Compiling $ARTIFACT with $GRAALVM_VERSION"
{ time native-image \
--verbose \
--no-server \
--no-fallback \
--enable-all-security-services \
-H:Name=$ARTIFACT \
-Dspring.native.remove-unused-autoconfig=true \
-Dspring.native.remove-yaml-support=true \
-Dspring.native.remove-xml-support=true \
-Dspring.native.remove-spel-support=true \
-Dspring.native.remove-jmx-support=true \
-cp $CP $MAINCLASS >> output.txt ; } 2>> output.txt
if [[ -f $ARTIFACT ]]
then
printf "${GREEN}SUCCESS${NC}\n"
mv ./$ARTIFACT ..
exit 0
else
cat output.txt
printf "${RED}FAILURE${NC}: an error occurred when compiling the native-image.\n"
exit 1
fi
但现在我的麻烦开始了:我的应用程序在启动期间依赖于一些 CSV 来加载数据。 数据是这样加载的
InputStream is = CSVUtil.class.getResourceAsStream("/myData.csv");
文件位于 /src/main/resources/myData.csv
如前所述,编译工作没有问题,但是一旦我启动应用程序,它就找不到 CSV。
Caused by: java.lang.NullPointerException: null
at java.io.Reader.<init>(Reader.java:167) ~[na:na]
at java.io.InputStreamReader.<init>(InputStreamReader.java:113) ~[na:na]
at ch.aaap.raw.CSVUtil.getData(CSVUtil.java:33) ~[na:na]
...
好像不是编译的一部分。有什么提示可以让 native-image
命令意识到我需要这些 CSV 吗?
看起来添加以下参数有帮助
-H:IncludeResources='.*/*.csv$'