GraalVM with native-image compilation in Travis CI

江枫思渺然 提交于 2020-06-28 04:23:35

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!