Search code examples
javamavenkotlinscriptengine

Getting `ScriptException` when using Kotlin `ScriptEngine` in tests run from Maven


In a Maven project I have tests that are using the Kotlin ScriptEngine (just calling scriptEngine.eval(script)). When I run the tests from IntelliJ they all pass, but during runs of mvn test, I am getting the following error:

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

I have these three classes in the classpath via appropriate Maven dependencies. (I actually added a call to System.out.println(KotlinJsr223DefaultScript.class.getName()) in the failing tests to make sure it's the case.) Here's the relevant fragment of the dependency tree:

[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

I saw people on the Internet run into similar issues, but their solution was to make sure the classes are available on the classpath, which I already have.


Solution

  • I was able to get the unit tests to work on the command line. The issue was the surefire plugin that would use a manifest-only jar that would contain the classpath. For some reason, the order in which the jars were listed in that manifest-only jar caused the issues that OP describes above. I was able to fix this issue by setting surefire.useManifestOnlyJar=false, either in pom.xml

    <properties>
        <surefire.useManifestOnlyJar>false</surefire.useManifestOnlyJar>
    </properties>
    

    or as command line argument for Maven:

    mvn -Dsurefire.useManifestOnlyJar=false test
    

    For more details on that property, see

    mvn surefire:help -Ddetail=true
    

    This resolves the problem for me.

    There is also documentation on class loading with surefire: https://maven.apache.org/surefire/maven-surefire-plugin/examples/class-loading.html