2

Is is possible to call javascript functions from kotlin JVM based project? Like for example I got class:

class JS{

 fun callJS( ){
  // somehow call js function
 }
}
1
  • This may be possible if you use Nashorn, for example. Which function specifically do you want to call? Commented Mar 29, 2018 at 11:36

1 Answer 1

4

You can use a ScriptEngineManager with JavaScript as the engine.

You use ScriptEngineManager.getEngineByName to get the engine itself, but that doesn't allow calling methods from Java. In order to do this, you need an Invocable. This is done by first evaluating the script (either as a Reader or String) and then casting it as an Invocable.

I personally prefer using two extension functions for this. You don't need both, but there's one for Readers and one for Strings:

fun String.createInvocable(engine: ScriptEngine) : Invocable {
    engine.eval(this);
    return engine as Invocable;
}

fun Reader.createInvocable(engine: ScriptEngine) : Invocable{
    engine.eval(this)
    return engine as Invocable
}

The engine here is the JavaScript engine, and it uses it to eval the either String with the code or reader to the file with the code. It really depends on how you store it.

And then you use the Invocable to call the function.

Note that it returns null if there's nothing returned from the function, otherwise it gives a non-null object. That assumes null isn't being returned of course.

Anyways, for the actual engine. ScriptEngineManager is in the javax package, so you don't need to add any dependencies or libraries to use it. You need a ScriptEngineManager in order to get the engine itself:

val engineManager = ScriptEngineManager()

The ScriptEngineManager is just a manager of the engines. It can't be used directly for evaluating, since it isn't the engine. Since you want the JavaScript engine, you call getEngineByName, and pass javascript:

val engine = engineManager.getEngineByName("javascript")

And this is where the extension functions come in. Create a new Reader (or use the String with the source if you prefer) and call createInvocable:

val invocable = Files.newBufferedReader(Paths.get("dir")).createInvocable(engine)

And finally, call the function:

invocable.invokeFunction("name", "arguments")//there can be no arguments

If you have return values, add a var, or val to catch it.

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

2 Comments

Thanks for an answer. So there is not easy way to call javascript from kotlin like js("somemethod") ?
@YuriyHladyuk not at the moment, no. But with the extension functions, it's still relatively easy calling them

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.