Arthur Logo Apache Geronimo Arthur
  • Apache
  • Documentation
  • Community
  • Downloads
  • ASF
    License Sponsorship Thanks
    Security

Apache Geronimo Arthur Maven

Arthur Maven plugin provides a way to generate native-image configuration and execute it. It also enables to automatically download GraalVM avoiding you to manage the installation part.

Get started in 5 minutes

First thing to do to enable a native build of your application is to add the plugin with your application entry point (main(String[])):

<plugin>
    <groupId>org.apache.geronimo.arthur</groupId>
    <artifactId>arthur-maven-plugin</artifactId>
    <version>${arthur.version}</version>
    <configuration>
        <main>org.kamelot.Florida</main> (1)
    </configuration>
</plugin>
1 The application to compile natively

Once it is done, you can run mvn [process-classes] arthur:native-image.

Graal Setup

You probably notices that in previous part we didn’t mention you need to set your JAVA_HOME to a Graal instance or so. This is because the plugin is able to download GraalVM if it is not already done and to install - using GraalVM gu tool - `native-image`extension. You will find all the details of that feature in the configuration section but it is important to note a few points:

  1. You can explicit the native-image instance to use and avoid the implicit installation setting the configuration nativeImage,

  2. GraalVM version is configurable (note that it relies on SDKMan by default so ensure the last version you want to upgrade immediately is available),

  3. The plugin caches the GraalVM archive and its unpack flavor in your local maven repository to avoid to download and explode it each time.

Tip on graalVersion

Apache Arthur is able to deduce the download URL of Graal distribution if it is not explicit configured from graalVersion. This enables to avoid to handle the platform with profiles in your own build. Here are the supported download flavors:

  • If a download URL is set starting with https://api.sdkman.io/2/broker/download/java/ it will be used (SDKMan). Note that SDKMan does not guanratee your version will be resolvable after some time so good for tests mainly. graalVersion is the SDKMan version,

  • Else by default we use https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${graalSimpleVersion}/graalvm-ce-java${graalJavaVersion}-${githubPlatform}-${graalSimpleVersion}.tar.gz. graalVersion is $graalVersion.r$mainJavaVersion, ex: 22.0.3.r17,

  • Else if graalVersion is $javaVersion-graalce we use https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-$javaVersion/graalvm-community-jdk-$javaVersion_${githubPlatform2}_bin.tar.gz,

  • Else if graalVersion is $javaVersion-graal-oracle we use https://download.oracle.com/graalvm/$javaVersion/latest/graalvm-jdk-$javaVersion_${githubPlatform2}_bin.tar.gz,

  • Else we use the provided download url which can use the following placeholders:

    • graalSimpleVersion: if there is a .r$javaVersion at the end of the graalVersion it is the version without this suffix else graalVersion,

    • graalJavaVersion: graalVersion sanitized from its suffix (.r$javaVersion, -graalce, -graal-oracle),

    • githubPlatform: platform deduced from the running JVM one (build one), it ends with -amd64,

    • githubPlatform2: platform deduced from the running JVM one (build one), it ends with -x64 - graalce/graal-oracle cases.

Execution example

Here is a dump of a sample execution:

