We have successfully completed a JDK 21 upgrade from SAP Commerce version 2205 (previously on JDK 17). Sharing our learnings and resolutions encountered during the upgrade which may be helpful for similar implementations.
SAP has provided customized OpenRewrite recipes to automate static code migrations. These greatly reduce manual effort.
👉Refer to SAP Note #3618495 (OpenRewrite automation guide) for detailed execution steps.
Outcome: Automates majority of standard class and package-level updates.
Some library-level changes require manual fixes such as: - Assertion - Common.lang - RFCConstantsjakarta.jms
Action: Update imports and usage based on the upgraded libraries.
Several issues were observed during server startup and platform initialization. Details and solutions below.
Error:
Context initialization failed - Error creating bean with name 'org.springframework.security.filterChains'
NoSuchBeanDefinitionException: No bean named 'mvcHandlerMappingIntrospector' available.
Root Cause: Spring Security 6.x requires a shared ApplicationContext with Spring MVC when using MvcRequestMatcher.
Resolution: Update web.xml to ensure MVC config loads into the main context instead of DispatcherServlet.
➡ Added MVC configuration into global context
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/config/customextension-web-app-config.xml
WEB-INF/config/customextension-spring-mvc-config.xml
</param-value>
</context-param>
➡ Cleared separate servlet context
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
Outcome: Application started successfully.
Error:
PatternParseException: No more pattern data allowed after {*...} or ** pattern element
Root Cause: Legacy wildcards like /**/something, /**, {*path} are not supported under PathPatternParser.
Solution: Switch back to AntPathMatcher in spring-mvc-config.xml.
<bean id="pathMatcher" class="org.springframework.util.AntPathMatcher" />
<mvc:annotation-driven>
<mvc:path-matching path-matcher="pathMatcher"/>
</mvc:annotation-driven>
Outcome: Legacy mappings restored, storefront initialized.
Error:
IllegalArgumentException: expressionString cannot be empty
Root Cause: Spring Security 6 does not allow intercept-url without an access expression.
Fix: Add default authorization
<security:intercept-url pattern="/**" access="permitAll()" />
Outcome: Security filter chain initialized successfully.
Error: Deprecated password encoder triggered failure.
PBKDF2WithHmacSHA1SaltedPasswordEncoder is deprecated
Fix: Temporarily allow legacy password encoding
legacy.password.encoding.enabled=true
🔄Revert setting post-update if needed for backward compatibility.
Error:
IllegalStateException: Ambiguous handler methods mapped for '/'
Root Cause: Two controllers mapped to /.
Solution: Update default controller fallback
@RequestMapping(value = "/**", method = RequestMethod.GET)
Error: Missing command model attribute.
Neither BindingResult nor plain target object for bean name 'command'
Resolution: Add required model attributes
@ModelAttribute("command")
public LoginForm commandLoginForm() { return new LoginForm(); }
Error: Missing ExpressionHandler
No visible WebSecurityExpressionHandler instance could be found
Fix:
<bean id="webSecurityExpressionHandler"
class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
Solution: Add explicit URL mappings where needed.
@RequestMapping("/search/")
@GetMapping("/quote-requests/")
JDK 21 + Spring 6 migration introduces strict compatibility constraints requiring updates in: - Spring MVC URL mapping - Spring Security configuration rules - Application context structure - JSP model binding - Password encoding framework
The above resolutions enabled successful storefront startup and full system initialization.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 20 | |
| 4 | |
| 2 | |
| 2 | |
| 2 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |