javaspring-bootgradlespring-boot-gradle-plugin

Spring Boot Gradle multi-project build not seeing internal dependencies during tests


I'm having a problem on a larger multi-project build that I was migrating from Gradle 4 to 5, and replicated the issue on a smaller, more concise build to demonstrate the issue.

I have 2 projects in the build. One is a dependency (basic library) used by the other.

demo (root project)
|- build.gradle
|
|--- demo-web
|---|- build.gradle
|
|--- demo-dependency
|---|- build.gradle

Snippet of demo-web: build.gradle

...
dependencies {
    implementation project(':demo-dependency')
    ...
}
...

The dependency project defines one class that is used in the web project, DownstreamThing.

The web project attempts to use that to construct its own object, but during a build on the root project level, it fails.

> ./gradlew build
> Task :demo-web:test

com.example.demo.ThingTest > testThing FAILED
    java.lang.NoClassDefFoundError at ThingTest.java:12
        Caused by: java.lang.ClassNotFoundException at ThingTest.java:12

ThingTest.java

    @Test
    public void testThing() {
        DownstreamThing t =  new DownstreamThing(); //line 12, ClassNotFoundException
        assertTrue(t != null);
    }

I didn't have any trouble with this in Gradle 4, but only in Gradle 5. Why is the dependency not being found during the test task?

Full source for the example is here: https://bitbucket.org/travelsized/gradle-problem/src/master/


Solution

  • Bjørn Vester's answer got me pointed in the right direction. The spring-boot plugin was causing the jar tasks to go awry. I needed to make sure that the bootJar task was disabled for the dependency while the jar task was enabled.

    The changes in the configuration to do this between versions of Gradle and the Spring Boot plugin made this get lost in the upgrades.

    Previously, I could specify a classifier for the jar post-boot:

    bootRepackage  {
        classifier = 'exec'
    }
    

    Now, I need to enable and disable the appropriate tasks:

    bootJar {
        enabled = false
    }
    
    jar {
        enabled = true
        archiveBaseName = "demo-dependency"
    }
    

    In the larger project, I previously had a jar task that specified the archiveBaseName, but didn't explicitly enable it to override the bootJar task. Once I made the above changes (while keeping the boot plugins in place), things started working.