4

Background:

I currently have a multi-module (multi-project) application repo. The "root" is not a runnable application. It's merely the source directory where I have a root build.gradle.kts file which holds the dependencies and plugins that are common between all my sub-projects. Each of my sub-projects have their own build.gradle.kts.

So my overall project structure looks sort of like this:

my_root_project
    - gradle
        - wrapper
            - gradle-wrapper.jar
            - gradle-wrapper.properties
    - gradle.build.kts
    - settings.gradle.kts
    - my_nested_project_a
        - src
            - main
                - kotlin
    - my_nested_project_b
        ...

Issue:

Every time I run gradle build, I get an error saying:

> Task :bootJar FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':bootJar'.
> Main class name has not been configured and it could not be resolved

However when I run any one of my sub-projects (e.g. build :my_nested_project_a:build), it builds just fine.

Current Gradle Build Files

Here's what I currently have in the "root" gradle.build.kts:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

group = "com.example"
version = "1.0.0"
java.sourceCompatibility = JavaVersion.VERSION_1_8
java.targetCompatibility = JavaVersion.VERSION_1_8

plugins {
    id("org.springframework.boot") version "2.1.8.RELEASE" apply false
    id("io.spring.dependency-management") version "1.0.8.RELEASE" apply false
    kotlin("jvm") version "1.3.50"
    kotlin("plugin.spring") version "1.3.50"
    kotlin("plugin.jpa") version "1.3.50"
    kotlin("plugin.allopen") version "1.3.50"
}

allprojects {
    repositories {
        maven(url = "https://my.company.com/repo/with/all/the/stuff/I/need")
    }

    apply(plugin = "org.jetbrains.kotlin.jvm")
    apply(plugin = "java")
    apply(plugin = "org.springframework.boot")
    apply(plugin = "io.spring.dependency-management")
    apply(plugin = "org.jetbrains.kotlin.plugin.spring")

    dependencies {
        implementation("org.springframework.boot:spring-boot-starter-web")
        implementation("org.jetbrains.kotlin:kotlin-reflect")
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    }

    tasks.withType<KotlinCompile> {
        kotlinOptions {
            freeCompilerArgs = listOf("-Xjsr305=strict")
            jvmTarget = "1.8"
        }
    }
}

NOTE: I'm using apply false on my plugins because I thought it would keep gradle from trying to find a main class when building using gradle build.

What I'm trying to do:

I have a CI pipeline that I'd like to simply run gradle build which should run the build task for all of the sub-projects. However, in that process, I'd like to ignore running the build for the "root" project or bypass it since it's not a runnable application, and just build the sub-projects.

Any help would be greatly appreciated! :)

drix
  • 177
  • 3
  • 9

4 Answers4

2

If you want to ignore task bootJar,s o add the following configuration.

bootJar {
    enabled = false
}
Jonathan JOhx
  • 5,784
  • 2
  • 17
  • 33
  • I'm new to Gradle, so forgive me if I'm asking the obvious. Is this Kotlin DSL syntax? Also, I tried adding it to my root `gradle.build.kts` file (outside of any other tasks), but I got compilation errors. Is there a specific place I should be putting it? – drix Oct 08 '19 at 13:04
  • could you please take a look this example project https://github.com/gradle/kotlin-dsl-samples/blob/master/samples/hello-android/build.gradle.kts – Jonathan JOhx Oct 08 '19 at 14:38
1

In your root build.gradle.kts, ignore bootJar task, with Kotlin DSL :

import org.springframework.boot.gradle.tasks.bundling.BootJar

tasks.getByName<BootJar>("bootJar") {
    enabled = false
}
Xavier D
  • 3,364
  • 1
  • 9
  • 16
0

If you have the plugin applied in allprojects session, you're applying it to the root as well, and since it's the first one resolved in gradle build, you should have the main class configured there.

Alternatively, you can remove the apply(plugin = "org.springframework.boot") line from the root and apply the plugin only to the module that has the main method annotated with @SpringBootApplication, and point the plugin to the main class there.

Say your main class is in my_nested_project_a/src/main/com/example/MainClass.kt.

Your my_nested_project_a/build.gradle.kts should look like:

plugins {
    id("org.springframework.boot")
}

springBoot {
    mainClassName = "com.example.MainClass"
}

dependencies {
    ...
}

And you should remove this line from the root build.gradle.kts:

apply(plugin = "org.springframework.boot")
L. Shimizu
  • 11
  • 5
0

I have a similar setup and question. I replaced allprojects with subprojects and added jar.enabled(false) to the root build.gradle file and it worked.

plugins {
    id("java-library")
    id('org.jetbrains.kotlin.jvm') version "${kotlinVersion}"
    id("com.diffplug.spotless") version "${spotlessVersion}"
    id("maven-publish")
}

jar.enabled(false)

subprojects {
    apply plugin: "java-library"
    apply plugin: "org.jetbrains.kotlin.jvm"
    apply plugin: "com.diffplug.spotless"
    apply plugin: "maven-publish"

    group = GROUP
    version = VERSION_NAME

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

    dependencies {
        testImplementation 'org.jetbrains.kotlin:kotlin-test'
        testImplementation("org.junit.jupiter:junit-jupiter:${junitVersion}")
    }

    publishing {
        publications {
            library(MavenPublication) {
                from components.java
            }
        }
        repositories {
            maven {
                url "https://gitlab.mhighpoint.com/api/v4/projects/${System.getenv('CI_PROJECT_ID')}/packages/maven"
                credentials(HttpHeaderCredentials) {
                    name = "Job-Token"
                    value = System.getenv('CI_JOB_TOKEN')
                }
                authentication {
                    header(HttpHeaderAuthentication)
                }
            }
        }
    }

    spotless {
        java {
            googleJavaFormat() // googleJavaFormat('1.1') to specify a specific version
        }
        kotlin {
            target '**/src/**/*.kt'
            ktlint("0.41.0").userData('disabled_rules': 'no-wildcard-imports,import-ordering')

            trimTrailingWhitespace()
            indentWithSpaces()
            endWithNewline()
        }
        format 'misc', {
            target '**/*.gradle'

            trimTrailingWhitespace()
            indentWithSpaces() // or spaces. Takes an integer argument if you don't like 4
            endWithNewline()
        }
    }

    test {
        useJUnitPlatform()
    }

    jar {
        archiveBaseName = "${rootProject.name}-${project.name}"
    }

    tasks {
        assemble.dependsOn(spotlessApply)
    }
}