建造Kotlin+;带有Gradle的Java9项目

建造Kotlin+;带有Gradle的Java9项目,java,gradle,kotlin,java-9,Java,Gradle,Kotlin,Java 9,我对Gradle(老实说,还有Java9)相当陌生,我正在尝试使用Gradle构建一个简单的库项目,它是Java9和Kotlin的混合体。更详细地说,Java中有一个接口,Kotlin中有一个实现;我会用Kotlin做所有的事情,但不管怎样,modules info.java都是java,所以我决定这样做 我是在IntelliJ Idea的基础上构建的,1.2.0 kotlin插件和外部定义的gradle 4.3.1 文件系统架构是: + src + main + java

我对Gradle(老实说,还有Java9)相当陌生,我正在尝试使用Gradle构建一个简单的库项目,它是Java9和Kotlin的混合体。更详细地说,Java中有一个接口,Kotlin中有一个实现;我会用Kotlin做所有的事情,但不管怎样,
modules info.java
都是java,所以我决定这样做

我是在IntelliJ Idea的基础上构建的,1.2.0 kotlin插件和外部定义的gradle 4.3.1

文件系统架构是:

+ src
  + main
    + java
      + some.package
        - Roundabout.java [an interface]
      - module-info.java
    + kotlin
      + some.package.impl
        - RoundaboutImpl.kt [implementing the interface]
module info.java
是:

module some.package {
  requires kotlin.stdlib;
  exports some.package;
}
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"
}
build.gradle
是:

module some.package {
  requires kotlin.stdlib;
  exports some.package;
}
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"
}
请注意,我必须在java编译任务上指定一个模块路径,否则编译失败:

错误:找不到模块:kotlin.stdlib 需要kotlin.stdlib

无论如何,现在这个构建失败了,出现了这个错误,我不知道如何解决它:

错误:包some.package.impl不存在

导入some.package.impl.roundoundtimpl

错误:找不到符号

返回新的roundoundtimpl(队列大小、并行性、工作线程、线程池)

我认为编译的Kotlin部分是正常的,然后java部分失败了,因为它没有“看到”Kotlin的一面

我想我应该告诉它在类路径中加载已经编译好的kotlin类;但是(首先)在格拉德尔我该怎么做?还有(第二)这可能吗?我认为在Java9中不能混合使用模块路径和类路径

我怎样才能解决这个问题?我认为这是一种非常常见的情况,因为每个java9风格的模块都将是一个混合语言模块(因为
module info.java
),所以我认为这里缺少一些真正基本的东西


提前谢谢

解决了!将kotlin编译目录设置为与Java相同的目录就足够了:

compileKotlin.destinationDir = compileJava.destinationDir
它现在起作用了,无论是在同一棵树上还是在不同的树上;但是有一个怪癖:
jar
任务生成一个jar,其中所有条目都是重复的。下一步我会解决这个问题


谢谢大家

我使用下面的gradle脚本,将module-info.java放在src/module下。它会自动包含在jar中(无重复项):

我不会再更新了,看一看
查看当前使用的版本。

接受的答案对我不起作用(至少不是它的呈现方式),但这是起作用的:

plugins {
    id "org.jetbrains.kotlin.jvm" version "1.3.50"
}

compileKotlin {
    doFirst {
        destinationDir = compileJava.destinationDir
    }
}

jar {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
按照公认的答案建议的方式进行操作导致我出现以下错误:

为指定的目录“/path/to/project/build/classes/kotlin/main” 属性“compileKotlinOutputClasses”不存在



Gradle版本:5.6

要学究气,
模块信息。java
不是真正的java,它是一种特殊的DSL,但Kotlin开发人员已经表示,他们将保持原样。是的,感谢您的澄清!如果将接口和impl都保存在Java或Kotlin中会怎么样。那么它会编译吗?另外,为什么要使用JVM1.8编译Kotlin?谢谢您的评论。一个全java的解决方案是编译的,而一个全kotlin的解决方案总是一个混合项目,因为正如前面所说的modules-info.java是由javac管理的,所以结果是相同的。另外,我不认为我正在使用JVM1.8进行compileKotlin,只是告诉编译器使用1.8Target(这是最新的);我错了吗?从Kotlin版本开始,您现在可以使用一个简单的
jar{duplicatesStrategy=“exclude”}