diff --git a/src/main/java/org/openrewrite/java/migrate/AddMockitoJavaAgentToMavenSurefirePlugin.java b/src/main/java/org/openrewrite/java/migrate/AddMockitoJavaAgentToMavenSurefirePlugin.java new file mode 100644 index 0000000000..824047375c --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/AddMockitoJavaAgentToMavenSurefirePlugin.java @@ -0,0 +1,185 @@ +/* + * Copyright 2026 the original author or authors. + *

+ * 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 + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * 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.migrate; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.intellij.lang.annotations.Language; +import org.openrewrite.ExecutionContext; +import org.openrewrite.Preconditions; +import org.openrewrite.Recipe; +import org.openrewrite.TreeVisitor; +import org.openrewrite.internal.ListUtils; +import org.openrewrite.maven.AddPlugin; +import org.openrewrite.maven.AddPropertyVisitor; +import org.openrewrite.maven.ChangePluginExecutions; +import org.openrewrite.maven.MavenIsoVisitor; +import org.openrewrite.maven.search.DependencyInsight; +import org.openrewrite.maven.search.FindPlugin; +import org.openrewrite.maven.tree.Plugin; +import org.openrewrite.maven.tree.ResolvedDependency; +import org.openrewrite.maven.tree.Scope; +import org.openrewrite.semver.LatestRelease; +import org.openrewrite.xml.AddOrUpdateChildTag; +import org.openrewrite.xml.AddToTagVisitor; +import org.openrewrite.xml.XPathMatcher; +import org.openrewrite.xml.XmlIsoVisitor; +import org.openrewrite.xml.tree.Content; +import org.openrewrite.xml.tree.Xml; + +import java.util.List; +import java.util.Optional; + +import static java.util.Collections.emptyList; + +public class AddMockitoJavaAgentToMavenSurefirePlugin extends Recipe { + + private static final String MAVEN_PLUGINS_GROUP_ID = "org.apache.maven.plugins"; + private static final String MAVEN_SUREFIRE_PLUGIN_ARTIFACT_ID = "maven-surefire-plugin"; + + @Language("xpath") + private static final String MAVEN_DEPENDENCY_PLUGIN_EXECUTION_MATCHER = "/project/build/plugins/plugin[artifactId='maven-dependency-plugin']/executions/execution"; + + @Language("xml") + private static final String MAVEN_DEPENDENCY_PLUGIN_PROPERTIES_GOAL = "properties"; + + @Language("xml") + private static final String MAVEN_DEPENDENCY_PLUGIN_EXECUTION_TAG = ""+ MAVEN_DEPENDENCY_PLUGIN_PROPERTIES_GOAL + ""; + + @Getter + final String displayName = "Add Mockito Java Agent to Maven Surefire Plugin"; + + @Getter + final String description = "Adds required configuration to specifically enable the Mockito/Bytebuddy Java agent in the Maven Surefire plugin for Java 21 compatibility."; + + @Override + public TreeVisitor getVisitor() { + return Preconditions.check(new DependencyInsight("org.mockito", "mockito-core", "test", null, false), new MavenIsoVisitor() { + private final String CONFIGURATION_TAG_TEMPLATE = "%s"; + + private String getArgLineJavaAgentArgument() { + String mockitoCoreVersion = getResolutionResult().getDependencies().getOrDefault(Scope.Test, emptyList()).stream() + .filter(dependency -> dependency.getGroupId().equals("org.mockito") && dependency.getArtifactId() + .equals("mockito-core")).findFirst().map(ResolvedDependency::getVersion).get(); + + return new LatestRelease(null).compare(null, mockitoCoreVersion, "5.14.0") >= 0 ? + "-javaagent:${org.mockito:mockito-core:jar}" : "-javaagent:${net.bytebuddy:byte-buddy-agent:jar}"; + } + + private Xml.Tag buildConfigurationTag(String argLineJavaAgentParam, boolean hasExistingArgLine) { + return Xml.Tag.build(String.format(CONFIGURATION_TAG_TEMPLATE, hasExistingArgLine ? argLineJavaAgentParam : "@{argLine} " + argLineJavaAgentParam)); + } + + private void maybeAddMavenDependencyPluginWithPropertiesGoal() { + Optional mavenDependencyPlugin = getResolutionResult().getPom().getPlugins().stream() + .filter(plugin -> plugin.getGroupId().equals("org.apache.maven.plugins") + && plugin.getArtifactId().equals("maven-dependency-plugin")).findFirst(); + + if (!mavenDependencyPlugin.isPresent()) { + doAfterVisit(new AddPlugin("org.apache.maven.plugins", "maven-dependency-plugin", null, null, null, + "" + MAVEN_DEPENDENCY_PLUGIN_EXECUTION_TAG + "", "**/pom.xml").getVisitor()); + } else if (mavenDependencyPlugin.get().getExecutions().isEmpty()) { + doAfterVisit(new ChangePluginExecutions("org.apache.maven.plugins", "maven-dependency-plugin", MAVEN_DEPENDENCY_PLUGIN_EXECUTION_TAG).getVisitor()); + } else if (mavenDependencyPlugin.get().getExecutions().stream().noneMatch(execution -> execution.getGoals() != null)) { + doAfterVisit(new AddOrUpdateChildTag(MAVEN_DEPENDENCY_PLUGIN_EXECUTION_MATCHER, "" + MAVEN_DEPENDENCY_PLUGIN_PROPERTIES_GOAL + "", false).getVisitor()); + } else if (mavenDependencyPlugin.get().getExecutions().stream().noneMatch(execution -> execution.getGoals() != null && execution.getGoals().contains("properties"))) { + doAfterVisit(new AppendChildTagToParentVisitor( + new XPathMatcher(MAVEN_DEPENDENCY_PLUGIN_EXECUTION_MATCHER + "/goals"), + Xml.Tag.build(MAVEN_DEPENDENCY_PLUGIN_PROPERTIES_GOAL))); + } + } + + @Override + public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) { + if (getResolutionResult().getPom().getPluginManagement().stream().anyMatch( + plugin -> plugin.getGroupId().equals("org.apache.maven.plugins") && plugin.getArtifactId() + .equals("maven-surefire-plugin") && plugin.getConfigurationStringValue("argLine") != null && plugin.getConfigurationStringValue("argLine").contains(getArgLineJavaAgentArgument()))) { + return document; + } + + maybeAddMavenDependencyPluginWithPropertiesGoal(); + doAfterVisit(new AddPropertyVisitor("argLine", "", true)); + + if (FindPlugin.find(document, "org.apache.maven.plugins", "maven-surefire-plugin").isEmpty()) { + doAfterVisit(new AddPlugin("org.apache.maven.plugins", "maven-surefire-plugin", null, + String.format(CONFIGURATION_TAG_TEMPLATE, "@{argLine} " + getArgLineJavaAgentArgument()), null, + null, null).getVisitor()); + return document; + } + return super.visitDocument(document, ctx); + } + + @Override + public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) { + Xml.Tag t = super.visitTag(tag, ctx); + // `isPluginTag` matches any `plugin` under a `plugins` element, so this covers both + // `build/plugins` and `build/pluginManagement/plugins` declarations. + if (!isPluginTag(MAVEN_PLUGINS_GROUP_ID, MAVEN_SUREFIRE_PLUGIN_ARTIFACT_ID)) { + return t; + } + + String argLineJavaAgentParam = getArgLineJavaAgentArgument(); + //noinspection unchecked + List pluginContents = (List) t.getContent(); + Optional configuration = t.getChild("configuration"); + if (!configuration.isPresent()) { + return autoFormat(t.withContent(ListUtils.concat(pluginContents, + buildConfigurationTag(argLineJavaAgentParam, false))), ctx); + } + + Xml.Tag config = configuration.get(); + //noinspection unchecked + List configContents = (List) config.getContent(); + List argLineTagChildren = config.getChildren("argLine"); + if (argLineTagChildren.isEmpty()) { + Xml.Tag updatedConfig = config.withContent(ListUtils.concatAll(configContents, + buildConfigurationTag(argLineJavaAgentParam, false).getContent())); + return autoFormat(t.withContent(ListUtils.map(pluginContents, c -> c == config ? updatedConfig : c)), ctx); + } + if (argLineTagChildren.size() == 1) { + Xml.Tag argLineTag = argLineTagChildren.get(0); + String existingArgLineValue = argLineTag.getValue().orElse("@{argLine}"); + + if (!existingArgLineValue.contains(argLineJavaAgentParam)) { + List nonArgLineTags = ListUtils.filter(configContents, content -> content != argLineTag); + Xml.Tag mergedConfiguration = buildConfigurationTag(existingArgLineValue + " " + argLineJavaAgentParam, true); + Xml.Tag updatedConfig = config.withContent(ListUtils.concatAll(nonArgLineTags, mergedConfiguration.getContent())); + return autoFormat(t.withContent(ListUtils.map(pluginContents, c -> c == config ? updatedConfig : c)), ctx); + } + } + // No surefire change needed: the single argLine already contains the agent, or + // there are multiple tags (an invalid configuration, since surefire's + // argLine is single-valued) that we leave untouched. + return t; + } + }); + } + + @RequiredArgsConstructor + private static class AppendChildTagToParentVisitor extends XmlIsoVisitor { + private final XPathMatcher parentXPathMatcher; + private final Xml.Tag newChildTag; + + @Override + public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) { + if (parentXPathMatcher.matches(getCursor()) && + tag.getChildren(newChildTag.getName()).stream().noneMatch(child -> child.getValue().equals(newChildTag.getValue()))) { + return autoFormat(AddToTagVisitor.addToTag(tag, newChildTag, getCursor()), ctx); + } + return super.visitTag(tag, ctx); + } + } +} diff --git a/src/main/resources/META-INF/rewrite/java-version-25.yml b/src/main/resources/META-INF/rewrite/java-version-25.yml index 8462207518..8df8f20b03 100644 --- a/src/main/resources/META-INF/rewrite/java-version-25.yml +++ b/src/main/resources/META-INF/rewrite/java-version-25.yml @@ -221,27 +221,7 @@ recipeList: groupId: org.mockito artifactId: mockito-* newVersion: 5.17.x - - org.openrewrite.java.migrate.AddSurefireFailsafeArgLineForMockito - ---- -type: specs.openrewrite.org/v1beta/recipe -name: org.openrewrite.java.migrate.AddSurefireFailsafeArgLineForMockito -displayName: Add surefire `--add-opens` for Mockito/ByteBuddy -description: >- - Adds `--add-opens` JVM arguments required by Mockito and ByteBuddy to the Maven Surefire and Failsafe plugin - `argLine` configuration. Only applied when the project depends on Mockito. -preconditions: - - org.openrewrite.java.dependencies.search.ModuleHasDependency: - groupIdPattern: org.mockito - artifactIdPattern: mockito-* -recipeList: - - org.openrewrite.java.migrate.AddSurefireFailsafeArgLine: - argLine: >- - --add-opens java.base/java.lang=ALL-UNNAMED - --add-opens java.base/java.lang.reflect=ALL-UNNAMED - --add-opens java.base/jdk.internal.misc=ALL-UNNAMED - --add-opens java.base/jdk.internal.reflect=ALL-UNNAMED - -Dnet.bytebuddy.experimental=true + - org.openrewrite.java.migrate.AddMockitoJavaAgentToMavenSurefirePlugin --- type: specs.openrewrite.org/v1beta/recipe diff --git a/src/main/resources/META-INF/rewrite/recipes.csv b/src/main/resources/META-INF/rewrite/recipes.csv index dfdfe9bef6..0f8af09307 100644 --- a/src/main/resources/META-INF/rewrite/recipes.csv +++ b/src/main/resources/META-INF/rewrite/recipes.csv @@ -13,10 +13,10 @@ maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.A maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.AddLombokMapstructBinding,Add `lombok-mapstruct-binding` when both MapStruct and Lombok are used,Add the `lombok-mapstruct-binding` annotation processor as needed when both MapStruct and Lombok are used.,5,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.AddLombokMapstructBindingMavenDependencyOnly,Add `lombok-mapstruct-binding` dependency for Maven when both MapStruct and Lombok are used,"Add the `lombok-mapstruct-binding` when both MapStruct and Lombok are used, and the dependency does not already exist. Only to be called from `org.openrewrite.java.migrate.AddLombokMapstructBinding` to reduce redundant checks.",2,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.AddMissingMethodImplementation,Adds missing method implementations,Check for missing methods required by interfaces and adds them.,1,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,"[{""name"":""fullyQualifiedClassName"",""type"":""String"",""displayName"":""Fully qualified class name"",""description"":""A fully qualified class being implemented with missing method."",""example"":""com.yourorg.FooBar"",""required"":true},{""name"":""methodPattern"",""type"":""String"",""displayName"":""Method pattern"",""description"":""A method pattern for matching required method definition."",""example"":""*..* hello(..)"",""required"":true},{""name"":""methodTemplateString"",""type"":""String"",""displayName"":""Method template"",""description"":""Template of method to add"",""example"":""public String hello() { return \\\""Hello from #{}!\\\""; }"",""required"":true}]", +maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.AddMockitoJavaAgentToMavenSurefirePlugin,Add Mockito Java Agent to Maven Surefire Plugin,Adds required configuration to specifically enable the Mockito/Bytebuddy Java agent in the Maven Surefire plugin for Java 21 compatibility.,1,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,, maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.AddStaticVariableOnProducerSessionBean,Adds `static` modifier to `@Produces` fields that are in session beans,"Ensures that the fields annotated with `@Produces` which is inside the session bean (`@Stateless`, `@Stateful`, or `@Singleton`) are declared `static`.",1,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,, maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.AddSuppressionForIllegalReflectionWarningsPlugin,Add maven jar plugin to suppress illegal reflection warnings,Adds a maven jar plugin that's configured to suppress Illegal Reflection Warnings.,1,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,"[{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number, or node-style semver selector used to select the version number."",""example"":""29.X""}]", maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.AddSurefireFailsafeArgLine,Add `argLine` to surefire and failsafe plugins,"Adds the specified arguments to the `argLine` configuration of the Maven Surefire and Failsafe plugins, merging with any existing argLine value without duplicating arguments.",1,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,"[{""name"":""argLine"",""type"":""String"",""displayName"":""Arg line"",""description"":""The arguments to add to the surefire and failsafe plugin `argLine` configuration. Individual arguments are space-separated. Arguments already present in the existing argLine are not duplicated."",""example"":""--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED"",""required"":true}]", -maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.AddSurefireFailsafeArgLineForMockito,Add surefire `--add-opens` for Mockito/ByteBuddy,Adds `--add-opens` JVM arguments required by Mockito and ByteBuddy to the Maven Surefire and Failsafe plugin `argLine` configuration. Only applied when the project depends on Mockito.,2,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,, maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.ArrayStoreExceptionToTypeNotPresentException,Catch `TypeNotPresentException` thrown by `Class.getAnnotation()`,Replace catch blocks for `ArrayStoreException` around `Class.getAnnotation()` with `TypeNotPresentException` to ensure compatibility with Java 11+.,1,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,, maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.BeanDiscovery,Behavior change to bean discovery in modules with `beans.xml` file with no version specified,Alters beans with missing version attribute to include this attribute as well as the bean-discovery-mode="all" attribute to maintain an explicit bean archive.,1,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,, maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.BeansXmlNamespace,Change `beans.xml` `schemaLocation` to match XML namespace,Set the `schemaLocation` that corresponds to the `xmlns` set in `beans.xml` files.,1,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,, @@ -46,7 +46,7 @@ maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.J maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.JREThrowableFinalMethods,Rename final method declarations `getSuppressed()` and `addSuppressed(Throwable exception)` in classes that extend `Throwable`,The recipe renames `getSuppressed()` and `addSuppressed(Throwable exception)` methods in classes that extend `java.lang.Throwable` to `myGetSuppressed` and `myAddSuppressed(Throwable)`. These methods were added to Throwable in Java 7 and are marked final which cannot be overridden.,1,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,, maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.JREWrapperInterface,Add missing `isWrapperFor` and `unwrap` methods,Add method implementations stubs to classes that implement `java.sql.Wrapper`.,3,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,, maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.Java8toJava11,Migrate to Java 11,"This recipe will apply changes commonly needed when upgrading to Java 11. Specifically, for those applications that are built on Java 8, this recipe will update and add dependencies on J2EE libraries that are no longer directly bundled with the JDK. This recipe will also replace deprecated API with equivalents when there is a clear migration strategy. Build files will also be updated to use Java 11 as the target/source and plugins will be also be upgraded to versions that are compatible with Java 11.",255,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.JavaBestPractices,Java best practices,"Applies opinionated best practices for Java projects targeting Java 25. This recipe includes the full Java 25 upgrade chain plus additional improvements to code style, API usage, and third-party dependency reduction that go beyond what the version migration recipes apply.",1505,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.JavaBestPractices,Java best practices,"Applies opinionated best practices for Java projects targeting Java 25. This recipe includes the full Java 25 upgrade chain plus additional improvements to code style, API usage, and third-party dependency reduction that go beyond what the version migration recipes apply.",1504,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.JpaCacheProperties,Disable the persistence unit second-level cache,Sets an explicit value for the shared cache mode.,1,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,, maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.Jre17AgentMainPreMainPublic,Set visibility of `premain` and `agentmain` methods to `public`,Check for a behavior change in Java agents.,5,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,, maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.Krb5LoginModuleClass,Use `com.sun.security.auth.module.Krb5LoginModule` instead of `com.ibm.security.auth.module.Krb5LoginModule`,Do not use the `com.ibm.security.auth.module.Krb5LoginModule` class.,2,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,Basic building blocks for transforming Java code.,, @@ -92,10 +92,10 @@ maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.U maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.UpgradePluginsForJava11,Upgrade plugins to Java 11 compatible versions,Updates plugins to version compatible with Java 11.,6,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.UpgradePluginsForJava17,Upgrade plugins to Java 17 compatible versions,Updates plugins to version compatible with Java 17.,8,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.UpgradePluginsForJava21,Upgrade plugins to Java 21 compatible versions,Updates plugins and dependencies to version compatible with Java 21.,6,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.UpgradePluginsForJava25,Upgrade plugins to Java 25 compatible versions,Updates plugins and dependencies to versions compatible with Java 25.,10,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.UpgradePluginsForJava25,Upgrade plugins to Java 25 compatible versions,Updates plugins and dependencies to versions compatible with Java 25.,9,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.UpgradeToJava17,Migrate to Java 17,"This recipe will apply changes commonly needed when migrating to Java 17. Specifically, for those applications that are built on Java 8, this recipe will update and add dependencies on J2EE libraries that are no longer directly bundled with the JDK. This recipe will also replace deprecated API with equivalents when there is a clear migration strategy. Build files will also be updated to use Java 17 as the target/source and plugins will be also be upgraded to versions that are compatible with Java 17.",416,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.UpgradeToJava21,Migrate to Java 21,This recipe will apply changes commonly needed when migrating to Java 21. This recipe will also replace deprecated API with equivalents when there is a clear migration strategy. Build files will also be updated to use Java 21 as the target/source and plugins will be also be upgraded to versions that are compatible with Java 21.,592,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.UpgradeToJava25,Migrate to Java 25,This recipe will apply changes commonly needed when migrating to Java 25. This recipe will also replace deprecated API with equivalents when there is a clear migration strategy. Build files will also be updated to use Java 25 as the target/source and plugins will be also be upgraded to versions that are compatible with Java 25.,1155,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.UpgradeToJava25,Migrate to Java 25,This recipe will apply changes commonly needed when migrating to Java 25. This recipe will also replace deprecated API with equivalents when there is a clear migration strategy. Build files will also be updated to use Java 25 as the target/source and plugins will be also be upgraded to versions that are compatible with Java 25.,1154,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.UpgradeToJava6,Migrate to Java 6,This recipe will apply changes commonly needed when upgrading to Java 6. This recipe will also replace deprecated API with equivalents when there is a clear migration strategy.,7,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.UpgradeToJava7,Migrate to Java 7,This recipe will apply changes commonly needed when upgrading to Java 7. This recipe will also replace deprecated API with equivalents when there is a clear migration strategy.,28,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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-migrate-java,org.openrewrite.java.migrate.UpgradeToJava8,Migrate to Java 8,This recipe will apply changes commonly needed when upgrading to Java 8. This recipe will also replace deprecated API with equivalents when there is a clear migration strategy.,54,,,Modernize,Java,,,Modernize your code to best use the project's current JDK version. Take advantage of newly available APIs and reduce the dependency of your code on third party dependencies where there is equivalent functionality in the Java standard library.,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.""}]}]" diff --git a/src/test/java/org/openrewrite/java/migrate/AddMockitoJavaAgentToMavenSurefirePluginTest.java b/src/test/java/org/openrewrite/java/migrate/AddMockitoJavaAgentToMavenSurefirePluginTest.java new file mode 100644 index 0000000000..26004a91cc --- /dev/null +++ b/src/test/java/org/openrewrite/java/migrate/AddMockitoJavaAgentToMavenSurefirePluginTest.java @@ -0,0 +1,1481 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * 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 + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * 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.migrate; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; +import org.openrewrite.test.RecipeSpec; + +import static org.openrewrite.java.Assertions.mavenProject; +import static org.openrewrite.maven.Assertions.pomXml; + +public class AddMockitoJavaAgentToMavenSurefirePluginTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec.recipe(new AddMockitoJavaAgentToMavenSurefirePlugin()); + } + + @Test + void addsMockitoAgentArgAndPropertiesGoalToMavenPlugins() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + """, + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + + + + + """ + ) + ) + ); + } + + @Test + void addsByteBuddyAgentArgWithSurefirePluginAndNoExistingConfigurationWithOlderMockitoVersion() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.3.13 + + + + custom value + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + """, + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.3.13 + + + + custom value + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${net.bytebuddy:byte-buddy-agent:jar} + + + + + + """ + ) + ) + ); + } + + @Test + void addsMockitoAgentArgToExistingConfigurationWithNoArgLineTag() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + some-property + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + foobar + + + + + + + """, + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + some-property + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + foobar + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + + + + + """ + ) + ) + ); + } + + @Test + void addsMockitoAgentArgToExistingArgLineTagWithNoValue() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + + + """, + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + + + + + """ + ) + ) + ); + } + + @Test + void addsMockitoAgentArgPreservingExistingArgLineArguments() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + foobar + + -Xmx256m + + + + + + """, + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + foobar + + + -Xmx256m -javaagent:${org.mockito:mockito-core:jar} + + + + + + """ + ) + ) + ); + } + + @Test + void onlyAddsConfigurationToPomWithMockitoInMultiModuleProject() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + 1.0 + + + test-module1 + + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + """, + spec -> spec.path("pom.xml") + ), + pomXml( + """ + + 4.0.0 + org.sample + test-module1 + ${revision} + + + org.sample + test + 1.0 + ../pom.xml + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + """, + """ + + 4.0.0 + org.sample + test-module1 + ${revision} + + + org.sample + test + 1.0 + ../pom.xml + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + + + + + """, + spec -> spec.path("test-module1/pom.xml") + ) + ) + ); + } + + @Test + void addsMavenSurefireAndDependencyPluginsWhenAbsent() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + """, + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + + + + + """ + ) + ) + ); + } + + @Test + void addsGoalsTagWithPropertiesGoalToExistingMavenDependencyPluginWhenMissing() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + + + + + """, + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + + + + + """ + ) + ) + ); + } + + @Test + void addsPropertiesGoalToExistingGoalsSectionInMavenDependencyPlugin() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + + + + analyize + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + + + + + """, + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + + + + analyize + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + + + + + """ + ) + ) + ); + } + + @Test + void makesNoChangeWhenMockitoAgentFlagAlreadyExists() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + ${project.build.directory}/jacoco.exec + + + + + + + """ + ) + ) + ); + } + + @Test + void makesNoChangeWhenMockitoAgentFlagAlreadyExistsUsingSingleLineArgline() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + ${project.build.directory}/jacoco.exec + + + + + + + """ + ) + ) + ); + } + + @Test + void makesNoChangeWhenMockitoCoreDependencyIsNotOnClasspath() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.build.directory}/jacoco.exec + + + + + + + """ + ) + ) + ); + } + + @Test + void makesNoChangesWhenParentPomManagesSurefirePluginAndHasAgentConfiguration() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + 1.0 + + + test-module1 + + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + ${project.build.directory}/jacoco.exec + + + + + + + + """, + spec -> spec.path("pom.xml") + ), + pomXml( + """ + + 4.0.0 + org.sample + test-module1 + ${revision} + + + org.sample + test + 1.0 + ../pom.xml + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + """, + spec -> spec.path("test-module1/pom.xml") + ) + ) + ); + } + + @Test + void updatesIndividualPomsWhenParentPomManagesSurefirePluginWithoutAgentConfiguration() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + 1.0 + + + test-module1 + + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + ${project.build.directory}/jacoco.exec + + + + + + + + """, + spec -> spec.path("pom.xml") + ), + pomXml( + """ + + 4.0.0 + org.sample + test-module1 + ${revision} + + + org.sample + test + 1.0 + ../pom.xml + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + """, + """ + + 4.0.0 + org.sample + test-module1 + ${revision} + + + org.sample + test + 1.0 + ../pom.xml + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + + + """, + spec -> spec.path("test-module1/pom.xml") + ) + ) + ); + } + + @Test + void augmentsSurefirePluginDeclaredInPluginManagement() { + rewriteRun( + mavenProject("test-project", + pomXml( + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + """, + """ + + 4.0.0 + org.sample + test + ${revision} + + + org.springframework.boot + spring-boot-starter-parent + 3.5.4 + + + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + properties + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + @{argLine} -javaagent:${org.mockito:mockito-core:jar} + + + + + + + """ + ) + ) + ); + } +} diff --git a/src/test/java/org/openrewrite/java/migrate/UpgradeToJava25Test.java b/src/test/java/org/openrewrite/java/migrate/UpgradeToJava25Test.java index f116ab9393..44d4b3a562 100644 --- a/src/test/java/org/openrewrite/java/migrate/UpgradeToJava25Test.java +++ b/src/test/java/org/openrewrite/java/migrate/UpgradeToJava25Test.java @@ -118,8 +118,7 @@ void upgradesMavenPluginsForJava25() { .containsPattern("maven-compiler-plugin\\s*3\\.15\\.") .containsPattern("maven-surefire-plugin\\s*3\\.5\\.") .containsPattern("maven-failsafe-plugin\\s*3\\.5\\.") - .contains("--add-opens java.base/java.lang=ALL-UNNAMED") - .contains("-Dnet.bytebuddy.experimental=true") + .contains("@{argLine} -javaagent:${org.mockito:mockito-core:jar}") .actual()) ) )