Есть ли способ использовать kotlin.random.Random внутри собственного образа GraalVM

Я попытался создать простое приложение с Kotlin, которое использует класс kotlin.random.Random в собственном образе GraalVM. Но это не удается во время выполнения. Stacktrace см. Ниже.

В качестве обходного пути вы можете использовать стандартный java-класс java.util.Random.

Может кто подскажет, как использовать тип Kotlin?

App.kt

import kotlin.random.Random

fun main(args: Array<String>) {
   println(Random.nextInt())
}

Dockerfile

############################################################################
# Graal Native Image Early-Access Build
#
# Make sure you configured Docker to use at least 6gb ram!
# build from project root dir with: docker build -t example-kotlin-random-graalvm-native:1.0.0-SNAPSHOT .
# run with: docker run -d example-kotlin-random-graalvm-native:1.0.0-SNAPSHOT
############################################################################
#####
# The builder image to build the native app
#####
FROM findepi/graalvm:native as builder
LABEL stage=builder

WORKDIR /builder
COPY ./build/libs/app-all.jar ./app.jar
RUN native-image \
    --no-fallback \
    --static \
    -jar app.jar

#####
# The actual image to run
#####
FROM alpine:3.9
RUN apk --no-cache add ca-certificates

# App
WORKDIR /app
COPY --from=builder /builder/app .
EXPOSE $PORT
ENTRYPOINT ["./app"]

Ошибка выполнения

Exception in thread "main" java.lang.ExceptionInInitializerError

at com.oracle.svm.core.hub.ClassInitializationInfo.initialize(ClassInitializationInfo.java:290)

at java.lang.Class.ensureInitialized(DynamicHub.java:475)

at kotlin.random.Random.<clinit>(Random.kt:242)

at com.oracle.svm.core.hub.ClassInitializationInfo.invokeClassInitializer(ClassInitializationInfo.java:350)

at com.oracle.svm.core.hub.ClassInitializationInfo.initialize(ClassInitializationInfo.java:270)

at com.example.AppKt.main(App.kt:8)

Caused by: java.lang.InstantiationException: Type `kotlin.internal.jdk8.JDK8PlatformImplementations` can not be instantiated reflectively as it does not have a no-parameter constructor or the no-parameter constructor has not been added explicitly to the native image.

at java.lang.Class.newInstance(DynamicHub.java:793)

at kotlin.internal.PlatformImplementationsKt.<clinit>(PlatformImplementations.kt:41)

... 6 more

Минимальный рабочий пример проекта здесь


person Oliver    schedule 28.04.2020    source источник
comment
Я не использовал Kotlin, но подозреваю, что вам нужно включить библиотеки Kotlin в вызов native-image.   -  person David Conrad    schedule 28.04.2020
comment
похоже, что kotlin использует там отражение, возможно, вам придется использовать настройка отражения вручную.   -  person Gilles D.    schedule 29.04.2020


Ответы (1)


Вам необходимо изменить правила отражения < br /> добавьте следующее к аргументам native-image:

-H:ReflectionConfigurationFiles=/path/to/reflectconfig

и поместите правила для затронутого класса в файл Reflectionconfig:

[{
    "name" : "kotlin.internal.jdk8.JDK8PlatformImplementations",
    "allDeclaredConstructors" : true,
    "allPublicConstructors" : true,
    "allDeclaredFields" : true,
    "allPublicFields" : true,
    "allDeclaredMethods" : true,
    "allPublicMethods" : true
}]

в качестве альтернативы вы также можете указать метод инициализации в том же файле, прочтите это

person Francesco    schedule 19.08.2020