$ mvn arthur:native-image -o
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------< org.apache.geronimo.arthur:sample >---------------------
[INFO] Building Arthur :: Sample 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- arthur-maven-plugin:1.0.0-SNAPSHOT:native-image (default-cli) @ jdbc ---
[INFO] Using GRAAL: /home/rmannibucau/.m2/repository/org/apache/geronimo/arthur/cache/graal/19.2.1/distribution_exploded (1)
[INFO] Extension org.apache.geronimo.arthur.maven.extension.MavenArthurExtension updated build context (2)
[INFO] Creating resources model '/opt/dev/arthur/sample/target/arthur_workdir/generated_configuration/resources.arthur.json' (3)
[INFO] Creating dynamic proxy model '/opt/dev/arthur/sample/target/arthur_workdir/generated_configuration/dynamicproxies.arthur.json' (3)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]    classlist:   6,427.14 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]        (cap):   2,126.93 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]        setup:   3,480.51 ms (4)
ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: Provider com.oracle.truffle.js.scriptengine.GraalJSEngineFactory could not be instantiated
ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: Provider com.oracle.truffle.js.scriptengine.GraalJSEngineFactory could not be instantiated
/opt/dev/arthur/sample/target/sample.graal.bin:16697]   (typeflow):  15,605.58 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]    (objects):  11,369.56 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]   (features):   1,901.64 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]     analysis:  30,057.86 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]     (clinit):     568.59 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]     universe:   1,196.02 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]      (parse):   2,334.15 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]     (inline):   3,093.09 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]    (compile):  20,410.16 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]      compile:  27,352.51 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]        image:   2,792.40 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]        write:     677.26 ms (4)
/opt/dev/arthur/sample/target/sample.graal.bin:16697]      [total]:  72,280.13 ms (4)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:14 min
[INFO] Finished at: 2019-10-29T17:55:16+01:00
[INFO] ------------------------------------------------------------------------
1 The GraalVM distribution was already existing so was not download and was directly used,
2 Maven inline Graal configuration (resources, reflection, bundles) was set up,
3 Dynamic (Arthur prebuild phase) configuration was dumped before launching native-image,
4 native-image execution/phases

Native Image Mojo configuration

The plugin is quite configurable and even enable to build a main in a test scope. Here is the full list of available configuration.

Name Type Description

addAllCharsets

boolean

Should all charsets be added.

Default value: true

User property: arthur.addAllCharsets

allowIncompleteClasspath

Boolean

Should incomplete classpath be tolerated.

Default value: -

User property: arthur.allowIncompleteClasspath

attach

boolean

Should binary artifact be attached.

Default value: true

User property: arthur.attach

attachClassifier

String

If attach is true, the classifier to use the binary file, none will skip the classifier.

Default value: arthur

User property: arthur.attachClassifier

attachType

String

If attach is true, the type to use to attach the binary file.

Default value: bin

User property: arthur.attachType

buildStaticImage

boolean

Should the image be static or dynamic (jvm part).

Default value: true

User property: arthur.buildStaticImage

bundles

List

Inline resource bundle model (appended to reflectionConfigurationFiles).

Default value: -

User property: -

classpath

List

custom pre-built classpath, if not set it defaults on the project dependencies.

Default value: -

User property: arthur.classpath

customOptions

List

Generates a native binary from current project.custom native-image arguments.

Default value: -

User property: arthur.customOptions

dynamicProxies

List

Inline dynamic proxy configuration (appended to dynamicProxyConfigurationFiles).

Default value: -

User property: -

dynamicProxyConfigurationFiles

List

JSON java.lang.reflect.Proxy configuration.

Default value: -

User property: arthur.dynamicProxyConfigurationFiles

enableAllSecurityServices

Boolean

Should security services be included.

Default value: -

User property: arthur.enableAllSecurityServices

enforceMaxRuntimeCompileMethods

boolean

Enforce maxRuntimeCompileMethods.

Default value: true

User property: arthur.enforceMaxRuntimeCompileMethods

excludedArtifacts

List

groupId:artifactId list of ignored artifact during the pre-build phase.

Default value: -

User property: arthur.excludedArtifacts

extensionProperties

Map

Properties passed to the extensions if needed.

Default value: -

User property: -

fallbackMode

FallbackMode

Behavior when native compilation fails, it is recommended to keep it to "no".Supported values are no, force and auto.

Default value: no

User property: arthur.fallbackMode

graalDownloadUrl

String

In case Graal must be downloaded to get native-image, where to take it from.

Default value: auto

User property: arthur.graalDownloadUrl

graalExtensions

List

