Sithira
Sithira

Reputation: 1016

Gradle: multi-project build with spring-boot

I'm new to Gradle and I'm just getting started with it using a multi-project build. Currently, I'm using spring-boot for services and i have the following directory structure

|- api-web (module)
|-- build.gradle
|- api-admin (module)
|-- build.gradle
|- build.gradle (root)
|- settings.gradle

Below are the configurations of the root

build.gradle (root)

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.2.2.RELEASE'
    id 'io.spring.dependency-management' version '1.0.8.RELEASE'
}

description = "Company Multi-Project"

ext {
    springBootVersion = '2.2.2.RELEASE'
}

bootJar {
    enabled = false
}

allprojects {

    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8

    repositories {
        mavenCentral()
    }
}

subprojects {

    group = 'com.company'
    version = '0.0.1-SNAPSHOT'

    apply plugin: 'java'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'

    jar {
        enabled = true
    }

    bootJar {
        enabled = false
    }

    dependencies {

        // Lombok annotation processor
        annotationProcessor 'org.projectlombok:lombok'

        compileOnly 'org.projectlombok:lombok'
    }
}

settings.gradle (root)

rootProject.name = 'core'

include 'common'
include 'api-web'
include 'api-admin'

Gradle configurations of the modules

api-admin (module)

jar {
    manifest {
        attributes 'Main-Class': 'com.company.apiadmin.ApiAdminApplication'
    }
}

dependencies {
    implementation project(':common')
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

I have added jar closure to prevent error on runtime. This avoids the issue where it fails to run saying "No Manifest"

However even after adding that jar closure, now there is a new issue

Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/boot/SpringApplication

Now I know this says class not found, but my question is how does it occur and why and how to overcome this. I have tried most of the suggestions in Medium, StackOverflow and in Blog posts. Nothing helped. Your help will be highly appreciated. Thanks

Upvotes: 8

Views: 6969

Answers (1)

Sithira
Sithira

Reputation: 1016

I found the solution for my self, it was a bit tricky to find but finally, I found it

The main point is that you should definitely add the spring-boot-gradle-plugin and that will resolve all of your NoClassDef errors and No Manifest Found errors. To add this you should define a build script in your root build.gradle file

buildscript {
    ext {
        springBootVersion = "2.2.2.RELEASE"
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
    }
}

Then you should define the plugins for your project

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.2.2.RELEASE'
    id 'io.spring.dependency-management' version '1.0.8.RELEASE'
}

then you can define all the subprojects and allprojects as you normally would.

Then in the modules, in every sub-module just add these lines

apply plugin: 'org.springframework.boot'

bootJar {
    launchScript() // optional
}

dependencies {

    // your module-specific dependencies
}

and the dependencies as you normally would.

That's it, now you can build using gradle and execute the .jar files as you normally would. :-)

Upvotes: 9

Related Questions