Search code examples
javaspringmavengradle

problem on spring-web and spring-boot-autoconfigure: correct the classpath


I was migrating my API from Java 11 to 17 to reduce high and critical vulnerabilities and changed spring boot version from 2.7.5 to 2.7.11. I'm facing a issue when I run the application even though it builds perfectly:

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.springframework.boot.autoconfigure.condition.OnWarDeploymentCondition.getMatchOutcome(OnWarDeploymentCondition.java:43)

The following method did not exist:

    'javax.servlet.ServletContext org.springframework.web.context.WebApplicationContext.getServletContext()'

The calling method's class, org.springframework.boot.autoconfigure.condition.OnWarDeploymentCondition, was loaded from the following location:

    jar:file:/Users/safak.bilici/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-autoconfigure/2.7.12/5bb8661bba72f7ca353ae486ccb06285f0ed84eb/spring-boot-autoconfigure-2.7.12.jar!/org/springframework/boot/autoconfigure/condition/OnWarDeploymentCondition.class

The called method's class, org.springframework.web.context.WebApplicationContext, is available from the following locations:

    jar:file:/Users/safak.bilici/.gradle/caches/modules-2/files-2.1/org.springframework/spring-web/6.0.0/a4c5f5a17e22e9de997628be893bea0e40eab152/spring-web-6.0.0.jar!/org/springframework/web/context/WebApplicationContext.class

The called method's class hierarchy was loaded from the following locations:

    org.springframework.web.context.WebApplicationContext: file:/Users/safak.bilici/.gradle/caches/modules-2/files-2.1/org.springframework/spring-web/6.0.0/a4c5f5a17e22e9de997628be893bea0e40eab152/spring-web-6.0.0.jar


Action:

Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.boot.autoconfigure.condition.OnWarDeploymentCondition and org.springframework.web.context.WebApplicationContext

My gradle file looks like this:

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

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
    testImplementation 'org.mockito:mockito-core:4.8.0'
    testImplementation 'org.mockito:mockito-inline:4.8.0'
    implementation 'org.springframework.boot:spring-boot-starter-web'

    implementation 'org.springdoc:springdoc-openapi-ui:1.6.12'
    implementation 'redis.clients:jedis:4.3.1'
    implementation 'com.google.code.gson:gson:2.10'
    implementation platform('com.amazonaws:aws-java-sdk-bom:1.12.328')
    implementation 'com.amazonaws:aws-java-sdk-dynamodb:1.12.332'
    implementation 'software.amazon.awssdk:dynamodb:2.20.0'
    implementation 'software.amazon.awssdk:athena:2.20.5'
    implementation 'org.opensearch:opensearch:2.6.0'
    implementation 'org.opensearch.client:opensearch-rest-high-level-client:2.3.0'
    implementation 'com.fasterxml.jackson.core:jackson-core:2.13.4'
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4.2'
    implementation 'com.amazonaws:aws-java-sdk-sqs:1.12.333'

    implementation 'org.springframework.boot:spring-boot-starter-aop'
    implementation 'org.springframework.boot:spring-boot-starter-parent:3.2.0'
    implementation 'org.apache.httpcomponents.client5:httpclient5-fluent:5.1.4'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'

    compileOnly 'org.projectlombok:lombok:1.18.24'
    implementation group: 'commons-io', name: 'commons-io', version: '2.7'

    annotationProcessor 'org.projectlombok:lombok:1.18.24'
    annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-autoconfigure:2.7.12'
    implementation 'org.springframework:spring-core'

    implementation 'org.springframework:spring-web:6.0.0'

    implementation 'com.mysql:mysql-connector-j'
    implementation 'ch.qos.logback:logback-classic:1.2.13'
    implementation 'ch.qos.logback:logback-core:1.2.13'
    implementation 'org.postgresql:postgresql:42.7.0'
    implementation 'commons-dbutils:commons-dbutils:1.8.1'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    implementation 'io.netty:netty-all:4.1.100.Final'
    implementation 'io.netty:netty-codec-haproxy:4.1.100.Final'
    implementation 'io.netty:netty-codec-http:4.1.100.Final'
    implementation 'io.netty:netty-codec-http2:4.1.100.Final'
    implementation 'io.netty:netty-handler:4.1.100.Final'
    implementation 'io.projectreactor.netty:reactor-netty-http:1.1.13'
    implementation 'org.jooq:jooq:3.18.7'
    implementation 'org.jooq:jooq-codegen:3.18.7'
    implementation 'org.jooq:jooq-meta:3.18.7'

    implementation 'org.json:json:20231013'
    implementation 'org.apache.tomcat.embed:tomcat-embed-core:9.0.83'


    implementation 'javax.annotation:javax.annotation-api:1.3.2'
    implementation 'javax.xml.bind:jaxb-api:2.3.1'
    implementation 'org.eclipse.jetty:jetty-server:11.0.14'
    implementation 'org.springframework.boot:spring-boot-starter-jetty:3.1.2'

    implementation 'org.apache.commons:commons-collections4:4.4'

    implementation 'com.amazonaws:aws-java-sdk-ssm'

    implementation 'org.yaml:snakeyaml:2.0'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'io.github.resilience4j:resilience4j-spring-boot2:1.7.1'
    implementation 'io.github.resilience4j:resilience4j-reactor:1.7.1'
    testImplementation 'org.springframework.boot:spring-boot-starter-test:2.6.3'

    testCompileOnly 'org.projectlombok:lombok:1.18.24'

    testAnnotationProcessor 'org.projectlombok:lombok:1.18.24'

}

I tried most of the versions of org.springframework:spring-web and org.springframework.boot:spring-boot-autoconfigure, normally spring-web 5.3.27 version runs perfectly but it has a critical vulnerability. I tried this solution posted on stackoverflow but it did not work.


Solution

  • The point of the Spring Boot BOM is, that it defines a bunch of libraries in versions that are known to work properly together.

    spring-boot-autoconfigure in version 2.7.12 for example works with javax.servlet.ServletContext, while spring-web in version 6.0.0 works with the new jakarta.servlet.ServletContext. Thus those two are not compatible. spring-web in version 5.3.27 was still using javax.servlet.ServletContext, so was compatible. spring-boot-autoconfigure in version 3.2.2 for example also uses the new jakarta.servlet.ServletContext, so this version would be compatible with spring-web in version 6.0.0.

    But even if you use 6.0.0 and 3.2.2, you probably get further problems with other dependencies still using the old javax. and not the new jakarta.. You have to make sure you are using version of all dependencies that work properly together which usually the Spring Boot BOM is meant to care for, so maybe you should instead use a newer version of Spring Boot that has the versions you want.


    Btw. you should stop use the Spring Dependency Management plugin. It is an obsolete relict from times when Gradle did not have built-in BOM support. It by now does more harm than good and even its maintainer recommends not to use it anymore, but to use the built-in BOM support using platform(...) instead.