<groupId>:<artifactId>[:<extension>[:<classifier>]]:<version> list of artifacts appended to graal build.If you don’t want transitive dependencies to be included, you can append to the coordinates ?transitive=false.

Default value: -

User property: arthur.graalExtensions

graalPlatform

String

In case Graal must be downloaded to get native-image, which platform to download, auto will handle it for you.

Default value: auto

User property: arthur.graalPlatform

graalVersion

String

In case Graal must be downloaded to get native-image, which version to download.It contains the graal version and can be suffixed by the graal java version prefixed with "r" (as on sdkman).Alternatively, in more recent version you can use "$javaVersion-graalce" or "$javaVersion-graal-oracle" to use the appropriated mirror.

Default value: 20.3.0.r8

User property: arthur.graalVersion

groupId:artifactI

String

In case Graal must be downloaded to get native-image, it will be cached in the local repository with this gav.

Default value: org.apache.geronimo.arthur.cache:graal

User property: arthur.graalCacheGav

includeResourceBundles

List

resource bundle qualified names to include.

Default value: -

User property: arthur.includeResourceBundles

inheritIO

boolean

The execution will fork native-image process, should IO be inherited from maven process (recommended).

Default value: true

User property: arthur.inheritIO

initializeAtBuildTime

List

Classes to initialize at build time.

Default value: -

User property: arthur.initializeAtBuildTime

initializeAtRunTime

List

Classes to intiialize at run time.

Default value: -

User property: arthur.initializeAtRunTime

main*

String

Which main to compile.

Default value: -

User property: arthur.main

maxRuntimeCompileMethods

int

Limit the number of compilable methods.

Default value: 1000

User property: arthur.maxRuntimeCompileMethods

nativeImage

String

native-image binary to use, if not set it will install graal in the local repository.

Default value: -

User property: arthur.nativeImage

noServer

boolean

Should graal build server be used (a bit like gradle daemon), it is very discouraged to be used cause invalidation is not yet well handled.Deprecated in recent graalvm versions.

Default value: false

User property: arthur.noServer

output

String

Where to put the output binary.

Default value: ${project.build.directory}/${project.artifactId}.graal.bin

User property: arthur.output

printClassInitialization

boolean

Should initialiation of classes be printed - mainly for debug purposes.

Default value: false

User property: arthur.printClassInitialization

propertiesPrefix

String

Once built, the binary path is set in maven properties.This enables to configure the prefix to use.

Default value: arthur.

User property: arthur.propertiesPrefix

reflectionConfigurationFiles

List

JSON reflection configuration.

Default value: -

User property: arthur.reflectionConfigurationFiles

reflections

List

Inline configuration model (appended to reflectionConfigurationFiles).

Default value: -

User property: -

reportExceptionStackTraces

boolean

Should exception stacks be reported.

Default value: true

User property: arthur.reportExceptionStackTraces

reportUnsupportedElementsAtRuntime

boolean

Should unsupported element be reported at runtime or not. It is not a recommended option but it is often needed.

Default value: true

User property: arthur.reportUnsupportedElementsAtRuntime

resources

List

Inline resources model (appended to resourcesConfigurationFiles).

Default value: -

User property: -

resourcesConfigurationFiles

List

JSON resources configuration.

Default value: -

User property: arthur.resourcesConfigurationFiles

scanningClassesOrPackagesExcludes

List

Classes or packages (startsWith is used to test entries).

Default value: -

User property: arthur.scanningClassesOrPackagesExcludes

scanningExcludedArtifacts

List

groupId:artifactId list of ignored artifact during the scanning phase.Compared to excludedArtifacts, it keeps the jar in the scanning/extension classloaderbut it does not enable to find any annotation in it.Note that putting * will disable the scanning completely.

Default value: -

User property: arthur.scanningExcludedArtifacts

skip

boolean

Should this mojo be skipped.

Default value: -

User property: arthur.skip

supportTestArtifacts

boolean

Should the build be done with test dependencies (and binaries).

