<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>
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.
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
.
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:
You can explicit the native-image
instance to use and avoid the implicit installation setting the configuration nativeImage
,
GraalVM version is configurable (note that it relies on SDKMan by default so ensure the last version you want to upgrade immediately is available),
The plugin caches the GraalVM archive and its unpack flavor in your local maven repository to avoid to download and explode it each time.
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.
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 |
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 Default value: arthur User property: arthur.attachClassifier |
attachType |
String |
If 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 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 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 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 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 |
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 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 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 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 .
|
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.
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 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-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] ------------------------------------------------------------------------
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).
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 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: - |
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.
|
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 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: - |
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