Kotlin JSR-223 ScriptEngineFactory in fat jar - Can't find the kotlin compiler compiler

I have a fat jar where I am trying to get a Kotlin instance ScriptEngine

.

For debugging purposes, I iterate through the available Script Engine Factories and get the engines.

val scriptEngineManager = ScriptEngineManager()
for (factory in scriptEngineManager.engineFactories) {
    val scriptEngine = factory.scriptEngine
}

      

When it hits the Kotlin engine, it crashes with the following exception:

Exception in thread "main" java.io.FileNotFoundException: Cannot find kotlin compiler jar, set kotlin.compiler.jar property to proper location
        at org.jetbrains.kotlin.script.jsr223.KotlinJsr223ScriptEngineFactoryExamplesKt$kotlinCompilerJar$2.invoke(KotlinJsr223ScriptEngineFactoryExamples.kt:100)
        at org.jetbrains.kotlin.script.jsr223.KotlinJsr223ScriptEngineFactoryExamplesKt$kotlinCompilerJar$2.invoke(KotlinJsr223ScriptEngineFactoryExamples.kt)
        at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:130)
        at org.jetbrains.kotlin.script.jsr223.KotlinJsr223ScriptEngineFactoryExamplesKt.getKotlinCompilerJar(KotlinJsr223ScriptEngineFactoryExamples.kt)
        at org.jetbrains.kotlin.script.jsr223.KotlinJsr223ScriptEngineFactoryExamplesKt.access$getKotlinCompilerJar$p(KotlinJsr223ScriptEngineFactoryExamples.kt:1)
        at org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmDaemonLocalEvalScriptEngineFactory.getScriptEngine(KotlinJsr223ScriptEngineFactoryExamples.kt:56)
        at davidsiro.invoices.InvoiceGeneratorKt.generateInvoice(invoiceGenerator.kt:16)
        at davidsiro.invoices.MainKt.main(main.kt:11)

      

My fat jar contains all the dependencies (albeit unpacked), including the Kotlin compiler. I am using Maven Assembly Plugin to build it, which is configured like this:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.6</version>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>${main.class}</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
            </configuration>
        </execution>
    </executions>
</plugin>

      

Any ideas?

Update

For the record, I tried with both KotlinJsr223JvmLocalScriptEngineFactory and KotlinJsr223JvmDaemonLocalEvalScriptEngineFactory with the same result.

+3


source to share


1 answer


The JSR223 factories in kotlin-script-util try to find a compiler to set up compilation. In your case, you need to write your own factory to explicitly specify the classpath of the compilation script, eg.

class MyScriptEngineFactory : KotlinJsr223JvmScriptEngineFactoryBase() {   
    override fun getScriptEngine(): ScriptEngine =
        KotlinJsr223JvmLocalScriptEngine(
            Disposer.newDisposable(),
            this,
            classpath, // !!! supply the script classpath here
            KotlinStandardJsr223ScriptTemplate::class.qualifiedName!!,
            { ctx, types -> ScriptArgsWithTypes(arrayOf(ctx.getBindings(ScriptContext.ENGINE_SCOPE)), types ?: emptyArray()) },
            arrayOf(Bindings::class)
        )
}

      

You need to put the following cans in classpath

:



  • kotlin-script-util.jar

    - it contains a template class used as a superclass for the script
  • kotlin-script-runtime.jar

    - for base classes used in scripts
  • any other jars you need to use in your scenarios is likely - kotlin-stdlib.jar

You can put your fat jar instead, but that will mean whatever is available from it will be available from your scripts. Not to mention the compiler overhead.

+7


source







All Articles