Default value: false

User property: arthur.supportTestArtifacts

supportedTypes

List

List of types used in the build classpath, typically enables to ignore tar.gz/natives for example.

Default value: jar,zip

User property: arthur.supportedTypes

usePackagedArtifact

boolean

Should jar be used instead of exploded folder (target/classes).Note this option disable the support of module test classes.

Default value: false

User property: arthur.usePackagedArtifact

useTcclAsScanningParentClassLoader

boolean

By default arthur runs the extension with a dedicated classloader built from the project having as parent the JVM,this enables to use the mojo as parent instead).

Default value: false

User property: arthur.useTcclAsScanningParentClassLoader

workdir

File

Where the temporary files are created.

Default value: ${project.build.directory}/arthur_workdir

User property: -

if you want to debug native image generation, you must add org.graalvm.nativeimage:svm dependency and add the customOption --debug-attach.

What about docker?

One of the main reasons to go native is to reduce the startup latency and the memory consumption. This is literally a paraphrase to say we want to run into Kubernetes. Therefore the question to bundle the native binary as a docker image comes pretty quickly.

Sample Dockerfile

There are multiple option to create a docker image but one interesting point to mention is to build the binary in a docker image to ensure the target binary matches the target image architecture. For that case, we recommend you to build your project as you want, copy the project in a builder docker image and use a multi-stage builder to ensure you build on the platform you will run (the FROM of your Dockerfile).

to avoid a lot of downloads/latency it can be neat to not bind arthur:native-image plugin goal to any phase and just call it explicitly in your build. To do that just use <phase /> instead of an explicit phase if you define a custom execution.

Here is an example:

FROM maven:3.6-jdk-8-slim AS builder
COPY . /project
COPY target/m2 /root/.m2/repository
WORKDIR /project
RUN mvn package arthur:native-image

FROM scratch
COPY --from=builder /project/target/myapp.graal.bin /project/myapp.graal.bin
ENTRYPOINT [ "/project/myapp.graal.bin" ]

To avoid to download all needed dependencies all the time don’t forget to prepare a local copy of the maven repository, here is how to launch this docker creation assuming you put this Dockerfile at the root of your maven project:

# prepare the local copy of the m2 with dependency plugin (for examples, some other plugins will also include build maven plugins in the dedicated m2)
mvn dependency:copy-dependencies -Dmdep.useRepositoryLayout=true -DoutputDirectory=target/m2

# actually build
docker build -t sample:latest
you can also do the package on your machine and skip it in the docker build but the tip to prepare a local m2 copy is still helping to speed up the build.
if you use private repositories, don’t forget to copy your settings.xml as well (in /root/.m2 for maven/builder image).
when building on a jenkins running on Kubernetes, ensure to use a build image with an architecture compatible, this avoids all that setup and you can just run it directly as if it was locally.

Jib to create an image

Jib is an awesome project propulsed by Google enabling to build docker images without docker. It can be used to put your binary into a very light image (based on the "empty" scratch one). Here is how to add it to your pom:

<plugin> (1)
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>1.7.0</version>
    <configuration>
        <from>
            <image>scratch</image> (2)
        </from>
        <to>
            <image>sample:latest</image>
        </to>
        <extraDirectories>
            <paths>
                <path>${project.build.directory}/graal</path> (3)
            </paths>
            <permissions>
                <permission> (4)
                    <file>/sample.graal.bin</file>
                    <mode>755</mode>
                </permission>
            </permissions>
        </extraDirectories>
        <container>
            <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
            <entrypoint>
                <arg>/sample.graal.bin</arg> (5)
            </entrypoint>
        </container>
    </configuration>
</plugin>
1 Add jib-maven-plugin in your pom.xml
2 Use scratch keyword as base image (which almost means "nothing" or "empty image")
3 Reference the folder containing your binary (you can desire to tune the output`parameter of the `arthur-maven-plugin to ensure the folder only contains your binary since the full folder will be added to the image)
4 Ensure the binary has the right permission (executable)
5 Set the binary as entrypoint

