Nayan Kurude
Nayan Kurude

Reputation: 183

Gradle, Kotlin, Multi Module Project: Getting build errors while compiling this project

I am getting the following error on running gradle build command on root folder.

E:\Code\mdh>gradle build

> Task :multidemo:compileKotlin FAILED
e: E:\Code\mdh\multidemo\src\main\kotlin\com\simbalarry\multidemo\SampleController.kt: (3, 23): Unresolved reference: somelib
e: E:\Code\mdh\multidemo\src\main\kotlin\com\simbalarry\multidemo\SampleController.kt: (18, 12): Unresolved reference: Tester

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':multidemo:compileKotlin'.
> Compilation error. See log for more details

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 5s
4 actionable tasks: 1 executed, 3 up-to-date

Below is my project structure and multidemo project is using some functionalities of somelib. Also, I have deliberetly kept somelib as spring boot project as I will be adding more spring boot related functionalities later.

Root Project
  |
  |---settings.gradle
  |---somelib
  |       |
  |       |---build.gradle
  |       |---settings.gradle
  |       |---src/main/kotlin/somepackage/Tester.kt
  |       |---src/main/kotlin/somepackage/SomeLibApplication.kt
  |
  |---multidemo
  |       |---build.gradle
  |       |---settings.gradle
  |       |---src/main/kotlin/somepackage/SampleController.kt
  |       |---src/main/kotlin/somepackage/MultidemoApplication.kt

Below are the contents of every file

Root/settings.gradle

include ':somelib', ':multidemo'

somelib/build.gradle

plugins {
    id 'org.springframework.boot' version '2.1.3.RELEASE'
    id 'org.jetbrains.kotlin.jvm' version '1.3.21'
    id 'org.jetbrains.kotlin.plugin.spring' version '1.3.21'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.simbalarry'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
    implementation 'org.jetbrains.kotlin:kotlin-reflect'
    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

compileKotlin {
    kotlinOptions {
        freeCompilerArgs = ['-Xjsr305=strict']
        jvmTarget = '1.8'
    }
}

compileTestKotlin {
    kotlinOptions {
        freeCompilerArgs = ['-Xjsr305=strict']
        jvmTarget = '1.8'
    }
}

somelib/settings.gradle

pluginManagement {
    repositories {
        gradlePluginPortal()
    }
}
rootProject.name = 'somelib'

somelib/src/main/kotlin/somepackage/Tester.kt

package com.simbalarry.somelib


/*
 * Created on : 17-03-2019
 * Author     : Nayan Kurude
 */

object Tester {
  fun getOutputText(): String {
    return "Sample Text"
  }
}

somelib/src/main/kotlin/somepackage/SomelibApplication.kt

package com.simbalarry.somelib

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class SomelibApplication

fun main(args: Array<String>) {
    runApplication<SomelibApplication>(*args)
}

multidemo/build.gradle

plugins {
    id 'org.springframework.boot' version '2.1.3.RELEASE'
    id 'org.jetbrains.kotlin.jvm' version '1.3.21'
    id 'org.jetbrains.kotlin.plugin.spring' version '1.3.21'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.simbalarry'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
    mavenLocal()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
    implementation 'org.jetbrains.kotlin:kotlin-reflect'
    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
    compile project(':somelib')
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

compileKotlin {
    kotlinOptions {
        freeCompilerArgs = ['-Xjsr305=strict']
        jvmTarget = '1.8'
    }
}

compileTestKotlin {
    kotlinOptions {
        freeCompilerArgs = ['-Xjsr305=strict']
        jvmTarget = '1.8'
    }
}

multidemo/settings.gradle

pluginManagement {
    repositories {
        gradlePluginPortal()
    }
}
rootProject.name = 'multidemo'

multidemo/src/main/kotlin/somepackage/MultiDemoApplication.kt

package com.simbalarry.multidemo

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class MultidemoApplication

fun main(args: Array<String>) {
    runApplication<MultidemoApplication>(*args)
}

multidemo/src/main/kotlin/somepackage/SampleController.kt

package com.simbalarry.multidemo

import com.simbalarry.somelib.Tester
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController


/*
 * Created on : 17-03-2019
 * Author     : Nayan Kurude
 */

@RestController
class SampleController {

  @RequestMapping("/hello")
  fun hello(): String {
    return Tester.getOutputText()
  }
}

Could anyone please tell me where am i doing something wrong.

Upvotes: 0

Views: 2232

Answers (1)

JB Nizet
JB Nizet

Reputation: 691695

As I said in comments: somelib is supposed to be a library. So it shouldn't apply the spring boot plugin, whose role is to create a Spring Boot application.

Your build.gradle file for somelib should look like this:

plugins {
    id 'java-library' // 1
    id 'org.springframework.boot' version '2.1.3.RELEASE' apply false // 2
    id 'io.spring.dependency-management' version '1.0.6.RELEASE' //3
    id 'org.jetbrains.kotlin.jvm' version '1.3.21'
    id 'org.jetbrains.kotlin.plugin.spring' version '1.3.21'
}

group = 'com.simbalarry'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}

dependencyManagement { // 4
    imports {
        mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
    }
}

ext['kotlin.version'] = '1.3.21' // 5

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.fasterxml.jackson.module:jackson-module-kotlin'
    implementation 'org.jetbrains.kotlin:kotlin-reflect'
    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

compileKotlin {
    kotlinOptions {
        freeCompilerArgs = ['-Xjsr305=strict']
        jvmTarget = '1.8'
    }
}

compileTestKotlin {
    kotlinOptions {
        freeCompilerArgs = ['-Xjsr305=strict']
        jvmTarget = '1.8'
    }
}

Some explanations (see the comments in the code):

  1. Applies the java library gradle plugin, since that's what you want to create: a library that can be used in the other project
  2. Adds the Spring Boot plugin to the classpath of the build without applying it, in order to be able to use its BOM later. See https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/gradle-plugin/reference/html/#managing-dependencies-using-in-isolation
  3. Applies the spring dependency management plugin to be able to specify dependencies without version, by using the version numbers specified in the spring boot BOM
  4. Configure the dependency management plugin to use the spring boot BOM
  5. Override the kotlin version used in the BOM (1.2.71) by the one you want to use. See https://docs.spring.io/dependency-management-plugin/docs/current-SNAPSHOT/reference/html/#dependency-management-configuration-bom-import-override-property

Upvotes: 1

Related Questions