Поддержка сценариев 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 разными способами:
- Из
FileScriptSource
- при передаче списка файлов в конфигурации - Из списка содержимого исходного кода в памяти - например, каждый файл должен быть прочитан, а содержимое должно быть помещено внутрь
StringScriptSource
- Из единого сценария памяти, который создается просто с объединением всех исходных файлов ввода.
Как я обнаружил в своих экспериментах:
- Если у вас есть 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, вы можете уловить другой вид проблемы - конфликт классов с библиотекой сопрограмм, поэтому все вышеперечисленные параметры не работают.
Наконец, я изменил в своем коде следующее:
- На входе у меня всегда много файлов kt / kts.
- У меня есть три варианта компиляции (описанных выше). Итак, мой код выполняется
createJvmCompilationConfigurationFromTemplate
с другой логикой, в зависимости от моего режима компиляции (это просто перечисление). - Для модульных тестов я должен использовать только вариант 3.
- Для обслуживания я использую первый вариант, так как он самый быстрый
- Для пути к классам плагина gradle я запускаю отдельный экземпляр java (со свежим путем к классам), который выполняет ввод
kts
файлы.