Then you can create your docker image just launching: mvn jib:dockerBuild.

you can also directly push to a remote repository without the need of having a local docker daemon, see Jib documentation for more details.
in current jib version, the dependencies are build artifacts are still added to the image so you can have some "dead" code with that option. To avoid it you can switch to arthur:docker or arthur:image goals.

Arthur Docker

arthur-maven-plugin enables to build a docker image with a plain binary built with native-image. Its usage is close to jib - with a simpler configuration - but it also can be combine with native-image goal:

mvn arthur:native-image arthur:docker

Output looks like:

$ mvn arthur:native-image arthur:docker
[INFO] Scanning for projects...
[INFO]
[INFO] ---------------------< org.apache.geronimo.Arthur:sample >---------------------
[INFO] Building Arthur :: Sample 1.0.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- arthur-maven-plugin:1.0.0-SNAPSHOT:native-image (default-cli) @ sample ---
[INFO] Using GRAAL: /home/rmannibucau/.m2/repository/org/apache/geronimo/arthur/cache/graal/19.2.1/distribution_exploded
[INFO] Extension org.apache.geronimo.arthur.maven.extension.MavenArthurExtension updated build context
[INFO] Creating resources model '/media/data/home/rmannibucau/1_dev/connectors-se/jdbc/target/arthur_workdir/generated_configuration/resources.arthur.json'
[INFO] Creating dynamic proxy model '/media/data/home/rmannibucau/1_dev/connectors-se/jdbc/target/arthur_workdir/generated_configuration/dynamicproxies.arthur.json'
...same as before
[INFO]
[INFO] --- arthur-maven-plugin:1.0.0-SNAPSHOT:docker (default-cli) @ sample ---
[INFO] Containerizing application with the following files:
[INFO] 	Binary:
[INFO] 		/opt/geronimo/arthur/sample/target/sample.graal.bin
[INFO] Getting scratch base image...
[INFO] Building Binary layer...
[INFO]
[INFO] Container entrypoint set to [/sample]
[INFO] Container program arguments set to []
[INFO] Loading to Docker daemon...
[INFO] Built 'sample:1.0.0-SNAPSHOT'
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  01:29 min
[INFO] Finished at: 2019-10-30T10:51:43+01:00
[INFO] ------------------------------------------------------------------------

LDD or not

By default Arthur maven docker/image plugins assume the binary is self executable by itself (statically linked). If it is not the case, you need to ensure the from/base image has the needed libraries. It is not always trivial nor convenient so we have a mode using the build machine ldd to detect which libs are needed and add them in the image parsing ldd output.

this mode enables to build very light native images using scratch virtual base image (empty) but it can conflict with other base images since it sets LD_LIBRARY_PATH if not present int he environment configuration.

Here is what the ldd output look like - if not the case ensure to set a PATH before running the plugin which has a compliant ldd:

$ ldd doc.graal.bin
        linux-vdso.so.1 (0x00007ffcc41ba000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f4ad85e7000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4ad85e1000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4ad83ef000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f4adba6b000)

The parser will take all line containing a / and the first string without any space starting by a / will be considered as a path of a library to include. With previous output, the image will get libpthread.so.0, libdl.so.2, libc.so.6 and ld-linux-x86-64.so.2 included (but not linux-vdso.so.1 since it is not a path / it has no slash in the line).

Configuration

Name Type Description

allowInsecureRegistries

boolean

Are insecure registries allowed.

Default value: false

User property: arthur.allowInsecureRegistries

applicationLayersCache

File

Where to cache application layers.

Default value: ${project.build.directory}/arthur_jib_cache/application

User property: arthur.applicationLayersCache

baseLayersCache

File

Where to cache base layers layers (if any).

Default value: ${project.build.directory}/arthur_jib_cache/base

