问题
I have Java project which I compile with GraalVM native-image to executable binary. I'd like to configure continuous integration process for the project with Travis CI and it's ineresting to me - does Travis CI allow that? How can I configure .travis.yml file for building with GraalVM native-image?
回答1:
I was able to configure native-image GraalVM compilation in Travis CI builds using install-jdk.sh from Bach.java - Java Shell Builder. Here is .travis-ci.yml:
sudo: false
language: java
cache:
directories:
- $HOME/.m2
before_install:
- wget https://github.com/sormuras/bach/raw/master/install-jdk.sh
matrix:
include:
# GraalVM
- env: JDK='GraalVM 19'
install: . ./install-jdk.sh --url "https://github.com/oracle/graal/releases/download/vm-19.2.0/graalvm-ce-linux-amd64-19.2.0.tar.gz"
script:
- mvn package -Pnative -Dnative-image.docker-build=true
回答2:
Option 1: GraalVM with native-image compilation directly on Travis CI host
The first option to install GraalVM (incl. Native Image) on TravisCI: Simply use SDKMAN. The .travis.yml
looks like this:
language: minimal
install:
# Install GraalVM with SDKMAN
- curl -s "https://get.sdkman.io" | bash
- source "$HOME/.sdkman/bin/sdkman-init.sh"
- sdk install java 20.0.0.r11-grl
# Check if GraalVM was installed successfully
- java -version
# Install Maven, that uses GraalVM for later builds
- sdk install maven
# Show Maven using GraalVM JDK
- mvn --version
# Install GraalVM Native Image
- gu install native-image
# Check if Native Image was installed properly
- native-image --version
script:
# Run GraalVM Native Image compilation
- native-image \
--no-server \
--no-fallback \
-H:+TraceClassInitialization \
-H:Name=yourArtifactNameHere \
-H:+ReportExceptionStackTraces \
-DremoveUnusedAutoconfig=true \
-DremoveYamlSupport=true \
-cp yourClassPathHere yourMainClassHere;
There's one crucial point to notice here: Don't use a language: java
or the default linux distros like dist: bionic
alone!, because they ship with pre-installed Maven versions - which are configured to use the pre-installed OpenJDK. But most people will need Maven to use our SDKMAN installed GraalVM to properly compile our Java projects later. Therefore we simply use the language: minimal
, which is a simple way of getting our Travis builds based on a basic Travis build environment without pre-installed JDKs or Maven. To verify this, we run a mvn --version
, which should show something like this inside our Travis build:
$ mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /home/travis/.sdkman/candidates/maven/current
Java version: 11.0.6, vendor: Oracle Corporation, runtime: /home/travis/.sdkman/candidates/java/20.0.0.r11-grl
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.15.0-1028-gcp", arch: "amd64", family: "unix"
The native-image
command inside the script
section is just meant as a placeholder here, since you may have quite different parameters depending on your use case.
In my case, I wanted to compile a Spring Boot App, so I also created a 100% comprehensible example project spring-boot-graalvm, where you could also have a look at the TravisCI builds, which install GraalVM and do the native image compilation: https://travis-ci.org/jonashackt/spring-boot-graalvm
===========================================
Option 2: GraalVM with native-image compilation in Docker using TravisCI docker service
Maybe you're already used to build your Java apps inside Docker containers - then GraalVM native image compilation is no exception. Using the TravisCI docker service, the .travis.yml
becomes fairly simple:
dist: bionic
language: minimal
services:
- docker
script:
- docker build . --tag=spring-boot-graal
The crucial part is your Dockerfile
now (see this full example, leveraging Docker multi-stage builds) - and the advantage over Option 1: you can test it locally on your machine. Here's an example Dockerfile
:
FROM oracle/graalvm-ce:20.1.0-java11
MAINTAINER Jonas Hecht
ADD . /build
WORKDIR /build
# For SDKMAN to work we need unzip & zip
RUN yum install -y unzip zip
RUN \
# Install SDKMAN
curl -s "https://get.sdkman.io" | bash; \
source "$HOME/.sdkman/bin/sdkman-init.sh"; \
sdk install maven; \
# Install GraalVM Native Image
gu install native-image;
RUN source "$HOME/.sdkman/bin/sdkman-init.sh" && mvn --version
RUN native-image --version
RUN source "$HOME/.sdkman/bin/sdkman-init.sh" && native-image \
--no-server -J-Xmx4G \
--no-fallback \
-H:+TraceClassInitialization \
-H:Name=yourArtifactNameHere \
-H:+ReportExceptionStackTraces \
-DremoveUnusedAutoconfig=true \
-DremoveYamlSupport=true \
-cp yourClassPathHere yourMainClassHere;
We're using the official Oracle GraalVM image oracle/graalvm-ce:20.1.0-java11
from DockerHub at https://hub.docker.com/r/oracle/graalvm-ce/ here. As this lacks native-image
command and Maven, we use gu
util to install the command and SDKMAN again to install Maven. Now you can compile GraalVM Native Images both locally and on CloudCI systems like TravisCI.
Be reminded about one hint: the native image compilation is quite memory hungry. If you need to use the --no-server
option, you should limit memory usage with the -J-Xmx4G
parameter to 4GB
of RAM for Travis builds, since otherwise your builds might fail with Error: Image build request failed with exit status 137
or similar errors.
The next logical step would be to push the resulting Docker image to some sort of Docker registry and maybe run the container in some Cloud PaaS. If you need more info, have a look at this fully comprehesible guide here. There's also an example of a fully working Docker multi-stage build enabled Dockerfile
in this example project: https://github.com/jonashackt/spring-boot-graalvm/blob/master/Dockerfile
来源:https://stackoverflow.com/questions/58465833/graalvm-with-native-image-compilation-in-travis-ci