Upgrading from Gradle 6.7 to 7.4: NoClassDefFoundError

55 views Asked by At

I'm fairly unfamiliar with Gradle, so pardon the lack of detail or any misused terminology.

I'm upgrading the version of Gradle used by my java project from v6.7 to 7.4. My project consists of two 'sub' Gradle projects in the settings.gradle file:

rootProject.name = 'MyApp'

include 'MyApp-client'
include 'MyApp-server'

And the corresponding build.gradle files are as follows.

MyApp's build.gradle:

buildscript {
    repositories {
        maven { url "https://plugins.gradle.org/m2/" }
    }
    dependencies {
        classpath 'com.diffplug.spotless:spotless-plugin-gradle:6.8.0'
    }
}

allprojects {
    buildscript {
        repositories {
            maven { url "https://plugins.gradle.org/m2/" }
        }
    }
    apply plugin: 'java'
    apply plugin: 'com.diffplug.spotless'
    spotless {
        java {
            targetExclude 'src/main/java/com/company/myapp/server/ports/bar/baz/**'
            googleJavaFormat()
        }
    }

    repositories {
        maven {
            url "s3://fdeploy/maven/release"
            authentication {
                awsIm(AwsImAuthentication)
            }
        }
        maven {
            url "s3://fdeploy/maven/snapshot"
            authentication {
                awsIm(AwsImAuthentication)
            }
        }
        jcenter()
        mavenLocal()
        mavenCentral()
    }

    dependencies {
        testImplementation 'org.hsqldb:hsqldb:2.7.2'
    }

    sourceCompatibility = 1.17
    targetCompatibility = 1.17
    group = "com.company"
    def major_version = "1"
    def minor_version = "1"
    def patch_version = project.hasProperty("patchVersion") ? ".${project.patchVersion}" : "-SNAPSHOT"
    version = "$major_version.$minor_version$patch_version"

}

task("currentVersion") {
    println version
}

MyApp-client's build.gradle:

repositories {
    maven {
        url "https://plugins.gradle.org/m2/"
    }
}

apply plugin: 'maven-publish'

dependencies {
    def v
    v = "0.9.525"
    implementation group: 'com.company', name: 'cache', version: "${v}"
    implementation group: 'com.company', name: 'datatypes', version: "${v}"
    implementation group: 'com.company', name: 'datatypes-jackson', version: "${v}"
    implementation group: 'com.company', name: 'datatypes-jersey', version: "${v}"
    implementation group: 'com.company', name: 'datatypes-uel', version: "${v}"

    implementation group: 'io.swagger.core.v3', name: 'swagger-jaxrs2', version: '2.2.2'
    implementation 'io.opentracing.contrib:opentracing-okhttp3:3.0.0'
    implementation 'io.jaegertracing:jaeger-client:1.8.1'

    v = "2.9.10"
    implementation "com.fasterxml.jackson.core:jackson-annotations:${v}"
    implementation "com.fasterxml.jackson.core:jackson-core:${v}"
    implementation "com.fasterxml.jackson.core:jackson-databind:${v}"
    implementation "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${v}"
    implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:${v}"

    v = "2.6.1"
    implementation "com.squareup.retrofit2:retrofit:${v}"
    implementation "com.squareup.retrofit2:converter-jackson:${v}"

    v = "1.18.20"
    implementation "org.projectlombok:lombok:${v}"
    annotationProcessor "org.projectlombok:lombok:${v}"

    v = "4.12"
    testImplementation "junit:junit:${v}"

    v = "3.4"
    testImplementation "org.easymock:easymock:${v}"

    v = "3.9.1"
    testImplementation "org.assertj:assertj-core:${v}"
}


jar {
    enabled true
}


tasks.withType(Test) {
    testLogging {
        events "standardOut", "started", "passed", "skipped", "failed"
        showStandardStreams = true
    }
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            from components.java
            artifactId 'myapp-client'
        }
    }
    repositories {
        maven {
            url "s3://fdeploy/maven/release"
            authentication {
                awsIm(AwsImAuthentication)
            }
        }
    }
}

MyApp-server's build.gradle:

plugins {
    id "com.github.johnrengelman.shadow" version "7.0.0"
}

repositories {
    maven {
        url "https://plugins.gradle.org/m2/"
    }
}