User property: arthur.baseLayersCache

binarySource

File

Where is the binary to include. It defaults on native-image output if done before in the same execution

Default value: ${project.build.directory}/${project.artifactId}.graal.bin

User property: arthur.binarySource

cacertsTarget

String

When includeCacerts, the file which will contain the certificates in the image.

Default value: /certificates/cacerts

User property: arthur.cacertsDir

creationTimestamp

long

Timestamp creation for the image, it is recommended to set it fixed for reproducibility.

Default value: 1

User property: arthur.creationTimestamp

enableCache

boolean

Should base images be cached.

Default value: true

User property: arthur.enableCache

entrypoint

List

Entry point to use.

Default value: /${project.artifactId}

User property: arthur.entrypoint

environment

Map

Image environment.

Default value: -

User property: arthur.environment

from

String

Base image to use. Scratch will ensure it starts from an empty image and is the most minimal option.For a partially linked use busybox:glibc.Note that using scratch can require you to turn on useLDD flag (not by default since it depends in your build OS).On the opposite, using an existing distribution (debian, fedora, …​) enables to not do that at the cost of a bigger overall image.However, not only the overall image size is important, the reusable layers can save network time so pick what fits the best your case.

Default value: scratch

User property: arthur.from

graalDownloadUrl

String

In case Graal must be downloaded to get native-image, where to take it from.

Default value: auto

User property: arthur.graalDownloadUrl

graalPlatform

String

In case Graal must be downloaded to get native-image, which platform to download, auto will handle it for you.

Default value: auto

User property: arthur.graalPlatform

graalVersion

String

In case Graal must be downloaded to get native-image, which version to download.It contains the graal version and can be suffixed by the graal java version prefixed with "r" (as on sdkman).Alternatively, in more recent version you can use "$javaVersion-graalce" or "$javaVersion-graal-oracle" to use the appropriated mirror.

Default value: 20.3.0.r8

User property: arthur.graalVersion

groupId:artifactI

String

In case Graal must be downloaded to get native-image, it will be cached in the local repository with this gav.

Default value: org.apache.geronimo.arthur.cache:graal

User property: arthur.graalCacheGav

includeCacerts

boolean

Should cacerts be included.

Default value: false

User property: arthur.includeCacerts

includeNatives

List

Should JVM native libraries be included, it is useful to get libraries like sunec (security).Value can be false to disable it (empty or null works too), true to include them allor a list of lib names like sunec.

Default value: false

User property: arthur.includeNatives

labels

Map

Image labels.

Default value: -

User property: arthur.labels

nativeImage

String

native-image binary to use, if not set it will install graal in the local repository.

Default value: -

User property: arthur.nativeImage

nativeRootDir

String

When includeNatives, the directory which will contain the natives in the image.

Default value: /native

User property: arthur.nativeRootDir

otherFiles

List

Other files to include in the image, note that their permissions will not be executable.

Default value: -

User property: arthur.files

ports

List

Ports to expose.

Default value: -

User property: arthur.ports

programArguments

List

Program arguments.

Default value: -

User property: arthur.programArguments

propertiesPrefix

String

Once built, the binary path is set in maven properties.This enables to configure the prefix to use.

Default value: arthur.

User property: arthur.propertiesPrefix

skipLdLinuxInEntrypoint

boolean

If true, and even if useLDD is true, ld-linux will not be in entrypoint.

Default value: false

User property: arthur.skipLdLinuxInEntrypoint

threads

int

Number of threads used to build.

Default value: 1

User property: arthur.threads

timeout

long

Build timeout in milliseconds if it is using threads > 1.

Default value: 3600000

User property: arthur.timeout

to

String

Target image name.

Default value: ${project.artifactId}:${project.version}

User property: arthur.to

useLDD

boolean

If true, the created binary will be passed to ldd to detect the needed libraries.It enables to use FROM scratch even when the binary requires dynamic linking.Note that if ld-linux libraries is found by that processing it is set as first argument of the entrypointuntil skipLdLinuxInEntrypoint is set to true.

