Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b51b926
Jax-RS to Spring MVC Recipe
Jan 15, 2026
56fee71
Add license headers and apply formatter
timtebeek Jan 16, 2026
ad2cea2
Refactored for Java 8 Compatability
yasaswigadde Jan 17, 2026
636c894
Merge branch 'main' into main
timtebeek Jan 17, 2026
e1eef05
Refactor - Minor Code Cleanup
yasaswigadde Jan 29, 2026
b2d27c4
Merge branch 'openrewrite:main' into main
yasaswigadde Jan 30, 2026
da5ec28
Merge branch 'openrewrite:main' into main
yasaswigadde Feb 3, 2026
7be4343
Fixing Test Cases - Jax-RS to Spring MVC
yasaswigadde Feb 3, 2026
4a2f617
Merge branch 'main' of https://github.com/yasaswigadde/rewrite-spring
yasaswigadde Feb 3, 2026
fb3b7a8
Minor Refactoring and Reformat
yasaswigadde Feb 10, 2026
87519f7
Merge branch 'openrewrite:main' into main
yasaswigadde Feb 10, 2026
e6936c0
Merge branch 'main' of https://github.com/yasaswigadde/rewrite-spring
yasaswigadde Feb 10, 2026
c371ca4
Regenerate recipes.csv
timtebeek Feb 15, 2026
92c78d3
Polish and regenerate type table
timtebeek Feb 15, 2026
df26dd8
Add missing preconditions
timtebeek Feb 15, 2026
230a440
Merge branch 'main' into main
timtebeek Feb 15, 2026
4799c09
Merge remote-tracking branch 'upstream/main'
yasaswigadde Feb 18, 2026
ae71568
Merge branch 'main' of https://github.com/yasaswigadde/rewrite-spring
yasaswigadde Feb 18, 2026
5ea7348
Merge branch 'main' into main
timtebeek Feb 25, 2026
a9538a0
Merge branch 'main' into main
timtebeek Mar 12, 2026
f044327
Merge branch 'openrewrite:main' into main
yasaswigadde Mar 16, 2026
d65c7ed
Exclude Duplicate Recipe
yasaswigadde Mar 16, 2026
ac579ed
Merge branch 'openrewrite:main' into main
yasaswigadde Mar 16, 2026
5f16d17
Polish documentation
timtebeek Mar 17, 2026
2696a47
Move the ChangeType for Status to getRecipeList
timtebeek Mar 17, 2026
b4906a9
Use `ReplaceConstantWithAnotherConstant`
timtebeek Mar 17, 2026
03547d1
Validate static imports get converted as well
timtebeek Mar 17, 2026
762faa9
Merge branch 'main' into main
timtebeek Mar 24, 2026
a35f0a4
Recreate recipes.csv
timtebeek Mar 24, 2026
1ce2bb2
Polish
timtebeek Mar 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ recipeDependencies {
parserClasspath("io.micrometer:micrometer-observation:1.11.+")
parserClasspath("io.springfox:springfox-swagger2:3.+")
parserClasspath("io.swagger.core.v3:swagger-models:2.+")
parserClasspath("javax.ws.rs:javax.ws.rs-api:2.1.1")
parserClasspath("jakarta.ws.rs:jakarta.ws.rs-api:4.0.0")

testParserClasspath("com.fasterxml.jackson.core:jackson-core:2.20.+")
testParserClasspath("com.nimbusds:nimbus-jose-jwt:9.13")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2026 the original author or authors.
* <p>
* Licensed under the Moderne Source Available License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://docs.moderne.io/licensing/moderne-source-available-license
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.java.spring.mvc;

import lombok.EqualsAndHashCode;
import lombok.Value;
import org.openrewrite.Recipe;
import org.openrewrite.java.ChangeType;
import org.openrewrite.java.ReplaceConstantWithAnotherConstant;

import java.util.ArrayList;
import java.util.List;

@Value
@EqualsAndHashCode(callSuper = false)
public class JaxrsToSpringMvcMediaType extends Recipe {

String displayName = "Migrate JAX-RS MediaType to Spring MVC MediaType";
String description = "Replaces all JAX-RS MediaType with Spring MVC MediaType.";

private static final String SPRING_MEDIA_TYPE = "org.springframework.http.MediaType";

private static final String[] STRING_CONSTANTS = {
"APPLICATION_ATOM_XML",
"APPLICATION_FORM_URLENCODED",
"APPLICATION_JSON",
"APPLICATION_OCTET_STREAM",
"APPLICATION_XHTML_XML",
"APPLICATION_XML",
"MULTIPART_FORM_DATA",
"TEXT_HTML",
"TEXT_PLAIN",
"TEXT_XML"
};

@Override
public List<Recipe> getRecipeList() {
List<Recipe> recipes = new ArrayList<>();
for (String jaxRsType : new String[]{"javax.ws.rs.core.MediaType", "jakarta.ws.rs.core.MediaType"}) {
for (String c : STRING_CONSTANTS) {
// String constants: APPLICATION_JSON → APPLICATION_JSON_VALUE
recipes.add(new ReplaceConstantWithAnotherConstant(
jaxRsType + "." + c, SPRING_MEDIA_TYPE + "." + c + "_VALUE"));
// MediaType constants: APPLICATION_JSON_TYPE → APPLICATION_JSON
recipes.add(new ReplaceConstantWithAnotherConstant(
jaxRsType + "." + c + "_TYPE", SPRING_MEDIA_TYPE + "." + c));
}
// Special: WILDCARD → ALL
recipes.add(new ReplaceConstantWithAnotherConstant(
jaxRsType + ".WILDCARD", SPRING_MEDIA_TYPE + ".ALL_VALUE"));
recipes.add(new ReplaceConstantWithAnotherConstant(
jaxRsType + ".WILDCARD_TYPE", SPRING_MEDIA_TYPE + ".ALL"));
// Change the type itself for any remaining references (variable declarations, parameters, etc.)
recipes.add(new ChangeType(jaxRsType, SPRING_MEDIA_TYPE, true));
}
return recipes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright 2026 the original author or authors.
* <p>
* Licensed under the Moderne Source Available License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://docs.moderne.io/licensing/moderne-source-available-license
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.java.spring.mvc;

import lombok.EqualsAndHashCode;
import lombok.Value;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Preconditions;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.java.ChangeType;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.search.UsesType;
import org.openrewrite.java.tree.Expression;
import org.openrewrite.java.tree.J;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static java.util.Collections.emptyList;
import static java.util.Collections.reverse;
import static java.util.Collections.singletonList;

@Value
@EqualsAndHashCode(callSuper = false)
public class JaxrsToSpringMvcResponseEntity extends Recipe {

String displayName = "Migrate JAX-RS Response to Spring MVC ResponseEntity";
String description = "Replaces all JAX-RS Response with Spring MVC ResponseEntity.";

private static final MethodMatcher BUILD_MATCHER = new MethodMatcher("*.ws.rs.core.Response$ResponseBuilder build()");
private static final MethodMatcher OK_MATCHER = new MethodMatcher("*.ws.rs.core.Response ok(..)");
private static final MethodMatcher ENTITY_MATCHER = new MethodMatcher("*.ws.rs.core.Response$ResponseBuilder entity(..)");

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(new UsesType<>("*.ws.rs.core.Response", true), new JavaIsoVisitor<ExecutionContext>() {
@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation methodInv, ExecutionContext ctx) {
if (BUILD_MATCHER.matches(methodInv)) {
List<J.MethodInvocation> chain = new ArrayList<>();
J.MethodInvocation current = methodInv;
while (current != null) {
chain.add(current);
current = current.getSelect() instanceof J.MethodInvocation ? (J.MethodInvocation) current.getSelect() : null;
}
reverse(chain);
Expression body = null;
J.MethodInvocation rebuilt = chain.get(0);
if (OK_MATCHER.matches(rebuilt) && !rebuilt.getArguments().isEmpty() && !(rebuilt.getArguments().get(0) instanceof J.Empty)) {
if (chain.size() > 2) {
body = rebuilt.getArguments().get(0);
rebuilt = rebuilt.withArguments(emptyList());
} else {
return rebuilt.withPrefix(methodInv.getPrefix());
}
} else if ("serverError".equals(rebuilt.getSimpleName())) {
rebuilt = rebuilt.withName(rebuilt.getName().withSimpleName("internalServerError"));
}
for (J.MethodInvocation c : chain.subList(1, chain.size())) {
if (BUILD_MATCHER.matches(c) && body != null) {
c = c.withName(c.getName().withSimpleName("body")).withArguments(singletonList(body));
}
if (ENTITY_MATCHER.matches(c)) {
body = c.getArguments().get(0);
} else {
rebuilt = c.withSelect(rebuilt);
}
}
return rebuilt;
}
return super.visitMethodInvocation(methodInv, ctx);
}
});
}

@Override
public List<Recipe> getRecipeList() {
return Arrays.asList(
new ChangeType("javax.ws.rs.core.Response.Status", "org.springframework.http.HttpStatus", true),
new ChangeType("jakarta.ws.rs.core.Response.Status", "org.springframework.http.HttpStatus", true),
new ChangeType("javax.ws.rs.core.Response.ResponseBuilder", "org.springframework.http.ResponseEntity.BodyBuilder", true),
new ChangeType("jakarta.ws.rs.core.Response.ResponseBuilder", "org.springframework.http.ResponseEntity.BodyBuilder", true),
new ChangeType("javax.ws.rs.core.Response", "org.springframework.http.ResponseEntity", true),
new ChangeType("jakarta.ws.rs.core.Response", "org.springframework.http.ResponseEntity", true));
}
}
20 changes: 20 additions & 0 deletions src/main/java/org/openrewrite/java/spring/mvc/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright 2026 the original author or authors.
* <p>
* Licensed under the Moderne Source Available License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://docs.moderne.io/licensing/moderne-source-available-license
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@NullMarked @NonNullFields
package org.openrewrite.java.spring.mvc;

import org.jspecify.annotations.NullMarked;
import org.openrewrite.internal.lang.NonNullFields;
Binary file modified src/main/resources/META-INF/rewrite/classpath.tsv.gz
Binary file not shown.
4 changes: 3 additions & 1 deletion src/main/resources/META-INF/rewrite/recipes.csv
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot2.Sp
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot2.UpgradeSpringBoot_2_7,Migrate to Spring Boot 2.7,Upgrade to Spring Boot 2.7.,1196,,,,Spring Boot 2.x,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]"
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot2.search.CustomizingJooqDefaultConfiguration,In Spring Boot 2.5 a `DefaultConfigurationCustomizer` can now be used in favour of defining one or more `*Provider` beans,"To streamline the customization of jOOQ’s `DefaultConfiguration`, a bean that implements `DefaultConfigurationCustomizer` can now be defined. This customizer callback should be used in favour of defining one or more `*Provider` beans, the support for which has now been deprecated. See [Spring Boot 2.5 jOOQ customization](https://docs.spring.io/spring-boot/docs/2.5.x/reference/htmlsingle/#features.sql.jooq.customizing).",1,,,Search,Spring Boot 2.x,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot2.search.IntegrationSchedulerPoolRecipe,Integration scheduler pool size,"Spring Integration now reuses an available `TaskScheduler` rather than configuring its own. In a typical application setup relying on the auto-configuration, this means that Spring Integration uses the auto-configured task scheduler that has a pool size of 1. To restore Spring Integration’s default of 10 threads, use the `spring.task.scheduling.pool.size` property.",1,,,Search,Spring Boot 2.x,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot2.search.LoggingShutdownHooks,Applications using logging shutdown hooks,"Spring Boot registers a logging shutdown hook by default for JAR-based applications to ensure that logging resources are released when the JVM exits. If your application is deployed as a WAR then the shutdown hook is not registered since the servlet container usually handles logging concerns.
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot2.search.LoggingShutdownHooks,Applications using logging shutdown hooks,"Spring Boot registers a logging shutdown hook by default for JAR-based applications to ensure that logging resources are released when the JVM exits. If your application is deployed as a WAR then the shutdown hook is not registered since the servlet container usually handles logging concerns.

