Kotlin Script API throwing exceptions

I’m trying to get the Class<*> instance created by the KotlinToJVMBytecodeCompiler’s compileScript method:

private fun compileScript(
		scriptPath: String,
		scriptDefinition: KotlinScriptDefinition,
		runIsolated: Boolean = true,
		saveClassesDir: File? = null
): Class<*>? {
	val messageCollector = PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false)
	val rootDisposable = Disposer.newDisposable()
	try {
		val configuration = newConfiguration()
		configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
		configuration.addKotlinSourceRoot("testRes/script/$scriptPath")
		configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinition)
		configuration.put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true)
		if (saveClassesDir != null) configuration.put(JVMConfigurationKeys.OUTPUT_DIRECTORY, saveClassesDir)
		val environment = KotlinCoreEnvironment.createForTests(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
		return KotlinToJVMBytecodeCompiler.compileScript(environment, javaClass.classLoader.takeUnless { runIsolated })
	} finally {
		Disposer.dispose(rootDisposable)
	}
}

I invoked the function above with compileScript("example.kts", KotlinScriptDefinition(ScriptTemplate::class)), while example.kts is just a line of System.out.println and ScriptTemplate looks like

@ScriptTemplateDefinition
open class AbstractScriptTemplate(val args: Array<String>)

@ScriptTemplateDefinition
open class ScriptTemplate(args: Array<String>) : AbstractScriptTemplate(args)

But when I run my program I get this error:

exception: java.lang.RuntimeException: Primary constructor not found for script template class ScriptTemplate (not found)
	at org.jetbrains.kotlin.codegen.ScriptCodegen.genConstructor(ScriptCodegen.java:161)
	at org.jetbrains.kotlin.codegen.ScriptCodegen.generateBody(ScriptCodegen.java:103)
	at org.jetbrains.kotlin.codegen.MemberCodegen.generate(MemberCodegen.java:142)
	at org.jetbrains.kotlin.codegen.PackageCodegenImpl.generateFile(PackageCodegenImpl.java:115)
	at org.jetbrains.kotlin.codegen.PackageCodegenImpl.generate(PackageCodegenImpl.java:66)
	at org.jetbrains.kotlin.codegen.DefaultCodegenFactory.generatePackage(CodegenFactory.kt:97)
	at org.jetbrains.kotlin.codegen.DefaultCodegenFactory.generateModule(CodegenFactory.kt:68)
	at org.jetbrains.kotlin.codegen.KotlinCodegenFacade.doGenerateFiles(KotlinCodegenFacade.java:47)
	at org.jetbrains.kotlin.codegen.KotlinCodegenFacade.compileCorrectFiles(KotlinCodegenFacade.java:39)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.generate(KotlinToJVMBytecodeCompiler.kt:454)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyzeAndGenerate(KotlinToJVMBytecodeCompiler.kt:356)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileScript(KotlinToJVMBytecodeCompiler.kt:328)

Am I missing something?

I guess the reason is that the jar where your script template is defined is not in the compilation classpath. You can use configuration.addJvmClasspathRoots to add it.
But please note that you’re using internal apis now, so we’re not committed to keeping it stable and convenient for external usage.
The new public scripting api is in work and will be available in an experimental mode starting from 1.2.50.

1 Like

You can use configuration.addJvmClasspathRoots to add it.

Thanks, but I’m using the Jsr223 library now, it works like a charm.

But please note that you’re using internal apis now, so we’re not committed to keeping it stable and convenient for external usage.

I have clear understanding of what I’m doing, but thanks for reminding.