maven - 胖 jar 中的 Kotlin JSR-223 ScriptEngineFactory - 找不到 kotlin 编译器 jar

标签 maven kotlin executable-jar jsr223

我有一个 fat jar 子,我试图在其中获取 Kotlin 的实例 ScriptEngine .

出于调试目的,我遍历可用的脚本引擎工厂并获取引擎。

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

当它遇到 Kotlin 的引擎时,它会失败并出现以下异常:
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)

我的胖 jar 包含所有依赖项(尽管已解包),包括 Kotlin 编译器。我正在使用 Maven Assembly Plugin 来构建它,它的配置如下:
<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>

有任何想法吗?

更新

作为记录,我尝试使用 KotlinJsr223JvmLocalScriptEngineFactory 和 KotlinJsr223JvmDaemonLocalEvalScriptEngineFactory 获得相同的结果。

最佳答案

kotlin-script-util 中的 JSR223 工厂试图找到编译器 jar 以设置编译。在您的情况下,您需要编写自己的工厂来明确提供脚本编译类路径,例如

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)
        )
}

您需要将以下jar放入classpath :
  • kotlin-script-util.jar - 它包含用作脚本父类(super class)的模板类
  • kotlin-script-runtime.jar - 用于脚本中使用的基类
  • 您需要在脚本中使用的任何其他 jar,很可能 - kotlin-stdlib.jar

  • 你可以把你的 fat jar 子放在那里,但这意味着它的所有东西都可以从你的脚本中访问。不是在谈论编译器的开销。

    关于maven - 胖 jar 中的 Kotlin JSR-223 ScriptEngineFactory - 找不到 kotlin 编译器 jar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44781462/

    相关文章:

    android - 如何在kotlin android中使用viewmodel和数据绑定(bind)基于所有editetext启用/禁用按钮不为空

    kotlin - 比较字符串 Kotlin

    java - 如何在kotlin中获取当前类文件名

    java - launch4j 编译的 java 应用程序可执行文件被防病毒软件阻止

    java - 如果我使用 applet,如何使用 Eclipse 创建 .jar 文件?

    java - Log4j在maven项目中登录

    java - maven jar插件无法解析

    java - 如何将外部jar文件传递到spring boot项目?

    java - 添加 tomcat-catalina 依赖项时 Tomcat 服务器没有响应

    java - swagger-maven-plugin 不会为单个请求映射生成 "paths"元素