From c7f32b3e78018d784d49ae3f8578d35547198088 Mon Sep 17 00:00:00 2001 From: Jonathan Schneider Date: Sun, 23 Aug 2026 22:39:41 -0400 Subject: [PATCH] Upgrade AspectJ and fold `mockito-inline` into `mockito-core` for Java 25 `mockito-inline` was discontinued after 5.2.0 once inline mocking became the default in `mockito-core`, so raising a shared Mockito version property past that leaves the dependency unresolvable. Renaming rather than removing keeps Mockito present in a module whose only declaration was the inline artifact. Neither AspectJ plugin compiles at Java 25 out of the box: both bundle aspectjtools 1.9.7, which rejects `-25`, so the compiler has to be pinned explicitly. The coordinate moves because `org.codehaus.mojo` defaults `complianceLevel` to 1.4 and always passes it, which contradicts a source level of 25; `dev.aspectj` leaves it unset and follows source and target instead. --- .../META-INF/rewrite/java-version-25.yml | 27 ++++ .../java/migrate/UpgradeToJava25Test.java | 135 ++++++++++++++++++ 2 files changed, 162 insertions(+) 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 3d4fe18287..587ad1f8f5 100644 --- a/src/main/resources/META-INF/rewrite/java-version-25.yml +++ b/src/main/resources/META-INF/rewrite/java-version-25.yml @@ -220,6 +220,33 @@ recipeList: groupId: net.bytebuddy artifactId: byte-buddy* newVersion: 1.17.x + # Both distributions bundle an AspectJ too old to read Java 25 bytecode, so aspectjtools is pinned on the plugin. + # dev.aspectj is otherwise interchangeable, but org.codehaus.mojo's `complianceLevel` default of 1.4 is now fatal. + - org.openrewrite.maven.ChangePluginGroupIdAndArtifactId: + oldGroupId: org.codehaus.mojo + oldArtifactId: aspectj-maven-plugin + newGroupId: dev.aspectj + newVersion: 1.14.x + - org.openrewrite.maven.AddPluginDependency: + pluginGroupId: dev.aspectj + pluginArtifactId: aspectj-maven-plugin + groupId: org.aspectj + artifactId: aspectjtools + version: 1.9.25.1 + - org.openrewrite.xml.ChangeTagValue: + elementName: //plugin[artifactId='aspectj-maven-plugin']/configuration/complianceLevel + newValue: "25" + - org.openrewrite.java.dependencies.UpgradeDependencyVersion: + groupId: org.aspectj + artifactId: aspectj* + newVersion: 1.9.x + # mockito-inline was last published as 5.2.0 and inline mocking is the default in mockito-core 5.x, so fold it in + # before the bump below rather than leaving a coordinate that no longer resolves. + - org.openrewrite.java.dependencies.ChangeDependency: + oldGroupId: org.mockito + oldArtifactId: mockito-inline + newArtifactId: mockito-core + - org.openrewrite.maven.RemoveDuplicateDependencies - org.openrewrite.java.dependencies.UpgradeDependencyVersion: groupId: org.mockito artifactId: mockito-* diff --git a/src/test/java/org/openrewrite/java/migrate/UpgradeToJava25Test.java b/src/test/java/org/openrewrite/java/migrate/UpgradeToJava25Test.java index 478f008121..c48df08575 100644 --- a/src/test/java/org/openrewrite/java/migrate/UpgradeToJava25Test.java +++ b/src/test/java/org/openrewrite/java/migrate/UpgradeToJava25Test.java @@ -508,4 +508,139 @@ void addsLombokAnnotationProcessor() { ) ); } + + @Test + void mockitoInlineFoldedIntoMockitoCore() { + // mockito-inline was last published as 5.2.0, so bumping a shared mockito version property would otherwise + // leave it unresolvable; inline mocking is the default in mockito-core 5.x. + rewriteRun( + mavenProject("project", + pomXml( + //language=xml + """ + + com.mycompany.app + my-app + 1 + + 17 + 5.2.0 + + + + org.mockito + mockito-inline + ${mockito.version} + test + + + + """, + spec -> spec.after(actual -> + assertThat(actual) + .contains("25") + .doesNotContain("mockito-inline") + .contains("mockito-core") + .containsPattern("5\\.17\\.") + .actual()) + ) + ) + ); + } + + @Test + void mockitoInlineAlongsideMockitoCoreLeavesNoDuplicate() { + rewriteRun( + mavenProject("project", + pomXml( + //language=xml + """ + + com.mycompany.app + my-app + 1 + + 17 + 5.2.0 + + + + org.mockito + mockito-core + ${mockito.version} + test + + + org.mockito + mockito-inline + ${mockito.version} + test + + + + """, + spec -> spec.after(actual -> + assertThat(actual) + .doesNotContain("mockito-inline") + .containsOnlyOnce("mockito-core") + .containsPattern("5\\.17\\.") + .actual()) + ) + ) + ); + } + + @Test + void upgradesAspectJMavenPluginForJava25() { + // Only AspectJ 1.9.25 and later can read Java 25 bytecode, and neither plugin distribution bundles a compiler + // that new, so aspectjtools is pinned on the plugin itself. + rewriteRun( + mavenProject("project", + pomXml( + //language=xml + """ + + com.mycompany.app + my-app + 1 + + 8 + 8 + + + + org.aspectj + aspectjrt + 1.8.13 + + + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.11 + + ${maven.compiler.source} + ${maven.compiler.target} + 1.8 + + + + + + """, + spec -> spec.after(actual -> + assertThat(actual) + .contains("25") + .doesNotContain("org.codehaus.mojo") + .containsPattern("dev.aspectj\\s*aspectj-maven-plugin\\s*1\\.14\\.") + .containsPattern("aspectjtools\\s*1\\.9\\.25") + .contains("25") + .containsPattern("aspectjrt\\s*1\\.9\\.") + .actual()) + ) + ) + ); + } }