5

From my project's root directory, I issued the following command to create a native executable that will be specific to my operating system. See the following guide for details

mvn package -Pnative -Dquarkus.native.container-build=true

and here is the output.

[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------< com.example:quarkus-spring >---------------------
[INFO] Building quarkus-spring 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- quarkus-maven-plugin:1.13.7.Final:generate-code (default) @ quarkus-spring ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ quarkus-spring ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ quarkus-spring ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- quarkus-maven-plugin:1.13.7.Final:generate-code-tests (default) @ quarkus-spring ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ quarkus-spring ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ quarkus-spring ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:3.0.0-M5:test (default-test) @ quarkus-spring ---
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.example.controller.GreetingControllerTest
2021-06-22 21:17:05,339 WARN  [io.qua.dat.dep.dev.DevServicesDatasourceProcessor] (build-10) Unable to determine a database type for default datasource
2021-06-22 21:17:05,340 WARN  [io.qua.agr.dep.AgroalProcessor] (build-16) The Agroal dependency is present but no JDBC datasources have been defined.
2021-06-22 21:17:06,080 INFO  [io.quarkus] (main) Quarkus 1.13.7.Final on JVM started in 1.004s. Listening on: http://localhost:8081
2021-06-22 21:17:06,081 INFO  [io.quarkus] (main) Profile test activated.
2021-06-22 21:17:06,081 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, hibernate-orm-panache, mongodb-client, mutiny, narayana-jta, resteasy, smallrye-context-propagation, spring-boot-properties, spring-data-jpa, spring-data-rest, spring-di]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.755 s - in com.example.controller.GreetingControllerTest
2021-06-22 21:17:06,699 INFO  [io.quarkus] (main) Quarkus stopped in 0.020s
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ quarkus-spring ---
[INFO]
[INFO] --- quarkus-maven-plugin:1.13.7.Final:build (default) @ quarkus-spring ---
[INFO] [org.jboss.threads] JBoss Threads version 3.2.0.Final
[WARNING] [io.quarkus.agroal.deployment.AgroalProcessor] The Agroal dependency is present but no JDBC datasources have been defined.
[INFO] [org.hibernate.Version] HHH000412: Hibernate ORM core version 5.4.29.Final
[INFO] [io.quarkus.deployment.pkg.steps.JarResultBuildStep] Building native image source jar: /Users/viswanath/projects/quarkus-spring/target/quarkus-spring-1.0-SNAPSHOT-native-image-source-jar/quarkus-spring-1.0-SNAPSHOT-runner.jar
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildStep] Building native image from /Users/viswanath/projects/quarkus-spring/target/quarkus-spring-1.0-SNAPSHOT-native-image-source-jar/quarkus-spring-1.0-SNAPSHOT-runner.jar
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildContainerRunner] Using docker to run the native image builder
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildContainerRunner] Checking image status quay.io/quarkus/ubi-quarkus-native-image:21.0-java11
21.0-java11: Pulling from quarkus/ubi-quarkus-native-image
Digest: sha256:356624049da5f564e14acbaf167a341a01b332569db83e9967b1e72cfdf06653
Status: Image is up to date for quay.io/quarkus/ubi-quarkus-native-image:21.0-java11
quay.io/quarkus/ubi-quarkus-native-image:21.0-java11
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildStep] Running Quarkus native-image plugin on GraalVM Version 21.0.0.2 (Java Version 11.0.10+8-jvmci-21.0-b06)
[INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildRunner] docker run --env LANG=C --rm -v /Users/viswanath/projects/quarkus-spring/target/quarkus-spring-1.0-SNAPSHOT-native-image-source-jar:/project:z quay.io/quarkus/ubi-quarkus-native-image:21.0-java11 -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -J-Dsun.nio.ch.maxUpdateArraySize=100 -J-DCoordinatorEnvironmentBean.transactionStatusManagerEnable=false -J-Dvertx.logger-delegate-factory-class-name=io.quarkus.vertx.core.runtime.VertxLogDelegateFactory -J-Dvertx.disableDnsResolver=true -J-Dio.netty.leakDetection.level=DISABLED -J-Dio.netty.allocator.maxOrder=1 -J-Duser.language=en -J-Duser.country=GB -J-Dfile.encoding=UTF-8 --initialize-at-build-time= -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy\$BySpaceAndTime -H:+JNI -H:+AllowFoldMethods -jar quarkus-spring-1.0-SNAPSHOT-runner.jar -H:FallbackThreshold=0 -H:+ReportExceptionStackTraces -J-Xmx8192m -H:-AddAllCharsets -H:EnableURLProtocols=http,https --enable-all-security-services --no-server -H:-UseServiceLoaderFeature -H:+StackTrace quarkus-spring-1.0-SNAPSHOT-runner
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
^C%