Default value: false

User property: arthur.useLDD

workdir

File

Where the temporary files are created.

Default value: ${project.build.directory}/arthur_workdir

User property: -

Arthur Image

Similarly to docker goal, the plugin can generate an image. To do it just replace the arthur:docker by arthur:image.

this goal does not need a docker daemon on the machine, it just uses HTTP(S) communication with a registry.
if you use static build you can use scratch as base image (empty) but if you use -H:+StaticExecutableWithDynamicLibC which statically link everything but glic you should switch to busybox:glic for example. Also note that some applications will require more libraries like libdl so ensure to adjust your base image on your usage.

Configuration

Name Type Description

allowInsecureRegistries

boolean

Are insecure registries allowed.

Default value: false

User property: arthur.allowInsecureRegistries

applicationLayersCache

File

Where to cache application layers.

Default value: ${project.build.directory}/arthur_jib_cache/application

User property: arthur.applicationLayersCache

baseLayersCache

File

Where to cache base layers layers (if any).

Default value: ${project.build.directory}/arthur_jib_cache/base

User property: arthur.baseLayersCache

binarySource

File

Where is the binary to include. It defaults on native-image output if done before in the same execution

Default value: ${project.build.directory}/${project.artifactId}.graal.bin

User property: arthur.binarySource

cacertsTarget

String

When includeCacerts, the file which will contain the certificates in the image.

Default value: /certificates/cacerts

User property: arthur.cacertsDir

creationTimestamp

long

Timestamp creation for the image, it is recommended to set it fixed for reproducibility.

Default value: 1

User property: arthur.creationTimestamp

enableCache

boolean

Should base images be cached.

Default value: true

User property: arthur.enableCache

entrypoint

List

Entry point to use.

Default value: /${project.artifactId}

User property: arthur.entrypoint

environment

Map

Image environment.

Default value: -

User property: arthur.environment

from

String

Base image to use. Scratch will ensure it starts from an empty image and is the most minimal option.For a partially linked use busybox:glibc.Note that using scratch can require you to turn on useLDD flag (not by default since it depends in your build OS).On the opposite, using an existing distribution (debian, fedora, …​) enables to not do that at the cost of a bigger overall image.However, not only the overall image size is important, the reusable layers can save network time so pick what fits the best your case.

Default value: scratch

User property: arthur.from

graalDownloadUrl

String

In case Graal must be downloaded to get native-image, where to take it from.

Default value: auto

User property: arthur.graalDownloadUrl

graalPlatform

String

In case Graal must be downloaded to get native-image, which platform to download, auto will handle it for you.

Default value: auto

User property: arthur.graalPlatform

graalVersion

String

In case Graal must be downloaded to get native-image, which version to download.It contains the graal version and can be suffixed by the graal java version prefixed with "r" (as on sdkman).Alternatively, in more recent version you can use "$javaVersion-graalce" or "$javaVersion-graal-oracle" to use the appropriated mirror.

Default value: 20.3.0.r8

User property: arthur.graalVersion

groupId:artifactI

String

In case Graal must be downloaded to get native-image, it will be cached in the local repository with this gav.

Default value: org.apache.geronimo.arthur.cache:graal

User property: arthur.graalCacheGav

includeCacerts

boolean

Should cacerts be included.

Default value: false

User property: arthur.includeCacerts

includeNatives

List

Should JVM native libraries be included, it is useful to get libraries like sunec (security).Value can be false to disable it (empty or null works too), true to include them allor a list of lib names like sunec.

Default value: false

User property: arthur.includeNatives

labels

Map

Image labels.

Default value: -

User property: arthur.labels

nativeImage

String

native-image binary to use, if not set it will install graal in the local repository.

Default value: -

User property: arthur.nativeImage

nativeRootDir

String

When includeNatives, the directory which will contain the natives in the image.

