Skip to main content

8.89.0 release (2026-08-12)

Total recipe count: 4118

info

This changelog only shows what recipes have been added, removed, or changed. OpenRewrite may do releases that do not include these types of changes. To see these changes, please go to the releases page.

Corresponding CLI version

  • CLI version 4.5.2

Removed Artifacts

  • rewrite-go

New Recipes

  • org.openrewrite.cucumber.jvm.CollapseCucumberOptionsTags: Cucumber-JVM 6.0.0 narrowed @CucumberOptions#tags from String[] to a single String. The elements of the array were combined with and, such that tags = {"@a", "@b"} becomes tags = "(@a) and (@b)".
  • org.openrewrite.cucumber.jvm.CucumberApiToIoCucumber: Cucumber-JVM 5.0.0 moved the cucumber.api types to io.cucumber, but not as a single package rename: types were spread over io.cucumber.java, io.cucumber.junit, io.cucumber.testng, io.cucumber.plugin and io.cucumber.core. This recipe maps each cucumber.api type onto the package it actually moved to.
  • org.openrewrite.cucumber.jvm.CucumberJava8TypeDefinitionToCucumberJava: Replace LambdaGlue DataTableType, ParameterType, DocStringType and Default*Transformer registrations with cucumber-java annotated methods with the same body.
  • org.openrewrite.cucumber.jvm.CucumberOptionsPropertyToIndividualProperties: Cucumber-JVM 6.0.0 removed cucumber.options, which passed command line options as a single string, in favour of an individual property per option. This recipe splits the property into its replacements, both in .properties files and in Maven Surefire or Failsafe systemPropertyVariables. Options without a property equivalent, such as --threads, have no migration path; there the property is left untouched, with a TODO comment added above it.
  • org.openrewrite.cucumber.jvm.CucumberOptionsToTestNgCucumberOptions: Replace cucumber.api.CucumberOptions with the TestNG variant in source files that run through a TestNG runner.
  • org.openrewrite.cucumber.jvm.DropStrictOption: Cucumber-JVM 7.0.0 removed the strict option, as scenarios are now always executed in strict mode.
  • org.openrewrite.cucumber.jvm.DropTimeoutAttribute: Cucumber-JVM 5.0.0 removed the timeout attribute from step definition and hook annotations, in favor of asserting on the duration from within the step definition itself.
  • org.openrewrite.cucumber.jvm.FixTeluguLanguageCode: Cucumber-JVM 7.0.0 removed the incorrect ISO 639-1 code tl for Telugu, which is now consistently te.
  • org.openrewrite.cucumber.jvm.MigrateCucumberJava8ScenarioAndStatus: Scenario and Status are the only io.cucumber.java8 types with an io.cucumber.java counterpart; the language interfaces such as En and the LambdaGlue body types have none, so renaming the package wholesale would point whatever the migration could not convert at a type that does not exist. Where such a body type does survive it also still expects the cucumber-java8 Scenario, as in an anonymous HookBody, so leave both types be until the last of the lambda glue is gone.
  • org.openrewrite.cucumber.jvm.MigrateRuntimeOptionsBuilder: Cucumber-JVM 7.0.0 dropped RuntimeOptionsBuilder.addDefaultFormatterIfAbsent(), as no formatter is added implicitly any more, and renamed addDefaultSummaryPrinterIfAbsent() to addDefaultSummaryPrinterIfNotDisabled(), which defers to the new setNoSummary(). Mirrors the change Cucumber-JVM made to its own io.cucumber.core.cli.Main, which projects that run Cucumber programmatically tend to have copied.
  • org.openrewrite.cucumber.jvm.MigrateScenarioWriteAndEmbed: Cucumber-JVM 6.0.0 removed Scenario.write(String) and Scenario.embed(byte[], String) along with Scenario.embed(byte[], String, String), in favor of Scenario.log(String) and Scenario.attach(byte[], String, String). The two argument embed emitted an attachment without a name, which attach expresses as a null name.
  • org.openrewrite.cucumber.jvm.RemoveCucumberJava8Dependency: Removes the cucumber-java8 dependency where every LambdaGlue call migrates to cucumber-java, and retains it wherever one is left behind. Read from the glue as it stands before the migration, as what the migration leaves behind only becomes visible to a scanning recipe in the cycle after, which a build tool run never reaches. Glue left anywhere retains the dependency everywhere, an unused dependency being the one outcome here that still compiles.
  • org.openrewrite.cucumber.jvm.TypeRegistryConfigurerToAnnotations: Cucumber-JVM 7.0.0 removed TypeRegistryConfigurer; replace implementations with @ParameterType, @DataTableType, @DocStringType and @Default*Transformer annotated glue methods. Classes whose configureTypeRegistry method cannot be converted in full are left untouched, with a TODO comment added above the registration that could not be converted.
  • org.openrewrite.cucumber.jvm.UpgradeCucumber6x: Upgrade to Cucumber-JVM 6.x from any previous version.
  • org.openrewrite.gradle.gradle9.MigrateIsolatedProjectsProperties: Gradle 9.7 promotes the Isolated Projects feature flags out of the unsafe namespace and deprecates the legacy property names. org.gradle.unsafe.isolated-projects becomes org.gradle.isolated-projects, org.gradle.unsafe.isolated-projects.diagnostics becomes org.gradle.isolated-projects.diagnostics and org.gradle.unsafe.isolated-projects.dangerously-ignore-problems becomes org.gradle.isolated-projects.dangerously-ignore-problems. The legacy names still work as aliases, but will be removed in a future release.
  • org.openrewrite.gradle.gradle9.RemoveExitEnvironmentVar: Gradle 9.5 reworked the Windows start script template so that CreateStartScripts.getExitEnvironmentVar() and setExitEnvironmentVar(String) no longer affect the generated scripts, and Gradle 9.6 deprecates them. This recipe removes exitEnvironmentVar configuration from CreateStartScripts task configuration, and drops a configuration block that is left empty as a result. Custom start script templates that still reference the variable need to be updated by hand.
  • org.openrewrite.gradle.gradle9.RemovePmdTargetJdk: Gradle 9.6 deprecates Pmd.getTargetJdk(), PmdExtension.getTargetJdk(), their setters, and the TargetJdk enum, with no replacement: PMD selects a parser based on the source set's Java version instead. This recipe removes targetJdk configuration from pmd { } extension blocks and from Pmd task configuration, and drops a configuration block that is left empty as a result.
  • org.openrewrite.gradle.gradle9.UseRepositoryHandlerActionOverloads: Gradle 9.6 deprecates RepositoryHandler.flatDir(Map) and RepositoryHandler.mavenCentral(Map) in favor of the Action overloads that configure the repository through its own API. This recipe rewrites flatDir dirs: 'libs' to flatDir { dirs 'libs' } and mavenCentral name: 'central2' to mavenCentral { name = 'central2' }. Map notation carrying keys with no straightforward equivalent, such as the separately deprecated artifactUrls, is left alone.
  • org.openrewrite.gradle.spring.AddParametersCompilerFlagToGradle: Adds options.compilerArgs.add("-parameters") to JavaCompile tasks and, when the Kotlin Gradle Plugin version can be determined from this file's plugins {} block, the matching javaParameters flag (compilerOptions.javaParameters on 1.8+, kotlinOptions.javaParameters on older versions) to Kotlin compile tasks. Spring uses parameter name retention for dependency injection. Projects using the Spring Boot Gradle plugin already have both flags configured and are not modified. When the Kotlin plugin's version can't be determined from this file (version catalogs, convention plugins, buildscript classpath declarations) the Kotlin flag is left alone rather than risk emitting a form the applied plugin doesn't support.
  • org.openrewrite.hibernate.validator.HibernateValidator_9_1: This recipe will apply changes commonly needed when migrating to Hibernate Validator 9.1.x.
  • org.openrewrite.hibernate.validator.MoveValidToContainerElement: Hibernate Validator 9.1 deprecates requesting cascaded validation at the container level, and warns while building the metadata for declarations such as @Valid List<Order> orders. Rewrites those to the type argument form List<@Valid Order> orders that has been available since Bean Validation 2.0. The element type argument is annotated for Iterable and Optional containers, and the value type argument for Map, matching where the built-in value extractors cascade to. @Valid on anything other than one of those containers is left alone, as are wildcard, raw, qualified and array type arguments.
  • org.openrewrite.java.jackson.FindJsonSetterNullsAsEmptyCollections: Find Map and Collection fields that carry @JsonSetter(nulls = Nulls.AS_EMPTY), are initialized with an empty collection, and are no longer hidden by @JsonIgnore on the field or its getter, or by a class level @JsonIgnoreProperties. In rewrite-jackson 1.17.0 through 1.28.0 the Jackson 2 to 3 migration replaced @JsonIgnore with @JsonSetter(nulls = Nulls.AS_EMPTY) on exactly these fields, which starts serializing properties that were deliberately hidden wherever the field is otherwise visible, such as through a getter. Run this recipe to audit repositories migrated with those versions; every match that should stay out of the JSON output needs @JsonIgnore restored, which the addJsonIgnore option does for you.
  • org.openrewrite.java.jackson.RemoveDeadJacksonThrows: In Jackson 3 the exception hierarchy is rerooted under JacksonException, which extends RuntimeException. Any surviving throws for a Jackson exception type is dead: callers are not required to handle it, and the declaration misleads readers into thinking checked-exception handling is needed. Removes throws for JacksonException and its subtypes (e.g. DatabindException) from both methods and constructors. Assumes the Jackson 2 to 3 package changes have already run, so all Jackson exception types live under tools.jackson. Does not touch throws IOException (still a checked exception) or non-Jackson exception types.
  • org.openrewrite.java.migrate.BouncyCastleDerStringGetInstanceReturnType: In Bouncy Castle 1.71 the getInstance(..) methods on the DER*String ASN.1 types were pulled up to their ASN1*String supertypes, widening their return type. The call itself still compiles, as static methods are inherited, but assigning the result to a DER*String variable or field no longer does. This recipe widens those declared types to the matching ASN1*String, which compiles against both the -jdk15on and -jdk18on artifacts, and can therefore safely be applied ahead of the upgrade.
  • org.openrewrite.java.migrate.BouncyCastleSphincsPlusToPqcLegacy: Bouncy Castle 1.78 moved the pre-standardization SPHINCS+ implementation from org.bouncycastle.pqc.crypto.sphincsplus to org.bouncycastle.pqc.legacy.sphincsplus, to free up the original package for the FIPS 205 SLH-DSA implementation. All types moved unchanged, so this is a straight package rename.
  • org.openrewrite.java.recipes.ClasspathArgumentsOnePerLine: Put each argument of classpath and classpathFromResources on its own line when there are four or more arguments, such that classpath entries are easier to read, and adding or removing an entry shows up as a single line change.
  • org.openrewrite.java.spring.batch.MigrateToChunkOrientedStepBuilder: Spring Batch 6.0 deprecates StepBuilder.chunk(int, PlatformTransactionManager) in favor of a new chunk-oriented model, where the transaction manager is configured through ChunkOrientedStepBuilder.transactionManager(PlatformTransactionManager). Replaces chunk(chunkSize, transactionManager) with chunk(chunkSize).transactionManager(transactionManager), but only where every other method in the builder chain has an equivalent on ChunkOrientedStepBuilder. The new model dropped the Spring Retry based chunk and retry APIs without a drop-in replacement, so chains calling backOffPolicy, retryPolicy, retryContextCache, keyGenerator, noRetry, noRollback, noSkip, processorNonTransactional, readerIsTransactionalQueue, chunkOperations, stepOperations, exceptionHandler, listener(RetryListener), chunk(CompletionPolicy, PlatformTransactionManager) or taskExecutor(TaskExecutor) with a non-async executor are left untouched, and remain a manual migration step. See the Spring Batch 6.0 migration guide.
  • org.openrewrite.java.spring.boot4.AddAutoConfigureMockMvc: Adds @AutoConfigureMockMvc to @SpringBootTest classes that use MockMvc because Spring Boot 4 no longer auto-configures this bean.
  • org.openrewrite.maven.RemovePluginGoal: Removes a goal from a Maven plugin wherever it is declared: directly under a <plugin>, inside <executions>, and within <build>, <pluginManagement>, or <profiles>. If removing the goal leaves an <execution> with no remaining goals, the execution is removed. If all executions are removed, the <executions> element is also removed.
  • org.openrewrite.maven.UpgradePluginsForMaven4: Upgrades plugins that are known to fail under Maven 4, using the minimum working versions applied by Apache's own mvnup upgrade --plugins as a floor while accepting any newer release within the same major version. Plugins already at or above that floor are upgraded to the latest such release; plugins that declare no version are left alone. quarkus-maven-plugin is held at its floor, as its version is coupled to the Quarkus platform BOM. Plugin dependencies known to break Maven 4 are upgraded as well.
  • org.openrewrite.maven.spring.AddParametersCompilerFlagToMaven: Sets the maven.compiler.parameters property to true and, when kotlin-maven-plugin is declared, configures its javaParameters option. Spring uses parameter name retention for dependency injection. Projects whose effective build already decides parameter name retention — through their own configuration or any parent such as spring-boot-starter-parent — are not modified.

Removed Recipes

  • org.openrewrite.java.jackson.ReplaceJsonIgnoreWithJsonSetter: In Jackson 3, @JsonIgnore on fields initialized with empty collections causes the field value to become null instead of maintaining the empty collection. This recipe replaces @JsonIgnore with @JsonSetter(nulls = Nulls.AS_EMPTY) on Map and Collection fields that have an empty collection initializer.
  • org.openrewrite.java.spring.ws.MigrateAxiomToSaaj: Migrate from Apache Axiom SOAP message handling to SAAJ (SOAP with Attachments API for Java). Spring WS 4.0.x removed support for Apache Axiom because Axiom did not support Jakarta EE at the time. This recipe changes Axiom types to their SAAJ equivalents.
  • org.openrewrite.java.spring.ws.UpgradeSpringWs_4_0: Migrate applications to Spring WS 4.0. This recipe handles the removal of Apache Axiom support in Spring WS 4.0.x by migrating Axiom-based SOAP message handling to SAAJ (SOAP with Attachments API for Java). Note that Spring WS 4.1+ restores Axiom support if upgrading to that version is preferred.

Changed Recipes