Most applications will want the shutdown hook. However, if your application has complex context hierarchies, then you may need to disable it. You can use the `logging.register-shutdown-hook` property to do that.",1,,,Search,Spring Boot 2.x,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.boot2.search.FindUpgradeRequirementsSpringBoot_2_5,Find patterns that require updating for Spring Boot 2.5,Looks for a series of patterns that have not yet had auto-remediation recipes developed for.,6,,,Search,Spring Boot 2.x,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
Expand Down Expand Up @@ -304,6 +304,8 @@ maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.opentele
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.opentelemetry.MigrateNewRelicToOpenTelemetry,Migrate New Relic Agent to OpenTelemetry,Migrate from New Relic Java Agent annotations to OpenTelemetry annotations. Replace @Trace annotations with @WithSpan annotations.,4,,,,Opentelemetry,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.opentelemetry.MigrateDatadogToOpenTelemetry,Migrate Datadog tracing to OpenTelemetry,Migrate from Datadog Java tracing annotations to OpenTelemetry annotations. Replace Datadog @Trace annotations with @WithSpan annotations.,15,,,,Opentelemetry,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.security.SpringSecurityBestPractices,Spring security best practices,"Applies security best practices to Spring applications, including TLS for database and message broker connections.",3,,,,Security,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.mvc.JaxrsToSpringMvcMediaType,Migrate JAX-RS MediaType to Spring MVC MediaType,Replaces all JAX-RS MediaType with Spring MVC MediaType.,47,,,,Mvc,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.spring.mvc.JaxrsToSpringMvcResponseEntity,Migrate JAX-RS Response to Spring MVC ResponseEntity,Replaces all JAX-RS Response with Spring MVC ResponseEntity.,7,,,,Mvc,Spring,Java,,,,,Recipes for upgrading and patching [Spring](https://spring.io/) applications.,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.flyway.MigrateToFlyway10,Migrate to Flyway 10,Migrate to Flyway 10. See details at [Flyway V10 has landed](https://documentation.red-gate.com/fd/flyway-v10-has-landed-222627771.html).,9,,,,,Flyway,Java,,,,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.flyway.AddFlywayModulePostgreSQL,Add missing Flyway module for PostgreSQL,"Database modules for Flyway 10 have been split out in to separate modules for maintainability. Add the `flyway-database-postgresql` dependency if you are using PostgreSQL with Flyway 10, as detailed on https://github.com/flyway/flyway/issues/3780.",2,,,,,Flyway,Java,,,,,,Basic building blocks for transforming Java code.,,
maven,org.openrewrite.recipe:rewrite-spring,org.openrewrite.java.flyway.AddFlywayModuleMySQL,Add missing Flyway module for MySQL,"Database modules for Flyway 10 have been split out into separate modules for maintainability. Add the `flyway-mysql` dependency if you are using MySQL with Flyway 10, as detailed on https://github.com/flyway/flyway/issues/3780.",2,,,,,Flyway,Java,,,,,,Basic building blocks for transforming Java code.,,
Expand Down
Loading
Loading