Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 965 Vote(s) - 3.44 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Building a Kotlin + Java 9 project with Gradle

#1
I'm fairly new to Gradle (and Java 9, to be honest), and I'm trying to use Gradle to build a simple library project that is a mix of Java 9 and Kotlin. More in detail, there is an interface in Java and an implementation in Kotlin; I'd do everything in Kotlin, but the `modules-info.java` is java anyway, so I decided to do things this way.

I'm building on IntelliJ Idea, with the 1.2.0 kotlin plugin and gradle 4.3.1 defined externally.

Filesystem schema is:

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

`module-info.java` is:

module some.package {
requires kotlin.stdlib;
exports some.package;
}

and `build.gradle` is:

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

Notice that I had to specify a module path on the java compile task, or the compilation fails with:

>error: module not found: kotlin.stdlib
>requires kotlin.stdlib;

Anyway, now this build fails with this error, and I can't figure out how to solve it:

>error: package some.package.impl does not exist

>import some.package.impl.RoundaboutImpl;

>error: cannot find symbol

>return new RoundaboutImpl<>(queueSize, parallelism, worker, threadPool);

I *think* that the Kotlin part of the compilation is going ok, then the java part fails because it doesn't "see" the kotlin side, so to speak.

I think I should tell it somehow to to load the already compiled kotlin classes in the classpath; but (first) how do I do this in gradle? and (second) *is it even possible*? I think you can't mix module path and class path in Java 9.

How can I solve this? I think it is a pretty common situation, as every java9-style module will be a mixed-language module (because of `module-info.java`), so I think I'm missing something really basic here.

Thanks in advance!

Reply

#2
Solved! It was sufficient to set the kotlin compilation dir to the same dir as Java:

compileKotlin.destinationDir = compileJava.destinationDir

It works now, both with the sources in the same tree or in different trees; but with a quirk: the `jar` task produces a jar with all the entries duplicated. I'll work on fix this, next.

Thanks to everyone!
Reply

#3
I am using the following gradle script where I put the module-info.java under src/module. It gets automatically included in the jar (without duplicates):

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

I won't update it any longer, have a look at

[To see links please register here]

to see the current version in use.
Reply

#4
The accepted answer did not work for me (atleast not the way it was presented), but this is what worked:

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

compileKotlin {
doFirst {
destinationDir = compileJava.destinationDir
}
}

jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
```

Doing it the way the accepted answer suggests led to me getting this error:

> Directory '/path/to/project/build/classes/kotlin/main' specified for
> property 'compileKotlinOutputClasses' does not exist.

---

**Gradle version**: 5.6
Reply

#5
I ran into the same problem and the existing answers fixed only part of the issue for me, so I searched over all internet and ended up with a working solution. I don't know exactly why this works, but I decided to share my `build.gradle.kts` file here to help other people to find they way. This file is a combination of many pieces that I found on the internet.

I'm using Java 16, Kotlin 1.5.31 and Gradle 7.1.

**The file tree is:**
```
+ project
- build.gradle.kts
+ src
+ main
+ java
- module-info.java
+ my
+ package
- SomeClasses.java
+ kotlin
+ my
+ package
- MoreClasses.kt
```
**module-info.java**
```java
module name.of.your.javamodule {
requires kotlin.stdlib;
requires kotlinx.coroutines.core.jvm;
requires org.jetbrains.annotations;

exports my.pacakge;
}
```
**build.gradle.kts**
```build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
application
kotlin("jvm") version "1.5.31"
id("org.jetbrains.kotlin.plugin.serialization") version "1.5.31"
}
val kotlinVersion = "1.5.31"

group = "your.group.id"
version = "0.0.1-SNAPSHOT"
application {
mainClass.set("full.name.of.your.MainClass")
mainModule.set("name.of.your.javamodule") // Same defined in module-info.java
executableDir = "run"
}

repositories {
mavenCentral()
}

dependencies {
implementation(kotlin("stdlib-jdk8", kotlinVersion))
implementation("com.michael-bull.kotlin-inline-logger:kotlin-inline-logger:1.0.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2-native-mt")
implementation("org.jetbrains:annotations:22.0.0")
testImplementation(kotlin("test", kotlinVersion))
}

java {
sourceCompatibility = JavaVersion.VERSION_16
targetCompatibility = JavaVersion.VERSION_16
}

tasks {
run.configure {
dependsOn(jar)
doFirst {
jvmArgs = listOf(
"--module-path", classpath.asPath
)
classpath = files()
}
}

compileJava {
dependsOn(compileKotlin)
doFirst {
options.compilerArgs = listOf(
"--module-path", classpath.asPath
)
}
}

compileKotlin {
destinationDirectory.set(compileJava.get().destinationDirectory)
}

jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
}

tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = "16"
}
}

```
Reply

#6
On gradle 7.4 with kotlin DSL, I need to:
* move the module-info.java to src/main/java
* create any java file inside each package to export under src/main/java, at least empty package-info.java

In build.gradle.kts:
```
val compileKotlin: KotlinCompile by tasks
val compileJava: JavaCompile by tasks
compileKotlin.destinationDirectory.set(compileJava.destinationDirectory)
```

Also discussed here:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through