2

In picocli they give examples on how to generate GraalVM reflection configurations during the build for Maven and Gradle.

Gradle example

configurations {
    generateConfig
}
dependencies {
    compile 'info.picocli:picocli:3.9.3'
    generateConfig 'info.picocli:picocli-codegen:3.9.3'
}

task

task(generateGraalReflectionConfig, dependsOn: 'classes', type: JavaExec) {
    main = 'picocli.codegen.aot.graalvm.ReflectionConfigGenerator'
    classpath = configurations.generateConfig + sourceSets.main.runtimeClasspath
    def outputFile = new File(project.buildDir, 'cli-reflect.json')
    args = ["--output=$outputFile", 'com.your.package.YourCommand1', 'com.your.package.YourCommand2']
}
assemble.dependsOn generateGraalReflectionConfig

How could I write something equivalent for sbt ?

This is what I got so far but I don't know if I'm going in the right direction.

import Dependencies._

ThisBuild / scalaVersion := "2.12.8"
ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / organization := "com.example"
ThisBuild / organizationName := "example"

lazy val root = (project in file("."))
  .settings(
    name := "poc-cli",
    libraryDependencies += scalaTest % Test,
    libraryDependencies += "info.picocli" % "picocli" % "3.9.3",
    libraryDependencies += "info.picocli" % "picocli-codegen" % "3.9.3",
  )

lazy val graalConfig = inputKey[Unit]("gen-graal-config") 

graalConfig:= {
    val conf = (runMain in Compile).fullInput(" picocli.codegen.aot.graalvm.ReflectionConfigGenerator --output=cli-reflect.json example.Hello").evaluated
}

enablePlugins(GraalVMNativeImagePlugin)

Edit

in my initial question, I had the code below, with my current code the problem is solved

lazy val graalConfig = taskKey[Unit]("graal-config") := {
    Process("java" :: "-jar" :: "picocli.codegen.aot.graalvm.ReflectionConfigGenerator" :: "--output" :: "cli-reflect.json" :: "???" :: Nil,
        baseDirectory.value / "lib").!
}
Community
  • 1
  • 1
kronolynx
  • 197
  • 2
  • 14

2 Answers2

2

The solution was

import Dependencies._


ThisBuild / scalaVersion := "2.12.8"
ThisBuild / version := "0.1.0-SNAPSHOT"
ThisBuild / organization := "com.example"
ThisBuild / organizationName := "example"

lazy val root = (project in file("."))
  .settings(
    name := "poc-cli",
    libraryDependencies += scalaTest % Test,
    libraryDependencies += "info.picocli" % "picocli" % "3.9.3",
    libraryDependencies += "info.picocli" % "picocli-codegen" % "3.9.3",
  )

lazy val graalConfig = inputKey[Unit]("gen-graal-config")

graalVMNativeImageOptions += "-H:ReflectionConfigurationFiles=../cli-reflect.json"

graalConfig:= {
    (runMain in Compile).fullInput(" picocli.codegen.aot.graalvm.ReflectionConfigGenerator -o=target/cli-reflect.json example.Hello").evaluated
}

enablePlugins(GraalVMNativeImagePlugin)

then I can run:

$ sbt graalConfig
$ sbt graalvm-native-image:packageBin 
kronolynx
  • 197
  • 2
  • 14
2

picocli-codegen fixes picocli project reflections.

There is Graal Reflection Configuration Generator which generates the reflection.json automatically for me and attach it in the resulting jar just by adding it to my dependencies as AnnotationProcessor and annotating the classes, package scan is also supported.

This way you can easily generate reflection config whenever you needs it. Snippet example of how to configure and use it.

build.gradle

dependencies {
  compileOnly("com.mageddo.nativeimage:reflection-config-generator:2.1.1")
  annotationProcessor("com.mageddo.nativeimage:reflection-config-generator:2.1.1")
}

Config.java

@Reflection(declaredConstructors = true, scanPackage = "com.github.vo")
public class Config {}

Maven, and vanilla java are also supported, for more details check GRCG docs, check also this article talking about this tool

deFreitas
  • 4,196
  • 2
  • 33
  • 43
  • The link to the [article](http://bookmarks.mageddo.com/bookmark/634/Automatically-configure-native-image-reflection-configuration) is not accessible without a login... – Remko Popma Dec 02 '19 at 01:22
  • 1
    @RemkoPopma Thanks for the warning, it is working right now – deFreitas Dec 02 '19 at 02:00