Tiempo de lectura: 3 minutos

El ecosistema JVM ha estado y está gobernado casi en su totalidad por el lenguaje Java (y no lo digo yo, hay varios informes de diferentes fuentes, pero todos bastante alineados):

La diversidad es buena, muy buena, pero es todavía mejor cuando existe interoperabilidad entre los lenguajes y puedes usar en un mismo proyecto Spring, Micronaut, Play, etc. con un módulo en Java y otro en Kotlin, Groovy, Scala…

¿Por qué?

  • Características que hacen que un lenguaje encaje perfectamente bien para resolver un problema concreto o un ecosistema con ciertos requerimientos.
  • Aprender nuevas formas de resolver problemas y abrir nuestros horizontes.
  • Conocer nuevas herramientas/librerías/frameworks.

En mi caso, tras conocer las co-rutinas en Kotlin 1.3 enseguida encajé esta manera tan fantástica de manejar eventos asíncronos en uno de nuestros proyectos, simplificando enormemente la labor de implementar y probar los casos de uso. Si habéis trabajado en eventos asíncronos de cualquier tipo conoceréis perfectamente el temido callback hell.

Pero esta entrada no va de corutinas en Kotlin ni de programación asíncrona, sino de cómo podemos unir (por ejemplo) en un proyecto Java + Kotlin.

Vamos a usar IntelliJ, pero podéis usar cualquier otro IDE o, si el rollo canalla os invade, hacerlo desde consola. Como sistema de construcción usaremos Gradle.

Echándole un vistazo al fichero de configuración de Gradle tenemos este artefacto:

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"

Es la librería de Kotlin para jdk8, no necesitamos más. En mi caso también añadí la librería de corutinas para el ejemplo que nos atañe:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.2.1'

Vamos a la chicha, con un ejemplo muy básico pero suficiente para probar.

Tenemos 2 directorios bajo src/main, el propio de Java y el de Kotlin, con un par de clases que nos hemos creado de prueba en Java y Kotlin respectivamente:

El contenido de la clase Kotlin:

class Runner(
    private var timeMillis  : Long
) {

    fun run() {
        GlobalScope.launch { // launch new coroutine in background and continue
            delay(timeMillis)
            println("ke ase!")
        }
        println("Ola,") // main thread continues here immediately
        runBlocking {     // but this expression blocks the main thread
            delay(timeMillis)  // ... while we delay for 5 seconds to keep JVM alive
        }
    }
}

Y lo invocamos desde nuestra clase Java creando la instancia de la clase Kotlin y ejecutándola:

public class App {

    public static void main(String[] args) {
        Runner runnerInstance = new Runner(5000L);
        runnerInstance.run();
    }
}

Y la salida:

> Task :compileKotlin
> Task :compileJava
> Task :classes

> Task :App.main()
Ola,
ke ase!

Es un ejemplo sencillo pero nos podemos hacer a la idea de lo potente que es usar características (en este caso las co-rutinas de kotlin) de un lenguaje concreto de la JVM, inyectándolo en un proyecto ya existente como un módulo o en uno nuevo.

Kotlin tiene muchas anotaciones para configurar la construcción configurando el compilador para adaptarlo a nuestras necesidades en la JVM, podéis echarle un ojo a la documentación por si os interesa:

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.jvm

También tenéis documentación sobre la interoperabilidad entre Java y Kotlin en la doc oficial de Kotlin:

https://kotlinlang.org/docs/reference/java-interop.html

https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html

Poco más, cualquier duda no dudéis en escribirnos o contarnos vuestras inquietudes ⌨️

 

Ricardo Flores

Software arquebusier doing cool things in @GloinSL. Linux lover ∞ retro garbage necromancer