`ReplaceGlobalMethodSecurityWithMethodSecurity` swaps the annotation on a `GlobalMethodSecurityConfiguration` subclass, and the context fails to start: "EnableGlobalMethodSecurity is required"
Maintainers usually reply within 1 day
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 68/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- java, spring, spring-boot
Research direction
Start with ReplaceGlobalMethodSecurityWithMethodSecurity.java and its annotation-only visitor, then inspect the Spring Security migration guide and the reproducer’s MethodSecurityConfig superclass and createExpressionHandler() override. Run the minimal Boot 2.7.18 reproducer through the upgrade recipe, then test the migrated configuration on Boot 3.5.16. Done means the recipe output starts the application context without the reported exception.
Written by the indexing model from the issue text.
Description
What version of OpenRewrite are you using?
- rewrite-maven-plugin 6.46.1
- rewrite-spring 6.37.1
- Maven 3.9.12, JDK 17.0.13
These are the latest versions on Maven Central. I could not test rewrite-spring 6.41.0 from the Code Genome Project. ReplaceGlobalMethodSecurityWithMethodSecurity.java has not changed since 2026-04-29, before 6.37.1, so v6.41.0 and main have the same annotation-only visitor: https://github.com/openrewrite/rewrite-spring/blob/main/src/main/java/org/openrewrite/java/spring/security5/ReplaceGlobalMethodSecurityWithMethodSecurity.java
How are you running OpenRewrite?
Maven plugin from the command line, single-module project, no pom changes:
mvn -B org.openrewrite.maven:rewrite-maven-plugin:6.46.1:run \
-Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-spring:6.37.1 \
-Drewrite.activeRecipes=org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_5
Is your project public? If so, can you share a link to it?
Found while upgrading https://github.com/gtiwari333/spring-boot-blog-app at commit 095e50d8dcb9e01dae519dd9f7b5d394d39811c6 (src/main/java/gt/app/config/security/MethodSecurityConfig.java). The minimal reproducer is a Spring Boot 2.7.18 project with spring-boot-starter-security, the class below, and an empty @SpringBootTest.
What is the smallest, simplest way to reproduce the problem?
package com.example;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new DefaultMethodSecurityExpressionHandler();
}
}
Before the recipe, mvn test passes on Boot 2.7.18 (contextLoads).
What did you expect to see?
One of two things:
- Leave
@EnableGlobalMethodSecurityin place when the annotated class extendsGlobalMethodSecurityConfiguration. Both are deprecated but still present in Spring Security 6.5, so the app keeps working. - Or do the full migration: remove
extends GlobalMethodSecurityConfigurationand turn thecreateExpressionHandler()override into a@Bean MethodSecurityExpressionHandler, as the Spring Security 5.8 migration guide describes.
What did you see instead?
The recipe (UpgradeSpringSecurity_5_8 -> ReplaceGlobalMethodSecurityWithMethodSecurity) changes only the annotation and leaves the superclass in place:
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
@Configuration
-@EnableGlobalMethodSecurity(prePostEnabled = true)
+@EnableMethodSecurity
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
The code compiles. On Boot 3.5.16 / Spring Security 6.5.11 the application context no longer starts, because GlobalMethodSecurityConfiguration reads its settings from @EnableGlobalMethodSecurity:
java.lang.IllegalStateException: Failed to load ApplicationContext ...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'methodSecurityMetadataSource' defined in class path resource [com/example/MethodSecurityConfig.class]: ... Factory method 'methodSecurityMetadataSource' threw exception with message: org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity is required
Caused by: java.lang.IllegalArgumentException: org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity is required
at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.enableMethodSecurity(GlobalMethodSecurityConfiguration.java:465)
at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.prePostEnabled(GlobalMethodSecurityConfiguration.java:445)
at org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration.methodSecurityMetadataSource(GlobalMethodSecurityConfiguration.java:358)
The recipe's visitor only matches the annotation. It never checks the enclosing class's supertype.
What is the full stack trace of any errors you encountered?
See above. The full log is available if useful. There is no recipe error; the failure happens at application startup.
Are you interested in contributing a fix to OpenRewrite?
Not at the moment.
Found with an upgrade benchmark: https://github.com/imashishsharma/stratigraph/tree/main/bench/upgrade-gap
- Dominant language
- Java
- Stars
- 409
- Forks
- 160
- Avg merge
- 8h 37m
- Merged PRs (30d)
- 73
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from openrewrite/rewrite-spring
-
Recipe quality triage: remaining fixes, wiring and polish (A1–L4)Possibly taken @DavJaveiro claimed this 1 day ago. Opengood first issue
Difficulty 5/5 Over a week Newbie friendliness 35/100
openrewrite/rewrite-spring#1201 · 17 comments ·
Maintainers usually reply within 1 day
-
`UpgradeSpringBoot_3_4` keeps `htmlunit-driver` (HtmlUnit 2) and pins it to 4.13.0; MockMvc HtmlUnit tests then fail with `NoClassDefFoundError: org/htmlunit/WebConnection`May be free again @OnicarN claimed this 20 days ago, and no pull request is open. Open
Difficulty 3/5 1-2 days Newbie friendliness 58/100
openrewrite/rewrite-spring#1195 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 67/100
openrewrite/rewrite-spring#1159 · 1 reaction ·
Maintainers usually reply within 1 day
-
Optimize the PreciseBeanType recipe and add type exclusion functionalityMay be free again @Akhil-1527 claimed this 46 days ago, and no pull request is open. Openenhancement
Difficulty 4/5 3-5 days Newbie friendliness 45/100
openrewrite/rewrite-spring#1148 · 3 comments ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
openrewrite/rewrite-spring#1147 · 1 reaction ·
Maintainers usually reply within 1 day
All issues in openrewrite/rewrite-spring
Similar issues
-
Four TestConstraintBasedAlgorithm tests pass when nothing is thrownPossibly taken @sharanggupta claimed this today. Open
Difficulty 1/5 1-3 hours Newbie friendliness 85/100
-
bug documentation good first issue help wanted priority low size XS
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
martin-francois/symphony-trello#1351 ·
Maintainers usually reply within 1 day
-
Add test coverage for ConvertUtil.parseDate() with NULL inputPossibly taken @mirajul-mollah7 claimed this today. Open
Difficulty 1/5 Under an hour Newbie friendliness 78/100
eclipse-sw360/sw360#4792 · 1 comment ·
Maintainers usually reply within 3 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
aws/aws-emulator#30 · 1 comment ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 4 days