I've searched Stack and google looking for an answer to no luck. So I'm hoping someone can help me here.
I have a Spring Boot API which is currently using Tomcat, now I've read about some of the performance improvements in Undertow so I wanted to give it a go and see for myself.
Now, I've removed my spring-boot-web-starter dependancy and added undertow however I'm getting the following errors in a few classes and I can't seem to find how to resolve them:
class file for org.springframework.web.servlet.HandlerExceptionResolver not found
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
java: package org.springframework.web.servlet.config.annotation does not exist
java: package org.springframework.web.servlet.config.annotation does not exist
symbol: class AbstractMappingJacksonResponseBodyAdvice
I've tried just adding the spring-mvc dependancy which does resolve the above errors but then causes another type of error:
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.web.servlet.handler.AbstractHandlerMapping.<init>(AbstractHandlerMapping.java:83)
The following method did not exist:
'org.apache.commons.logging.Log org.springframework.core.log.LogDelegateFactory.getHiddenLog(java.lang.String)'
The method's class, org.springframework.core.log.LogDelegateFactory, is available from the following locations:
Many thanks if anyone can shed some light for me.
** Update **
Adding my build.gradle file:
plugins {
id "org.springframework.boot" version "2.4.3"
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id "com.commercehub.gradle.plugin.avro" version "0.21.0"
id "idea"
}
group 'org.test.profile-service'
version '1.0'
java {
sourceCompatibility = JavaVersion.VERSION_14
targetCompatibility = JavaVersion.VERSION_14
}
ext {
avroVersion = "1.10.1"
}
repositories {
mavenCentral()
jcenter()
maven {
url "https://packages.confluent.io/maven/"
}
}
avro {
createSetters = true
fieldVisibility = "PRIVATE"
}
//apply plugin: "war"
dependencies {
// providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
compile group: 'co.elastic.logging', name: 'logback-ecs-encoder', version: '0.5.2'
compile group: 'com.amazonaws', name: 'aws-java-sdk', version: '1.11.860'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '3.0.0'
compile group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0'
compile('org.springframework.boot:spring-boot-starter-data-elasticsearch')
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-mongodb', version: '2.3.3.RELEASE'
compile group: 'org.springframework.data', name: 'spring-data-elasticsearch', version: '4.1.5'
// compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.3.3.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: '2.3.3.RELEASE'
compile group: 'org.springframework.security', name: 'spring-security-oauth2-client', version: '5.4.0'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-validation', version: '2.4.2'
compile group: 'org.springframework.kafka', name: 'spring-kafka', version: '2.6.5'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-oauth2-resource-server', version: '2.4.2'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-cache', version: '2.4.3'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
compile group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.11.2'
compile group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'
implementation group: 'org.json', name: 'json', version: '20201115'
compile group: 'org.openapitools', name: 'jackson-databind-nullable', version: '0.2.1'
compile group: 'commons-io', name: 'commons-io', version: '2.6'
compile group: 'org.apache.commons', name: 'commons-collections4', version: '4.4'
compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.11'
compile group: 'org.passay', name: 'passay', version: '1.6.0'
compile group: 'com.google.guava', name: 'guava', version: '30.0-jre'
// https://mvnrepository.com/artifact/com.auth0/java-jwt
compile group: 'com.auth0', name: 'java-jwt', version: '3.12.0'
compile group: 'io.confluent', name: 'kafka-schema-registry-client', version: '6.0.0'
compile group: 'io.confluent', name: 'kafka-avro-serializer', version: '6.0.0'
compile group: 'io.confluent', name: 'monitoring-interceptors', version: '6.0.0'
compile(group: 'io.confluent', name: 'kafka-streams-avro-serde', version:'6.0.0') {
exclude(module: 'log4j-over-slf4j')
}
compile "org.apache.avro:avro:1.10.1"
implementation "org.apache.avro:avro:${avroVersion}"
compileOnly 'org.projectlombok:lombok:1.18.12'
annotationProcessor 'org.projectlombok:lombok:1.18.12'
implementation 'com.amazonaws:aws-java-sdk-s3'
implementation 'org.springframework.boot:spring-boot-starter-web'
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompileOnly 'org.projectlombok:lombok:1.18.12'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.12'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
jar {
manifest {
attributes(
'Main-Class': 'org.test.SpringBootPersistenceApplication'
)
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
}
By excluding spring-boot-starter-web
you did exclude all its dependencies, which are necessary to run a Spring Boot project in a servlet environment. Most notably you did exclude spring-web
, which contains most of the classes you find in the error messages.
As its name suggests spring-boot-starter-web
isn't centered around Tomcat, only its dependency spring-boot-starter-tomcat
is. So you should exclude the latter artifact and include spring-boot-starter-undertow
to pull the necessary Undertow dependencies into the project:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
</parent>
...
<dependencies>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
The last error is probably due to multiple incompatible versions of Spring Boot in your project. To make sure you have compatible versions, set the parent POM of your project to spring-boot-starter-parent
(or spring-boot-dependencies
) and omit specifying a <version>
tag whenever you can. Spring Boot manages the versions of many artifacts (see the complete list of managed dependencies).
Edit: If you are using Gradle your build.gradle should look like this:
plugins {
id 'org.springframework.boot' version '2.4.5'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
...
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
implementation 'org.springframework.boot:spring-boot-starter-undertow'
...
}