Native image generation fails as the build just hangs.


I chose to install Graal VM on my host and opt for the non-container based approach as shown below.

  • Install Graal VM on M1 Mac using the following command

    ❯ brew install --cask graalvm/tap/graalvm-ce-lts-java11

  • Add Graal VM to JEnv managed versions of Java

    ❯ jenv add /Library/Java/JavaVirtualMachines/graalvm-ce-lts-java11-20.3.1/Contents/Home graalvm64-11.0.10 added

  • For the project, set Graal VM's Java 11. From the project's directory, issue the following command

    ❯ jenv local graalvm64-11.0.10

  • Set GRAALVM_HOME environment variable to the GraalVM installation directory. Add the following to ~/.zshrc

    ❯ export GRAALVM_HOME=/Library/Java/JavaVirtualMachines/graalvm-ce-lts-java11-20.3.1/Contents/Home

and reload changes made to .zshrc by issuing the command

❯ source ~/.zshrc
  • Install the native-image tool using the following command. Some previous releases of GraalVM included the native-image tool by default. This is no longer the case; it must be installed as a second step after GraalVM itself is installed.

    ❯ ${GRAALVM_HOME}/bin/gu install native-image

  • Install binutils and add it to the path

    ❯ brew install binutils

    ❯ echo 'export PATH="/opt/homebrew/opt/binutils/bin:$PATH"' >> ~/.zshrc ❯ source ~/.zshrc

  • Create a native executable using the following caommand from project's root directory

    ❯ mvn clean install -Pnative -Dnative-image.docker-build=true -Dquarkus.native.native-image-xmx=4g

Finally when I ran the native image, it failed.

❯ ~/projects/quarkus-spring/target ./quarkus-spring-1.0-SNAPSHOT-runner                                      
[1]    11638 killed     ./quarkus-spring-1.0-SNAPSHOT-runner

Any help?

Viswanath
  • 1,413
  • 13
  • 25
  • [This bug](https://github.com/oracle/graal/issues/2666) seems to indicate that M1 support is not complete yet. – stdunbar Jun 22 '21 at 19:59

3 Answers3

4

The documentation explains that -Dquarkus.native.container-build=true option means that you want to build a Linux executable and that the build should happen in a container. You can even control the runtime for that Docker/Podman with:

# Docker
./mvnw package -Pnative -Dquarkus.native.container-build=true -Dquarkus.native.container-runtime=docker
# Podman
./mvnw package -Pnative -Dquarkus.native.container-build=true -Dquarkus.native.container-runtime=podman

It's likely the reason why the executable doesn't work on MacOS after your last command since it's a Linux binary. You can check that with:

file ./quarkus-spring-1.0-SNAPSHOT-runner

Though in the command line you're using "-Dquarkus.native.docker-build=true" instead of "-Dquarkus.native.container-build.true", and I don't know if has any relevance.

Oleg Šelajev
  • 3,530
  • 1
  • 17
  • 25
  • 1
    Thank you for your answer. it seems that the native linux image built is for x86-64 architecture. Can one also build an image for arm 64 architecture? – Viswanath Jun 24 '21 at 20:10
  • 1
    GraalVM works on Linux aarch64, you (here's for example the link to the current base binary: https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.1.0/graalvm-ce-java11-linux-aarch64-21.1.0.tar.gz) You'll need corresponding hardware though to run it. Here's an example of using Oracle cloud free Arm VM for building native image: https://www.youtube.com/watch?v=fh009OWr8Ks – Oleg Šelajev Jun 28 '21 at 11:00
0

This Answer from another similar question worked for me. Basically you just need to build base graalvm image on your M1 laptop and reference that image (e.g. here the image is tagged as graalvm) using -Dquarkus.native.builder-image=graalvm

David Tam
  • 485
  • 5
  • 13
0

If you are using macOS Catalina and later you may need to remove the quarantine attribute from the bits before you can use them To do this, run the following:

$ sudo xattr -r -d com.apple.quarantine path/to/graalvm/folder/

Based on Graal commit: https://github.com/oracle/graal/tree/vm-22.1.0

Procrastinator
  • 2,526
  • 30
  • 27
  • 36