Hello y'all,

whenever we try to update our SpringBoot application from 2.3.1 to 2.3.3 (using gradle), it fails with the following Exception:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
        at org.springframework.boot.SpringApplication.<clinit>(SpringApplication.java:196)
        at de.porsche.as.AppApplicationKt.main(AppApplication.kt:13)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 2 more

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':bootRun'.
> Process 'command '/Library/Java/JavaVirtualMachines/jdk-11.0.6.jdk/Contents/Home/bin/java'' finished with non-zero exit value 1

We don't quite understand why, since there were no breaking changes between SpringBoot 2.3.1 and 2.3.3? Or did we miss something?

Our gradle buildscript with all dependencies:

```buildscript { ext { kotlinVersion = '1.3.72' jacksonVersion = '2.11.2' springBootVersion = '2.3.1.RELEASE' junitVersion = '5.6.2' atriumVersion = '0.12.0' mockkVersion = '1.10.0' springmockkVersion = '2.0.3' jwtVersion = '0.4.1' khttpVersion = '1.0.0' wiremockVersion = '2.27.1' httpclientVersion = '4.5.12' kotlinterGradleVersion = '2.4.1' klaxonVersion = '5.3' kotlinLoggingVersion = '1.8.3' } repositories { mavenCentral() jcenter() maven { url "https://plugins.gradle.org/m2/" } maven { url xxxxxxxxxx } } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}") classpath("org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}") classpath "com.github.ben-manes:gradle-versions-plugin:0.29.0"

    // Verify pacts from gradle
    classpath 'au.com.dius:pact-jvm-provider-gradle_2.12:3.6.15'

    // Linter
    classpath("org.jmailen.gradle:kotlinter-gradle:${kotlinterGradleVersion}")

    //elaborate test logging
    classpath("com.adarshr:gradle-test-logger-plugin:2.1.0")

    classpath 'com.github.ksoichiro:gradle-console-reporter:0.6.2'
}

}

apply plugin: 'kotlin' apply plugin: 'kotlin-spring' apply plugin: 'org.jmailen.kotlinter' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' apply plugin: 'com.github.ben-manes.versions' apply plugin: 'au.com.dius.pact' apply plugin: 'com.adarshr.test-logger'

apply plugin: 'jacoco' apply plugin: 'com.github.ksoichiro.console.reporter'

group = 'de.xxxxxx.xxxx' sourceCompatibility = '1.8'

repositories { mavenCentral() maven { url REMOVED } jcenter() // to include 'kotlinx-html', which detekt needs for the html report }

test { useJUnitPlatform { excludeTags 'IntegrationTest' }

testLogging {
    events "passed", "skipped", "failed"
}

}

testlogger { theme 'standard' showExceptions true slowThreshold 100 showSummary true showPassed true showSkipped true showFailed true showStandardStreams false showPassedStandardStreams false showSkippedStandardStreams true showFailedStandardStreams true showStackTraces true }

task integrationTest(type: Test) { systemProperty "javax.net.ssl.keyStore", System.getProperty("keystore") systemProperty "javax.net.ssl.keyStorePassword", System.getProperty("password") useJUnitPlatform { includeTags 'IntegrationTest' }

testLogging {
    events "passed", "skipped", "failed"
    // showStandardStreams = true
}

}

dependencies { compile("org.springframework.boot:spring-boot-starter-validation:${springBootVersion}")

implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")

implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${jacksonVersion}")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:${jacksonVersion}")
implementation("com.fasterxml.jackson.core:jackson-core:${jacksonVersion}")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-joda:${jacksonVersion}")

implementation("com.github.tomakehurst:wiremock:${wiremockVersion}")

implementation("khttp:khttp:${khttpVersion}")

implementation('org.apache.httpcomponents:httpasyncclient')
implementation("org.apache.httpcomponents:httpclient:${httpclientVersion}")


implementation('org.springframework.boot:spring-boot-starter-actuator')
implementation('org.springframework.boot:spring-boot-starter-web')
implementation('org.springframework.boot:spring-boot-starter-cache')

runtime('org.springframework.boot:spring-boot-devtools')

testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.junit.jupiter:junit-jupiter:$junitVersion")

testImplementation("ch.tutteli.atrium:atrium-cc-en_GB-robstoll:$atriumVersion")
testImplementation("io.mockk:mockk:${mockkVersion}")
testImplementation("com.ninja-squad:springmockk:${springmockkVersion}")
implementation("com.beust:klaxon:${klaxonVersion}")
implementation("io.github.microutils:kotlin-logging:${kotlinLoggingVersion}")

}

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

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

kotlinter { ignoreFailures = false indentSize = 4 reporters = ['html'] experimentalRules = false disabledRules = [] fileBatchSize = 30 }

consoleReporter { jacoco { enabled true // Set this property to false if you want to see console report always. onlyWhenCoverageTaskExecuted false reportAfterBuildFinished true failIfLessThanThresholdError false autoconfigureCoverageConfig true coverageTaskName 'jacocoTestReport'

    brokenCoverageErrorMessage "Coverage has fallen below the threshold in some projects."
}

}



**Comment From: wilkinsona**

The `org/apache/commons/logging/LogFactory` that should be used in a Spring Boot application can be found in `spring-jcl`. It should be on the classpath as it's a transitive dependency of Spring Framework's other modules. I would guess that you have a corrupted jar file or perhaps a dependency resolution failure that has resulted in transitive dependencies not being resolved. `./gradlew dependencyInsight --dependency spring-jcl` may help to identify the cause of the missing class.

**Comment From: mhp-borisbojic**

It's weird. When I run `./gradlew dependencyInsight --dependency spring-jcl` with version 2.3.1, I get a full report about the dependencies:

Task :dependencyInsight org.springframework:spring-jcl:5.2.7.RELEASE variant "compile" [ org.gradle.status = release (not requested) org.gradle.usage = java-api org.gradle.libraryelements = jar (compatible with: classes) org.gradle.category = library

  Requested attributes not found in the selected variant:
     org.gradle.dependency.bundling     = external
     org.jetbrains.kotlin.platform.type = jvm
     org.gradle.jvm.version             = 8

] Selection reasons: - Selected by rule - By constraint

org.springframework:spring-jcl:5.2.7.RELEASE +--- org.springframework:spring-core:5.2.7.RELEASE | +--- org.springframework.boot:spring-boot-starter:2.3.1.RELEASE (requested org.springframework:spring-core) | | +--- org.springframework.boot:spring-boot-starter-actuator:2.3.1.RELEASE | | | +--- compileClasspath (requested org.springframework.boot:spring-boot-starter-actuator) | | | --- org.springframework.boot:spring-boot-dependencies:2.3.1.RELEASE

(Truncated the rest)


When I switch to SpringBoot 2.3.3, I get nothing anymore:

Task :dependencyInsight No dependencies matching given input were found in configuration ':compileClasspath'


I have no idea what's going on ...? :(


**Comment From: wilkinsona**

You have some corrupted dependency metadata which means that the transitive dependencies of `spring-core` cannot be resolved. This is what I get for a Spring Boot 2.3.3 project using Kotlin:

./gradlew dependencyInsight --dependency spring-jcl

Task :dependencyInsight org.springframework:spring-jcl:5.2.8.RELEASE (selected by rule) variant "compile" [ org.gradle.status = release (not requested) org.gradle.usage = java-api org.gradle.libraryelements = jar (compatible with: classes) org.gradle.category = library

  Requested attributes not found in the selected variant:
     org.gradle.dependency.bundling     = external
     org.jetbrains.kotlin.platform.type = jvm
     org.gradle.jvm.version             = 11

]

org.springframework:spring-jcl:5.2.8.RELEASE --- org.springframework:spring-core:5.2.8.RELEASE +--- org.springframework.boot:spring-boot-starter:2.3.3.RELEASE | --- compileClasspath (requested org.springframework.boot:spring-boot-starter) +--- org.springframework.boot:spring-boot:2.3.3.RELEASE | +--- org.springframework.boot:spring-boot-starter:2.3.3.RELEASE () | --- org.springframework.boot:spring-boot-autoconfigure:2.3.3.RELEASE | --- org.springframework.boot:spring-boot-starter:2.3.3.RELEASE () +--- org.springframework:spring-context:5.2.8.RELEASE | --- org.springframework.boot:spring-boot:2.3.3.RELEASE () +--- org.springframework:spring-aop:5.2.8.RELEASE | --- org.springframework:spring-context:5.2.8.RELEASE () +--- org.springframework:spring-beans:5.2.8.RELEASE | +--- org.springframework:spring-context:5.2.8.RELEASE () | --- org.springframework:spring-aop:5.2.8.RELEASE () --- org.springframework:spring-expression:5.2.8.RELEASE --- org.springframework:spring-context:5.2.8.RELEASE (*)

(*) - dependencies omitted (listed previously)

A web-based, searchable dependency report is available by adding the --scan option.

BUILD SUCCESSFUL in 979ms 1 actionable task: 1 executed ```

You could try building with --refresh-dependencies to cause Gradle to download your app's dependencies again. I also noticed that you're using a custom Maven repository. You may want to check that it isn't serving broken metadata for spring-core.

Unfortunately, there's nothing that we can do in Spring Boot to resolve this as the problem is out of our control so I'm going to close this issue. If you'd like further assistance, please follow up on Stack Overflow or Gitter.

Comment From: mhp-borisbojic

Maybe as a heads-up:

There is an issue with the spring-core jar inside the spring-boot 2.3.3.RELEASE jar which we are using. I’m not sure about the root cause of that. But we added a reference to spring-core explicitly in our build.gradle and then it works.

Comment From: snicoll

Thanks for the follow-up

There is an issue with the spring-core jar inside the spring-boot 2.3.3.RELEASE jar which we are using.

Spring Boot doesn't embed Spring Framework. It's just a separate jar that's downloaded by the build system. Spring Boot 2.3.3.RELEASE uses org.springframework:spring-core:5.2.8.RELEASE. Assuming your build uses dependency management, you are probably hardcoding a different version. If using 5.2.8.RELEASE breaks for you, this confirms the corrupted dependency problem @wilkinsona was mentioning earlier. Either way, there is nothing we can about that on our side I am afraid.