问题描述
在Maven项目中,我有使用Kotlin ScriptEngine
(仅调用scriptEngine.eval(script)
)的测试。当我从IntelliJ运行测试时,它们全部通过,但是在运行mvn test
时,出现以下错误:
javax.script.ScriptException: Cannot access script base class 'kotlin.script.experimental.jsr223.Kotlinjsr223DefaultScript'. Check your module classpath for missing or conflicting dependencies
Cannot access script provided property class 'kotlin.script.experimental.jvmhost.jsr223.Kotlinjsr223ScriptEngineImpl'. Check your module classpath for missing or conflicting dependencies
Cannot access script provided property class 'org.jetbrains.kotlin.cli.common.repl.AggregatedReplStageState'. Check your module classpath for missing or conflicting dependencies
我通过适当的Maven依赖关系在类路径中有这三个类。 (我确实在失败的测试中向System.out.println(Kotlinjsr223DefaultScript.class.getName())
添加了一个调用,以确保是这种情况。)这是依赖关系树的相关片段:
[INFO] | \- org.jetbrains.kotlin:kotlin-scripting-jsr223:jar:1.3.72:compile
[INFO] | +- org.jetbrains.kotlin:kotlin-script-runtime:jar:1.3.72:compile
[INFO] | +- org.jetbrains.kotlin:kotlin-scripting-common:jar:1.3.72:compile
[INFO] | | \- org.jetbrains.kotlinx:kotlinx-coroutines-core:jar:1.2.1:compile
[INFO] | +- org.jetbrains.kotlin:kotlin-scripting-jvm:jar:1.3.72:compile
[INFO] | +- org.jetbrains.kotlin:kotlin-scripting-jvm-host:jar:1.3.72:compile
[INFO] | | \- org.jetbrains.intellij.deps:trove4j:jar:1.0.20181211:runtime
[INFO] | +- org.jetbrains.kotlin:kotlin-scripting-compiler:jar:1.3.72:compile
[INFO] | | +- org.jetbrains.kotlin:kotlin-scripting-js:jar:1.3.72:compile
[INFO] | | +- org.jetbrains.kotlin:kotlin-util-klib:jar:1.3.72:compile
[INFO] | | | \- org.jetbrains.kotlin:kotlin-util-io:jar:1.3.72:compile
[INFO] | | \- org.jetbrains.kotlin:kotlin-scripting-compiler-impl:jar:1.3.72:compile
[INFO] | +- org.jetbrains.kotlin:kotlin-compiler:jar:1.3.72:runtime
[INFO] | \- org.jetbrains.kotlin:kotlin-reflect:jar:1.3.72:runtime
我看到Internet上的人们遇到了类似的问题,但是他们的解决方案是确保类在我已经拥有的类路径上可用。
解决方法
我能够让单元测试在命令行上工作。问题是surefire插件将使用包含类路径的仅清单jar。出于某种原因,jars 在那个仅清单 jar 中列出的顺序导致了 OP 上面描述的问题。我可以通过在 surefire.useManifestOnlyJar=false
pom.xml
来解决此问题
<properties>
<surefire.useManifestOnlyJar>false</surefire.useManifestOnlyJar>
</properties>
或作为 Maven 的命令行参数:
mvn -Dsurefire.useManifestOnlyJar=false test
有关该属性的更多详细信息,请参阅
mvn surefire:help -Ddetail=true
这为我解决了问题。
还有关于使用 surefire 加载类的文档:https://maven.apache.org/surefire/maven-surefire-plugin/examples/class-loading.html