Default value: /native

User property: arthur.nativeRootDir

otherFiles

List

Other files to include in the image, note that their permissions will not be executable.

Default value: -

User property: arthur.files

ports

List

Ports to expose.

Default value: -

User property: arthur.ports

programArguments

List

Program arguments.

Default value: -

User property: arthur.programArguments

propertiesPrefix

String

Once built, the binary path is set in maven properties.This enables to configure the prefix to use.

Default value: arthur.

User property: arthur.propertiesPrefix

serverId

String

Alternate mojo to jib:build to avoid to bundle useless files.Can be replaced by vanilla jib when it will support it, see https://github.com/GoogleContainerTools/jib/issues/1857Server identifier (in settings.xml) used to authenticate to the remote image registry.

Default value: -

User property: arthur.serverId

skipLdLinuxInEntrypoint

boolean

If true, and even if useLDD is true, ld-linux will not be in entrypoint.

Default value: false

User property: arthur.skipLdLinuxInEntrypoint

threads

int

Number of threads used to build.

Default value: 1

User property: arthur.threads

timeout

long

Build timeout in milliseconds if it is using threads > 1.

Default value: 3600000

User property: arthur.timeout

to

String

Target image name.

Default value: ${project.artifactId}:${project.version}

User property: arthur.to

useLDD

boolean

If true, the created binary will be passed to ldd to detect the needed libraries.It enables to use FROM scratch even when the binary requires dynamic linking.Note that if ld-linux libraries is found by that processing it is set as first argument of the entrypointuntil skipLdLinuxInEntrypoint is set to true.

Default value: false

User property: arthur.useLDD

workdir

File

Where the temporary files are created.

Default value: ${project.build.directory}/arthur_workdir

User property: -

Advanced example

Just to give a real world configuration, here is how a simple JDBC application can be natified. It configure some resource bundle, setup h2 driver and exclude derby from the build classpath:

<plugin>
    <groupId>org.apache.geronimo.arthur</groupId>
    <artifactId>arthur-maven-plugin</artifactId>
    <version>${arthur.version}</version>
    <configuration>
        <main>org.talend.components.jdbc.graalvm.MainTableNameInputEmitter</main>
        <supportTestArtifacts>true</supportTestArtifacts> <!-- for demo only -->
        <initializeAtBuildTime>
            <initializeAtBuildTime>org.h2.Driver</initializeAtBuildTime>
            <initializeAtBuildTime>org.company.MyProxyInterface1</initializeAtBuildTime>
            <initializeAtBuildTime>org.company.MyProxyInterface2</initializeAtBuildTime>
        </initializeAtBuildTime>
        <bundles>
            <bundle>
                <name>org.company.MyProxyInterface1Messages</name>
            </bundle>
        </bundles>
        <dynamicProxies>
          <dynamicProxy> <!-- short notation -->
              <classes>org.company.MyProxyInterface1</classes>
          </dynamicProxy>
          <dynamicProxy>
              <classes> <!-- long notation -->
                  <class>org.company.MyProxyInterface2</class>
              </classes>
          </dynamicProxy>
        </dynamicProxies>
        <excludedArtifacts> <!-- this setup uses supportTestArtifacts but we assume we don't want derby which is used in test dependencies -->
            <excludedArtifact>org.apache.derby:derby</excludedArtifact>
            <excludedArtifact>org.apache.derby:derbyclient</excludedArtifact>
            <excludedArtifact>org.apache.derby:derbynet</excludedArtifact>
        </excludedArtifacts>
    </configuration>
</plugin>

Then you can just run mvn [package] arthur:native-image arthur:docker to get a ready to deploy image.


Previous: Arthur Implementation Next: Knights

Copyright © 1999-2024 The Apache Software Foundation, Licensed under the Apache License, Version 2.0. Apache Geronimo, Geronimo, Apache, the Apache feather logo, and the Apache Geronimo project logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.