kotlin - 每当我尝试运行任何脚本时,Kotlin 脚本支持都会因“参数数量错误”而失败
问题描述
我正在尝试使用 运行一个非常基本的脚本org.jetbrains.kotlin:kotlin-scripting-jvm
,但是当我不应该得到两个错误时,我得到了两个错误。这是我的脚本:
1
我希望得到 aResultWithDiagnostics.Success
和 a resultValue
,1
但我得到 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)
解决方案
这不是解决方法,只是解决方法。
您可以通过不同的方式将源代码传递给 Kotlin 编译器:
- 从
FileScriptSource
- 当您传递配置中的文件列表时 - 从内存中的源代码内容列表 - 例如每个文件都应该被读取并且内容应该被放置在里面
StringScriptSource
- 来自单个内存脚本,该脚本仅使用所有输入源文件连接创建。
正如我在实验中发现的:
- 如果您在同一类路径中有 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 的类冲突,因此上述所有选项都不起作用。
最后,我在代码中更改了以下内容:
- 在输入时,我总是有很多 kt/kts 文件。
- 我有三个编译选项(如上所述)。因此
createJvmCompilationConfigurationFromTemplate
,根据我的编译模式(它只是枚举),我的代码以不同的逻辑执行。 - 对于单元测试,我只能使用选项 3。
- 对于服务,我使用第一个选项,因为它是最快的
- 对于 gradle 插件类路径,我启动了执行输入
kts
文件的单独的 java 实例(使用新的类路径)。
推荐阅读
- node.js - 我的功能是在收到 params.finalemail 后不发送电子邮件
- javascript - React 中的键盘快捷键,react-hotkeys 库
- python - 如何在 python/matplotlib 中设置默认刻度参数?
- html - 居中滑块控制字形
- angular - 如何从单元测试中正确调用函数
- sql - 为什么 2017-01-01 的日期部分周返回 52?
- php - 我想使用填充将数据保存在数据库中,但出现错误
- amazon-web-services - AWS CLI 不接受访问密钥
- python - 如何将 selenium 编码更改为 utf-8
- php - Laravel SoftDeletes conflicts with Eloquent ORM