Fat jar 中的 Kotlin JSR-223 ScriptEngineFactory - 找不到 kotlin 编译器 jar
Kotlin JSR-223 ScriptEngineFactory within the fat jar - Cannot find kotlin compiler jar
我有一个 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.invoke(KotlinJsr223ScriptEngineFactoryExamples.kt:100)
at org.jetbrains.kotlin.script.jsr223.KotlinJsr223ScriptEngineFactoryExamplesKt$kotlinCompilerJar.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)
我的 fat 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 路径,例如
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
- 它包含用作脚本 的超级class 的模板class
kotlin-script-runtime.jar
- 用于脚本中使用的基础 classes
- 您很可能需要在脚本中使用的任何其他 jar -
kotlin-stdlib.jar
你可以把你的 fat jar 放在那里,但这意味着它的所有内容都可以从你的脚本中访问。不谈论编译器的开销。
我有一个 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.invoke(KotlinJsr223ScriptEngineFactoryExamples.kt:100)
at org.jetbrains.kotlin.script.jsr223.KotlinJsr223ScriptEngineFactoryExamplesKt$kotlinCompilerJar.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)
我的 fat 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 路径,例如
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
- 它包含用作脚本 的超级class 的模板class
kotlin-script-runtime.jar
- 用于脚本中使用的基础 classes- 您很可能需要在脚本中使用的任何其他 jar -
kotlin-stdlib.jar
你可以把你的 fat jar 放在那里,但这意味着它的所有内容都可以从你的脚本中访问。不谈论编译器的开销。