dependencies {
    def v
    implementation project(":MyApp-client")

    v = "0.9.518"
    implementation group: 'com.company', name: 'cache', version: "${v}"
    implementation group: 'com.company', name: 'datatypes', version: "${v}"
    implementation group: 'com.company', name: 'datatypes-jackson', version: "${v}"
    implementation group: 'com.company', name: 'datatypes-jersey', version: "${v}"
    implementation group: 'com.company', name: 'catalog', version: "${v}"

    implementation group: 'io.swagger.core.v3', name: 'swagger-jaxrs2', version: '2.2.2'
    implementation group: 'com.bugsnag', name: 'bugsnag', version: '3.+'
    implementation "com.company:instrumentation:1.0.33"
    implementation 'no.finn.unleash:unleash-client-java:4.4.1'
    implementation 'io.opentracing.contrib:opentracing-jaxrs2:1.0.0'
    implementation 'io.jaegertracing:jaeger-client:1.8.1'
    implementation "io.vavr:vavr:0.10.4"
    implementation "com.googlecode.cqengine:cqengine:3.6.0"
    implementation "io.lettuce:lettuce-core:6.2.4.RELEASE"
    
    v = "1.3.15"
    implementation group: 'io.dropwizard', name: 'dropwizard-core', version: "${v}"
    implementation group: 'io.dropwizard', name: 'dropwizard-bom', version: "${v}"
    implementation group: 'io.dropwizard', name: 'dropwizard-servlets', version: "${v}"

    v = "2.9.10"
    implementation "com.fasterxml.jackson.core:jackson-annotations:${v}"
    implementation "com.fasterxml.jackson.core:jackson-core:${v}"
    implementation "com.fasterxml.jackson.core:jackson-databind:${v}"
    implementation "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${v}"
    implementation "com.fasterxml.jackson.datatype:jackson-datatype-joda:${v}"

    v = "1.18.24"
    implementation "org.projectlombok:lombok:${v}"
    annotationProcessor "org.projectlombok:lombok:${v}"

    v = "4.12"
    testImplementation "junit:junit:${v}"

    v = "2.9.0"
    testImplementation "org.mockito:mockito-core:${v}"
}

configurations.all {
    resolutionStrategy {
        def v
        v = "2.5.0-b61"
        force "org.glassfish.hk2:hk2-api:${v}"

        v = "2.23.2"
        force "org.glassfish.jersey.containers:jersey-container-servlet-core:${v}"
        force "org.glassfish.jersey.core:jersey-common:${v}"
        force "org.glassfish.jersey.core:jersey-server:${v}"
        force "org.glassfish.jersey.ext:jersey-bean-validation:${v}"

        // Dropwizard pulls in a really old beta version of Mockito by default.
        v = "2.9.0"
        force "org.mockito:mockito-core:${v}"

        v = "1.18.24"
        force "org.projectlombok:lombok:${v}"
    }
}

clean {
    delete "target"
}

jar {
    enabled true
    manifest {
        attributes "class-path": "lib-signed/bcprov-jdk15on.jar"
        attributes "main-class": "com.company.myapp.server.MyAppApp"
    }
}

shadowJar {
    mergeServiceFiles()
}

task targetJar(type: Copy) {
    dependsOn "shadowJar"

    from "build/libs/"
    into "target/"

    include "${project.name}-${version}-all.jar"
    rename  "${project.name}-${version}-all.jar",
            "myapp.jar"
}

tasks.withType(Test) {
    testLogging {
        events "standardOut", "started", "passed", "skipped", "failed"
        showStandardStreams = true
    }
}

assemble.dependsOn targetJar

When I run my gradle clean build command, some tests are also run (somewhere? somehow? I'm not exactly sure where/how/what triggers these tests to run), and the tests fail with NoClassDefFoundErrors:

com.company.myapp.server.ports.bar.MyMissingClassTestV1 > testConfidenceCheck STARTED
com.company.myapp.server.ports.bar.MyMissingClassTestV1 > testConfidenceCheck FAILED
    java.lang.NoClassDefFoundError at MyMissingClassTestV1.java:10

The line number of the failure points to the initialization of a class, MyMissingClassV1, however I'm not sure what about the upgrade would cause this error to occur. For the record, the tests all pass prior to the version upgrade changes I make.

I'm not sure if I'm articulating the problem correctly, but my hunch tells me that when the binaries for the tests are generated, the build is missing / does not include the MyMissingClassV1 class. Other reading I've done into the matter tells me that a 'fat' jar should solve this problem with missing dependencies, and that the "com.github.johnrengelman.shadow" plugin should somehow be triggering the creation of this 'fat' jar, but evidently this is not working as expected.

Any pointers in the right direction would be greatly appreciated, thanks for reading!

0

There are 0 answers