Using Java types from kotlin js (for use with rhino engine)


#1

At work we do customizing of enterprise systems (that we do not control) that use javascript and rhino/nashorn engine as the primary scripting platform.

Using the rhino engine it is possible to access all java classes by their full qualified name from javascript code. I want to write my code in kotlin, compile it to js and run it in rhino.

As one may can imagine most of the apis we use in the javascript code are java classes provided by the enterprise system. We have the jars that contain the java types. It would be really nice if I could import the java classes into the kotlin code and have all calls to the java type automatically converted to “external” style calls so I do not have to create kotlin definitions for the existing java type.

The primary goal of this is to have autocompletion and buildtime type checking for the javatype calls.

This is what I tried, however this:

import the.enterprise.api.types.EnterpriseApi // compiler error
import the.enterprise.api.types.EnterpriseContext // compiler error

// serverApi will be defined as a global object
// by the enterprise systems rhino context
external val serverApi: EnterpriseApi

fun functionCalledByTheEnterpriseSystem(context: EnterpriseContext) {
    serverApi.callApiFunction()
}

Does not compile:

.\App.kt: (3, 8): Unresolved reference: the
.\App.kt: (4, 8): Unresolved reference: the
.\App.kt: (6, 25): Unresolved reference: EnterpriseApi
.\App.kt: (8, 50): Unresolved reference: EnterpriseContext

Is it possible to do this with todays kotlin2js compiler?


#2

How could Kotlin to JS compiler know about Java classes? I guess, the only way is to declare classes you use (like the.enterprise.api.types.EnterpriseApi) as external classes. I’m not sure it will work, but you can try. Probably, you’ll need to use JsQualifier annotation on packages, since external classes are treated as top-level JavaScript declarations by default.

I guess it’s possible to parse either Java source files or Java bytecode and generate corresponding external Kotlin classes. However, there’s no such standart tool yet, nor it’s even planned.


#3

If you want to do it easily, you could go with either a doclet or (more modern) an annotation processor. You’d have to generate the Kotlin externals though. Kotlin can then treat it as “provided” javascript like it does with any other javascript.