在 Travis CI 中使用本地图像编译的 GraalVM

GraalVM with native-image compilation in Travis CI

我有 Java 个项目,我使用 GraalVM 本机映像将其编译为可执行二进制文件。我想使用 Travis CI 为项目配置持续集成过程,这对我来说很有趣 - Travis CI 允许吗?如何配置 .travis.yml 文件以使用 GraalVM 本机图像构建?

我能够使用 Bach.java 中的 install-jdk.sh 在 Travis CI 构建中配置本机映像 GraalVM 编译 - Java Shell 生成器。这是 .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

选项 1:直接在 Travis CI 主机

上使用本地图像编译的 GraalVM

在 Travis 上安装 GraalVM(包括 Native Image)的第一个选项CI:只需使用 SDKMAN.travis.yml 看起来像这样:

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;

这里有一点需要注意:不要单独使用 language: java 或默认的 linux 发行版,例如 dist: bionic ,因为它们附带预安装的 Maven 版本 - 配置为使用预安装的 OpenJDK。但是大多数人稍后将需要 Maven 来使用我们安装的 SDKMAN GraalVM 来正确编译我们的 Java 项目。因此我们简单地使用language: minimal,即a simple way of getting our Travis builds based on a basic Travis build environment without pre-installed JDKs or Maven。为了验证这一点,我们 运行 一个 mvn --version,它应该在我们的 Travis 构建中显示如下内容:

$ 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"

script 部分中的 native-image 命令 在这里只是一个占位符 ,因为根据您的用例,您可能有完全不同的参数.

在我的例子中,我想编译一个 Spring 启动应用程序,所以我还创建了一个 100% 可理解的示例项目 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

===========================================

选项 2:使用 TravisCI docker 服务

在 Docker 中使用原生图像编译的 GraalVM

也许您已经习惯于在 Docker 容器中构建 Java 应用程序 - 那么 GraalVM 本机映像编译也不例外。使用 the TravisCI docker service.travis.yml 变得相当简单:

dist: bionic
language: minimal

services:
  - docker

script:
  - docker build . --tag=spring-boot-graal

关键部分是您现在的 Dockerfile (see this full example, leveraging Docker multi-stage builds) - 以及优于选项 1 的优势:您可以在您的机器上进行本地测试。这是一个例子 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;

我们在此处使用来自 DockerHub at https://hub.docker.com/r/oracle/graalvm-ce/ 的官方 Oracle GraalVM 映像 oracle/graalvm-ce:20.1.0-java11。由于这里缺少 native-image 命令和 Maven,我们使用 gu util 安装命令,再次使用 SDKMAN 安装 Maven。现在您可以在本地和 CloudCI 系统(如 TravisCI].

上编译 GraalVM Native Images

提醒一个提示:本机图像编译非常耗内存。如果您需要使用 --no-server 选项,您应该使用 -J-Xmx4G 参数将内存使用限制为 Travis 构建的 4GB RAM,否则您的构建可能会失败并显示 Error: Image build request failed with exit status 137或类似的错误。

下一个合乎逻辑的步骤是将生成的 Docker 图像推送到某种 Docker 注册表,也许 运行 某些 Cloud PaaS 中的容器。如果您需要更多信息,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