首页 > 解决方案 > 每当我尝试运行任何脚本时,Kotlin 脚本支持都会因“参数数量错误”而失败

问题描述

我正在尝试使用 运行一个非常基本的脚本org.jetbrains.kotlin:kotlin-scripting-jvm,但是当我不应该得到两个错误时,我得到了两个错误。这是我的脚本:

1

我希望得到 aResultWithDiagnostics.Success和 a resultValue1但我得到 a 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
        } 

参数为空。我究竟做错了什么?这就是我尝试运行脚本的方式:

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)

标签: kotlinscriptingkotlin-script

解决方案


这不是解决方法,只是解决方法。

您可以通过不同的方式将源代码传递给 Kotlin 编译器:

  1. FileScriptSource- 当您传递配置中的文件列表时
  2. 从内存中的源代码内容列表 - 例如每个文件都应该被读取并且内容应该被放置在里面StringScriptSource
  3. 来自单个内存脚本,该脚本仅使用所有输入源文件连接创建。

正如我在实验中发现的:

  • 如果您在同一类路径中有 mockk+kotest jar,则选项 1 不起作用。在这种情况下,我想假设您进行一项更改:
// this doesn't work - scriptFile.toScriptSource()
scriptFile.readText().toScriptSource() // ok - we read source from memory, not from file
  • 如果你有大量的 Spring jar 服务,那么上面的所有选项都可以工作。这意味着您无法在单元测试中测试您的编译,但是您的服务将起作用!
  • 如果您想从 Gradle Plugin 进行编译,您可以发现另一种问题 -与 coroutines library 的类冲突,因此上述所有选项都不起作用。

最后,我在代码中更改了以下内容:

  1. 在输入时,我总是有很多 kt/kts 文件。
  2. 我有三个编译选项(如上所述)。因此createJvmCompilationConfigurationFromTemplate,根据我的编译模式(它只是枚举),我的代码以不同的逻辑执行。
  3. 对于单元测试,我只能使用选项 3。
  4. 对于服务,我使用第一个选项,因为它是最快的
  5. 对于 gradle 插件类路径,我启动了执行输入kts文件的单独的 java 实例(使用新的类路径)。

推荐阅读