Поддержка сценариев Kotlin не работает из-за "неправильного количества аргументов" всякий раз, когда я пытаюсь запустить любой сценарий

Я пытаюсь запустить очень простой скрипт с org.jetbrains.kotlin:kotlin-scripting-jvm, но получаю две ошибки, а не должно быть ни одной. Это мой сценарий:

1

Я ожидаю вернуть ResultWithDiagnostics.Success с resultValue из 1 но вместо этого я получаю Failure, с этими отчетами:

  • Выражение не используется
  • неправильное количество аргументов

Даже если я исправлю предупреждение, изменив свой скрипт на

class Foo(val foo: String = "foo")

Foo()

Я все еще получаю wrong number of arguments error. Я проверил источник и кажется, что в

BasicJvmScriptEvaluator:95
        return try {
            ctor.newInstance(*args.toArray()) <-- here
        } finally {
            Thread.currentThread().contextClassLoader = saveClassLoader
        } 

args пуст. Что я делаю неправильно? Вот как я пытаюсь запустить скрипт:

private fun evalFile(scriptFile: File): ResultWithDiagnostics<EvaluationResult> {
    val compilationConfiguration = createJvmCompilationConfigurationFromTemplate<TestScript> {
        jvm {
            dependenciesFromCurrentContext(wholeClasspath = true)
        }
    }

    return BasicJvmScriptingHost().eval(scriptFile.toScriptSource(), compilationConfiguration, null)
}

и это трассировка стека для этого wrong number of arguments ошибка я получаю:

java.lang.IllegalArgumentException: wrong number of arguments
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at kotlin.script.experimental.jvm.BasicJvmScriptEvaluator.evalWithConfigAndOtherScriptsResults(BasicJvmScriptEvaluator.kt:95)
    at kotlin.script.experimental.jvm.BasicJvmScriptEvaluator.invoke$suspendImpl(BasicJvmScriptEvaluator.kt:40)
    at kotlin.script.experimental.jvm.BasicJvmScriptEvaluator.invoke(BasicJvmScriptEvaluator.kt)
    at kotlin.script.experimental.host.BasicScriptingHost$eval$1.invokeSuspend(BasicScriptingHost.kt:47)
    at kotlin.script.experimental.host.BasicScriptingHost$eval$1.invoke(BasicScriptingHost.kt)
    at kotlin.script.experimental.host.BasicScriptingHost$runInCoroutineContext$1.invokeSuspend(BasicScriptingHost.kt:35)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:238)
    at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.kt:116)
    at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:80)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:54)
    at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
    at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:36)
    at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
    at kotlin.script.experimental.host.BasicScriptingHost.runInCoroutineContext(BasicScriptingHost.kt:35)
    at kotlin.script.experimental.host.BasicScriptingHost.eval(BasicScriptingHost.kt:45)

0 ответов

Это не исправление, это просто временное решение.

Вы можете передать исходный код в Kotlin Compiler разными способами:

  1. Из FileScriptSource - при передаче списка файлов в конфигурации
  2. Из списка содержимого исходного кода в памяти - например, каждый файл должен быть прочитан, а содержимое должно быть помещено внутрь StringScriptSource
  3. Из единого сценария памяти, который создается просто с объединением всех исходных файлов ввода.

Как я обнаружил в своих экспериментах:

  • Если у вас есть jar-файлы mockk+kotest в том же пути к классам, вариант 1 не работает. В этом случае я бы хотел предположить, что вы внесете одно изменение:
// this doesn't work - scriptFile.toScriptSource()
scriptFile.readText().toScriptSource() // ok - we read source from memory, not from file
  • Если у вас огромный сервис с большим количеством jar-файлов Spring, все вышеперечисленные варианты работают. Это означает, что вы не смогли протестировать свою компиляцию в модульных тестах, но ваш сервис будет работать!
  • Если вы хотите выполнить компиляцию из подключаемого модуля Gradle, вы можете уловить другой вид проблемы - конфликт классов с библиотекой сопрограмм, поэтому все вышеперечисленные параметры не работают.

Наконец, я изменил в своем коде следующее:

  1. На входе у меня всегда много файлов kt / kts.
  2. У меня есть три варианта компиляции (описанных выше). Итак, мой код выполняется createJvmCompilationConfigurationFromTemplate с другой логикой, в зависимости от моего режима компиляции (это просто перечисление).
  3. Для модульных тестов я должен использовать только вариант 3.
  4. Для обслуживания я использую первый вариант, так как он самый быстрый
  5. Для пути к классам плагина gradle я запускаю отдельный экземпляр java (со свежим путем к классам), который выполняет ввод kts файлы.
Другие вопросы по тегам