Updating to Tomcat 11, Spring Boot 3.1 and Java 17
I'm updating some projects to Tomcat 11, Spring Boot 3.1 and Java 17. Below are some of the breakages I encountered, and the solutions.
Update Java in pom.xml
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>17</source> <target>17</target> </configuration> </plugin> </plugins> </build>
Update Spring
<groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> - <version>2.x.x</version> + <version>3.1.4</version>
Replace javax with jakarta
Do a search and replace across all files:
- javax.servlet -> jakarta.servlet
- javax.jms -> jakarta.jms
Web Security
There were quite a lot of changes in the way web security is done.
-@EnableGlobalMethodSecurity(prePostEnabled = true) +@EnableMethodSecurity
-public class WebSecurityConfig extends WebSecurityConfigurerAdapter { +public class WebSecurityConfig {
The following shows the before and after:
Before
@Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests() .antMatchers(NO_AUTHENTICATION).permitAll() .antMatchers(NO_REMEMBERME).fullyAuthenticated() .anyRequest().authenticated() .and().formLogin().loginPage(LOGIN_PAGE).loginProcessingUrl(LOGIN_PAGE).permitAll() .and().headers().httpStrictTransportSecurity().disable() .and().logout().invalidateHttpSession(true).permitAll() .and().rememberMe().tokenRepository(persistentTokenRepository()).userDetailsService(userDetailsService).key(TOKEN_KEY) .tokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(365)); }
After
@Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { return http .csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests(authorizeHttpRequests -> authorizeHttpRequests .requestMatchers(antMatcher(NO_AUTHENTICATION)).permitAll() .requestMatchers(antMatcher(NO_REMEMBERME)).fullyAuthenticated() .anyRequest().authenticated()) .formLogin(formLogin -> formLogin .loginPage(LOGIN_PAGE).loginProcessingUrl(LOGIN_PAGE).permitAll()) .headers(headers -> headers .httpStrictTransportSecurity(HeadersConfigurer.HstsConfig::disable)) .logout(logout -> logout .invalidateHttpSession(true).permitAll()) .rememberMe(rememberMe -> rememberMe .tokenRepository(persistentTokenRepository()) .userDetailsService(userDetailsService).key(TOKEN_KEY) .tokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(365))) .build(); }
You can get the idea of the other sort of changes needed.
Wiremock
java.lang.NoClassDefFoundError: javax/servlet/DispatcherTypeUpdate to Wiremock 3.2.0
Feign
No qualifying bean of type 'org.springframework.cloud.openfeign.FeignContext' availableUpdate to a later version - 2022.0.3 got rid of this.
The configuration properties changed from
feign.client.xxxto
spring.cloud.openfeign.client.xxx
Web MVC trailing slash
Trailing slashes are now not matched. /foo/ will not match @GetMapping("/foo"). To get the old behavior back, use the following
@Configuration public class WebConfiguration implements WebMvcConfigurer { @Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setUseTrailingSlashMatch(true); } }
Test Containers
java.lang.NoClassDefFoundError: org/testcontainers/containers/wait/LogMessageWaitStrategyUpdate to 1.18.3 or later
Thymeleaf
Prevent a warning message:
-<footer th:replace="fragments/footer.html :: footer"></footer> +<footer th:replace="~{fragments/footer.html :: footer}"></footer>