Kotlin Support for Java 9 Module System?


#1

I wonder if Kotlin will support/integrate with the new module system? Is this on your roadmap?
Will the Compiler be aware of a module? Can I create a module in Kotlin?


Kotlin with java9 module
#2

Yes, supporting the Java 9 module system is one of the main priorities for Kotlin 1.2. The compiler will be fully aware of the new visibility rules. You’ll be able to create a module in Kotlin; the module-info file will have to remain in Java (because it’s effectively a separate DSL, and we don’t see much value in reinventing it), but the rest of implementation can be Kotlin.


#3

Kotlin 1.2 is out, so is this now possible? When I change the JDK version in my gradle file to 9, I get this:

e: Unknown JVM target version: 9.0
Supported versions: 1.6, 1.8


#4

Please make sure you’re using a recent Gradle version.


#5
./gradlew --version

------------------------------------------------------------
Gradle 4.4
------------------------------------------------------------

Build time:   2017-12-06 09:05:06 UTC
Revision:     cf7821a6f79f8e2a598df21780e3ff7ce8db2b82

Groovy:       2.4.12
Ant:          Apache Ant(TM) version 1.9.9 compiled on February 2 2017
JVM:          1.8.0_152 (Oracle Corporation 25.152-b16)
OS:           Linux 4.9.0-3-amd64 amd64

This is the m most recent of gradle I guess.


#6

The same problem.
From https://kotlinlang.org/docs/reference/using-gradle.html :

Target version of the generated JVM bytecode (1.6 or 1.8), default is 1.6
Possible values: “1.6”, “1.8”

So where is java 9?


#7

push


#8

Kotlin currently doesn’t support JVM 9 bytecode generation, however JVM 1.8 bytecode is fully compatible with Java 9.

If you want to build/consume modular jars, you need to author module-info.java file in your project. This isn’t different from a java-only project, you can refer to this Gradle guide for details on how to do that.


#9

I followed the mentioned guide but get stuck at the point that the build fails with errors like the following:

module-info.java:2: error: package is empty or does not exist: ch.tutteli.atrium.assertions

I am able to tweak the build with the solution mentioned in a SO question:

compileKotlin.destinationDir = compileJava.destinationDir

but it seems like a hack to me, is there kind of an official way of doing it?


#10

I currently use the following gradle code in my root build.gradle, where I can place the module-info.java under src/module

if (JavaVersion.current() >= JavaVersion.VERSION_1_9) {
    subprojects {
        def moduleInfo = file("${project.projectDir}/src/module/module-info.java")
        if (moduleInfo.exists()) {

            sourceSets {
                module {
                    java {
                        srcDirs = ['src/module']
                        compileClasspath = main.compileClasspath
                        sourceCompatibility = '9'
                        targetCompatibility = '9'
                    }
                }
                main {
                    kotlin { srcDirs += ['src/module'] }
                }
            }

            compileModuleJava.configure {
                dependsOn compileKotlin
                destinationDir = compileKotlin.destinationDir
                doFirst {
                    options.compilerArgs = ['--module-path', classpath.asPath,]
                    classpath = files()
                }
            }
            jar.dependsOn compileModuleJava
        }
    }
}

Edit: I added src/module to the source of main.kotlin in order that the kotlin compiler analyses the module-info.java and complains if necessary.

@ilya.gorbunov when is kotlin turning its jars into modules? I currently get the following warning because I do not want to specify kotlin.stlib for every module:

warning: requires transitive directive for an automatic module
    requires transitive kotlin.stdlib;