使用Gradle构建Kotlin + Java 9项目

时间:2017-12-05 15:59:06

标签: java gradle kotlin java-9

我对Gradle(和Java 9,说实话)相当新,而且我正在尝试使用Gradle构建一个简单的库项目,它是Java 9和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;
}

build.gradle是:

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不存在

     

import some.package.impl.RoundaboutImpl;

     

错误:找不到符号

     

返回新的RoundaboutImpl<>(queueSize,parallelism,worker,threadPool);

认为编辑的Kotlin部分正常,然后java部分失败,因为它没有""看到" kotlin方面,可以这么说。

我想我应该以某种方式告诉它在类路径中加载已编译的kotlin类;但是(首先)我如何在gradle中这样做?和(第二)甚至可能?我认为你不能在Java 9中混合模块路径和类路径。

我该如何解决这个问题?我认为这是一种非常常见的情况,因为每个java9风格的模块都是混合语言模块(因为module-info.java),所以我想我在这里缺少一些非常基本的东西。

提前致谢!

3 个答案:

答案 0 :(得分:10)

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

 classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"

现在可以使用同一棵树或不同树木中的来源;但有一个怪癖:compileKotlin.destinationDir = compileJava.destinationDir 任务产生一个包含所有条目重复的jar。我将继续努力解决这个问题。

感谢大家!

答案 1 :(得分:2)

我正在使用以下gradle脚本,我将module-info.java放在src / module下。它自动包含在jar中(没有重复):

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
        }
    }
}

我不会再更新它了,看看https://github.com/robstoll/atrium/blob/master/build.gradle 查看当前使用的版本。

答案 2 :(得分:-1)

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

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