2017-12-24 5 views
5

Ich habe ein Gradle-Projekt mit dem Kotlin Gradle-Plugin. Ich möchte ein Java 9 Modul bauen, so dass meine Verzeichnisstruktur wie folgt aussieht:Haben Kotlin 1.2.10 und Java 9 entgegengesetzte Regeln bezüglich automatischer Module?

src/main/java/ 
    - module-info.java 
src/main/kotlin/ 
    - Foo.kt 
    - Bar.kt 
build.gradle 
... 

Meine build.gradle die folgenden Abhängigkeiten erklärt:

dependencies { 
    compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.10" 
    compile "org.jetbrains.kotlin:kotlin-reflect:1.2.10" 
    compile "org.junit.jupiter:junit-jupiter-api:5.0.2" 
} 

und ich alle diese Abhängigkeiten in meiner Kotlin Quelle (Foo.kt, Bar.kt, ...).

Alles funktioniert prima an, wenn ich meine module-info.java wie so schreiben:

module my.module { 
    requires kotlin.stdlib; 
    exports my.module.pkg; 
} 

und wenn ich liefern alle meine Kompilierung-Abhängigkeiten zu javac während der compileJava Aufgabe this technique verwenden.

jedoch, wenn ich auf -Xlint:all drehen für den Java-Compiler während der compileJava Aufgabe (zu kompilieren module-info.java), erhalte ich die folgenden Warnungen:

/path/to/my.module/src/main/java/module-info.java:26: warning: requires directive for an automatic module 
    requires kotlin.stdlib; 
       ^

So hier sind wir der Java-Compiler haben, javac beschweren, dass kotlin.stdlib ist ein automatisches Modul, daher sollte ich keine requires Klausel dafür haben.

Aber wenn ich die requires Klausel löschen javac glücklich zu machen, macht es kotlinc noch wütender als javac war (ich erhalte eine Fehlermeldung nicht eine Warnung):

e: /path/to/my.module/src/main/java/module-info.java: The Kotlin standard library is not found in the module graph. Please ensure you have the 'requires kotlin.stdlib' clause in your module definition 

FAILURE: Build failed with an exception. 

* What went wrong: 
Execution failed for task ':my.module:compileKotlin'. 

Jetzt kann ich das in Ordnung bringen, auch durch so bearbeite meine compileKotlin Aufgabe:

compileKotlin { 
    doFirst { 
     kotlinOptions.freeCompilerArgs = ['-Xallow-kotlin-package'] 
    } 
} 

aber dies nur führt zu Fehlern bei der compileKotlin Aufgabe, die alle aussehen wie diese:

e: /path/to/my.module/src/main/kotlin/Foo.kt: (27, 30): Symbol is declared in module 'org.junit.jupiter.api' which current module does not depend on 

Und dann, wenn ich versuche, compileKotlin zu zwingen, einen Modul Weg zu nehmen, anstatt eine Classpath von "-Xmodule-path=${classpath.asPath}"-freeCompilerArgs Hinzufügen und classpath leer seine Einstellung können der Kotlin Compiler nichts finden, überhaupt, und ich am Ende mit zig Millionen ungelöster Referenzfehler!

Warum sagt mir der Kotlin-Compiler, dass ich requires kotlin.stdlib; haben muss, wenn der Java-Compiler das Gegenteil sagt? Wie kann ich Kotlin und Java zusammenbringen, um ein Java 9-Modul zu erstellen?

+0

haben Sie versucht, eine 'requires'-Anweisung für' org.junit.jupiter.api' hinzuzufügen? vielleicht ist das, was den letzten Fehler aus dem Kotlin-Compiler – msrd0

+0

@ msrd0 verursacht, ich habe es gerade versucht (hatte es nicht zuvor in Isolation getan). Das Hinzufügen von 'org.junit.jupiter.api' in' modul-info.java' als 'requires' * beseitigt * die nicht aufgelösten Symbolreferenzfehler. JEDOCH erzeugt es wiederum eine '-Xlint: all'-Warnung von' javac', die auf automatischen Modulen nicht 'requires' will. Es scheint also, als ob Kotlin und Java hier unterschiedliche Regeln durchsetzen. – 0xbe5077ed

+0

hast du es zusammen mit dem Flag '-Xallow-kotlin-package' versucht? – msrd0

Antwort

0

Wenn Sie Java 9-Modul in Kotlin erstellen, müssen Sie requires kotlin.stdlib in Ihrem module-info.java deklarieren, um Laufzeitabhängigkeiten des kompilierten Kotlin-Codes zusätzlich zu den expliziten Abhängigkeiten von der Standardbibliothek-API zu erfüllen.

javac warnt Sie davor, ein automatisches Modul zu benötigen, wenn Flusen aktiviert sind, da automatische Module ein Potential von drawbacks im Vergleich zu normalen Modulen haben. Bis die Standardbibliothek als normales Modul kompiliert ist, müssen Sie sich mit dieser Warnung befassen.

-Xallow-kotlin-package Mit dem Compiler-Flag können Sie require kotlin.stdlib weglassen, da es nur verwendet werden soll, wenn die Standardbibliothek selbst kompiliert wird. Wenn Sie dieses Flag angeben und diese Anforderung auslassen, können Sie natürlich keine API aus der Standardbibliothek verwenden. Daher ist dies für Sie keine wirkliche Option.