1

Groovy has a GroovyClassLoader with which a groovy class can be loaded into your java application with GroovyClassLoader.parseClass(String script) and then instantiated at a later time and it's method invoked.

Is there a way to do this with kotlin script files (.kts)?

I know I can use jsr223 to evaluate a script file with ScriptEngine.eval(String script) which uses KotlinJsr223JvmLocalScriptEngineFactory , however calling eval over a script which is simply a class declaration, returns null and I can't access that class.

I have added the correct dependencies and kotlin script engine factory is correctly loaded (I can see it in the result of new ScriptEngineManager().getEngineFactories()), I just get null as a result of eval. Assuming that's because the script itself doesn't really return anything, just define a class. This is what the script file I'm trying to load looks like:

package scripts

import com.example.SomeJavaInterface
import com.example.SomeArg
import com.example.SomeReturnValue

class TestScript : SomeJavaInterface {
    override fun someMethod(SomeArg arg): SomeReturnValue {
        return SomeReturnValue()
    }
}

I'm using kotlin-stdlib, kotlin-compiler and kotlin-script-util version 1.2.41.

Is this not achievable with kotlin scripts?

6
  • That’s what I provide in the following library: github.com/s1monw1/KtsRunner Commented May 31, 2018 at 16:17
  • @s1m0nw1 thanks for the comment. I've tried using your library but I've got an IllegalStateException: Could not load script from .kts. Now From what I can see the library an eval and then tries to cast the result and the thing breaks because eval returns null, just like it does to me in my original eval call. Commented Jun 1, 2018 at 6:15
  • Can you show me your script please? Commented Jun 1, 2018 at 8:37
  • @s1m0nw1 I've added it to the OP. Calling new KtsObjectLoader().load(Files.newBufferedReader(Paths.get("script.kts"))) or calling scriptEngine.eval(script) both return null. Script file is properly loaded (I can see it's contents when debugging). Commented Jun 4, 2018 at 6:14
  • Maybe you should add an instantiation as a last statement: TestScript() Commented Jun 4, 2018 at 6:40

1 Answer 1

3

You can return the class itself from the script. For example, the last line of your script could be TestScript::class. This gives you a KClass which you can then instantiate. To give you a real-world example, you can see how I instantiate the class I get from the script here.

Sign up to request clarification or add additional context in comments.

2 Comments

This link does not work
The link has been updated to a permalink.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.