////
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
////
= Arthur Implementation

Arthur implementation provides `org.apache.geronimo.arthur.impl.nativeimage.ArthurNativeImageExecutor` which executes the extensions and run `native-image`.

== Dependencies

[source,xml]
----
<dependency>
  <groupId>org.apache.geronimo.arthur</groupId>
  <artifactId>arthur-impl</artifactId>
  <version>${arthur.version}</version>
</dependency>
----

== Usage

By itself implementation module will miss a class finder and a JSON serializer.
You will likely want to add these dependencies to be able to use it in standalone mode - maven plugin does it for you:

[source,xml]
----
<dependency>
  <groupId>org.apache.xbean</groupId>
  <artifactId>xbean-finder-shaded</artifactId>
</dependency>
<dependency>
  <groupId>org.apache.geronimo.specs</groupId>
  <artifactId>geronimo-json_1.1_spec</artifactId>
</dependency>
<dependency>
  <groupId>org.apache.geronimo.specs</groupId>
  <artifactId>geronimo-jsonb_1.0_spec</artifactId>
</dependency>
<dependency>
  <groupId>org.apache.johnzon</groupId>
  <artifactId>johnzon-jsonb</artifactId>
</dependency>
----

Once you have that you can create a `Jsonb` instance to serialize the model and an `AnnotationFinder` to let `Context#finder` be implemented:

[source,java]
----
try (final Jsonb jsonb = JsonbBuilder.create(new JsonbConfig()
             .setProperty("johnzon.cdi.activated", false)
             .withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL))) {
    final AnnotationFinder finder = new AnnotationFinder(createScannedArchive());
    // finder.link() if you want to use findImplementations()
    new ArthurNativeImageExecutor(
        ArthurNativeImageExecutor.ExecutorConfiguration.builder()
                .jsonSerializer(jsonb::toJson)
                .annotatedClassFinder(finder::findAnnotatedClasses)
                .annotatedMethodFinder(finder::findAnnotatedMethods)
                .implementationFinder(p -> Collection.class.cast(finder.findImplementations(p)))
                .configuration(configuration)
                .workingDirectory(workdir.toPath().resolve("generated_configuration"))
                .build())
        .run();
} catch (final Exception e) {
    throw new IllegalStateException(e);
} finally {
    thread.setContextClassLoader(oldLoader);
}
----

== GraalVM Installer

The implementation module also contains the building block to install GraalVM locally.
It is based on `org.apache.geronimo.arthur.impl.nativeimage.installer.SdkmanGraalVMInstaller`.
The high level mecanism is to download it from an URL and cache it locally (archive + exploded folder).
For that it needs an "extractor" implementation which supports `tar.gz` on linux and `zip` on windows/cygwin.
You can use the provided `Extractor` class but then you need to add `commons-compress`:

[source,xml]
----
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-compress</artifactId>
  <version>1.19</version>
</dependency>
----

Once done the usage is pretty straigh forward:

[source,java]
----
final Path cache = Paths.get("cached-graal.tar.gz");
final Path workdir = Paths.get(System.getProperty("java.io.tmpdir")).resolve("graal_work_dir");
final SdkmanGraalVMInstallerConfiguration config = SdkmanGraalVMInstallerConfiguration.builder()
    .offline(offline)
    .inheritIO(inheritIO)
    .url("https://api.sdkman.io/2/broker/download/java/19.2.1-grl/linux64")
    .version("19.2.1")
    .platform("linux64")
    .gav("com.oracle.graal:graalvm:tar.gz:19.2.1")
    .workdir(workdir)
    // use built-in commons-compress based extractor, alternative you can do an exec of tar command if preferred
    .extractor(new Extractor()::unpack)
    // hardcoded cache
    .resolver(gav -> cache)
    .installer((gav, file) -> Files.copy(file, cache))
    .build();
final SdkmanGraalVMInstaller graalInstaller = new SdkmanGraalVMInstaller(config);
final Path graalHome = graalInstaller.install();
configuration.setNativeImage(graalInstaller.installNativeImage().toAbsolutePath().toString());
----


---

Previous: link:spi.html[Arthur SPI] Next: link:maven.html[Arthur Maven Plugin]
