Je suis assez nouveau sur Gradle (et Java 9, pour être honnête), et j'essaie d'utiliser Gradle pour construire un projet de bibliothèque simple qui est un mélange de Java 9 et Kotlin. Plus en détail, il y a une interface dans Java et une implémentation dans Kotlin; je ferais tout dans Kotlin, mais le modules-info.Java
est Java de toute façon, j'ai donc décidé de faire les choses de cette façon.
Je m'appuie sur IntelliJ Idea, avec le plugin kotlin 1.2.0 et gradle 4.3.1 définis en externe.
Le schéma du système de fichiers est:
+ src
+ main
+ Java
+ some.package
- Roundabout.Java [an interface]
- module-info.Java
+ kotlin
+ some.package.impl
- RoundaboutImpl.kt [implementing the interface]
module-info.Java
est:
module some.package {
requires kotlin.stdlib;
exports some.package;
}
et build.gradle
est:
buildscript {
ext.kotlin_version = '1.2.0'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
group 'some.package'
version '1.0-PRE_ALPHA'
apply plugin: 'Java-library'
apply plugin: 'kotlin'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
sourceCompatibility = 9
compileJava {
dependsOn(':compileKotlin')
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
]
classpath = files()
}
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib', version: "$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
Notez que je devais spécifier un chemin de module sur la tâche de compilation Java, ou la compilation échoue avec:
erreur: module introuvable: kotlin.stdlib nécessite kotlin.stdlib;
Quoi qu'il en soit, maintenant cette construction échoue avec cette erreur, et je ne peux pas comprendre comment le résoudre:
erreur: le package some.package.impl n'existe pas
importez some.package.impl.RoundaboutImpl;
erreur: impossible de trouver le symbole
return new RoundaboutImpl <> (queueSize, parallelism, worker, threadPool);
Je pense que la partie Kotlin de la compilation se passe bien, alors la partie Java échoue car elle ne "voit" pas le côté kotlin, pour ainsi dire.
Je pense que je devrais lui dire en quelque sorte de charger les classes kotlin déjà compilées dans le chemin de classe; mais (d'abord) comment faire ça en gradle? et (deuxième) est-ce même possible? Je pense que vous ne pouvez pas mélanger le chemin du module et le chemin de la classe dans Java 9.
Comment puis-je resoudre ceci? Je pense que c'est une situation assez courante, car chaque module de style Java9 sera un module mixte (à cause de module-info.Java
), donc je pense qu'il me manque quelque chose de vraiment basique ici.
Merci d'avance!
Résolu! Il suffisait de définir le répertoire de compilation kotlin sur le même répertoire que Java:
compileKotlin.destinationDir = compileJava.destinationDir
Cela fonctionne maintenant, à la fois avec les sources dans le même arbre ou dans des arbres différents; mais avec une bizarrerie: la tâche jar
produit un bocal avec toutes les entrées dupliquées. Je vais travailler sur le problème, ensuite.
Merci à tout le monde!
J'utilise le script gradle suivant où je mets le module-info.Java sous src/module. Il est automatiquement inclus dans le pot (sans doublons):
if (JavaVersion.current() >= JavaVersion.VERSION_1_9) {
subprojects {
def srcModule = "src/module"
def moduleInfo = file("${project.projectDir}/$srcModule/module-info.Java")
if (moduleInfo.exists()) {
sourceSets {
module {
Java {
srcDirs = [srcModule]
compileClasspath = main.compileClasspath
sourceCompatibility = '9'
targetCompatibility = '9'
}
}
main {
kotlin { srcDirs += [srcModule] }
}
}
compileModuleJava.configure {
dependsOn compileKotlin
destinationDir = compileKotlin.destinationDir
doFirst {
options.compilerArgs = ['--module-path', classpath.asPath,]
classpath = files()
}
}
jar.dependsOn compileModuleJava
}
}
}
Je ne le mettrai plus à jour, jetez un œil à https://github.com/robstoll/atrium/blob/master/build.gradle pour voir la version actuelle en cours d'utilisation.
La réponse acceptée n'a pas fonctionné pour moi (du moins pas la façon dont elle a été présentée), mais c'est ce qui a fonctionné:
plugins {
id "org.jetbrains.kotlin.jvm" version "1.3.50"
}
compileKotlin {
doFirst {
destinationDir = compileJava.destinationDir
}
}
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
Le faire comme le suggère la réponse acceptée m'a conduit à obtenir cette erreur:
Le répertoire '/ path/to/project/build/classes/kotlin/main' spécifié pour la propriété 'compileKotlinOutputClasses' n'existe pas.
version Gradle: 5.6