From b430e3147827b02e627fa531a6ebaa62b9e9f605 Mon Sep 17 00:00:00 2001 From: Jonathan Schneider Date: Sat, 3 Oct 2026 22:19:16 +0100 Subject: [PATCH] jaxb-api-missing-java8: add the Jakarta JAXB API for imports the parser could not resolve Generalize AddJaxbApiForImports into AddApiDependencyForImports (package and coordinates as options), skip modules that declare the API through a provided dependency, and use it in the Jakarta JAXB migration. --- ...s.java => AddApiDependencyForImports.java} | 60 ++++++- .../META-INF/rewrite/jakarta-ee-9.yml | 5 + .../resources/META-INF/rewrite/jaxb-apis.yml | 6 +- .../resources/META-INF/rewrite/recipes.csv | 10 +- ...xXmlBindMigrationToJakartaXmlBindTest.java | 63 ++++++++ .../javax/AddApiDependencyForImportsTest.java | 151 ++++++++++++++++++ .../AddJaxbApiForUnattributedImportsTest.java | 2 +- 7 files changed, 282 insertions(+), 15 deletions(-) rename src/main/java/org/openrewrite/java/migrate/javax/{AddJaxbApiForImports.java => AddApiDependencyForImports.java} (55%) create mode 100644 src/test/java/org/openrewrite/java/migrate/javax/AddApiDependencyForImportsTest.java diff --git a/src/main/java/org/openrewrite/java/migrate/javax/AddJaxbApiForImports.java b/src/main/java/org/openrewrite/java/migrate/javax/AddApiDependencyForImports.java similarity index 55% rename from src/main/java/org/openrewrite/java/migrate/javax/AddJaxbApiForImports.java rename to src/main/java/org/openrewrite/java/migrate/javax/AddApiDependencyForImports.java index 6459ed29f6..709bc0f912 100644 --- a/src/main/java/org/openrewrite/java/migrate/javax/AddJaxbApiForImports.java +++ b/src/main/java/org/openrewrite/java/migrate/javax/AddApiDependencyForImports.java @@ -22,6 +22,7 @@ import org.openrewrite.maven.AddDependencyVisitor; import org.openrewrite.maven.MavenIsoVisitor; import org.openrewrite.maven.tree.MavenResolutionResult; +import org.openrewrite.maven.tree.ResolvedDependency; import org.openrewrite.maven.tree.Scope; import org.openrewrite.xml.tree.Xml; @@ -31,12 +32,36 @@ import java.util.Map; import java.util.Set; +import static java.util.Collections.emptyList; + @Value @EqualsAndHashCode(callSuper = false) -public class AddJaxbApiForImports extends ScanningRecipe { - String displayName = "Add JAXB API dependencies for explicit imports"; - String description = "Add the JAXB API to the nearest Maven module importing javax.xml.bind types, " + - "including imports whose types could not be resolved by the parser."; +public class AddApiDependencyForImports extends ScanningRecipe { + + @Option(displayName = "Package name", + description = "The package whose imports need the API. A `jakarta` package also matches imports of its `javax` predecessor.", + example = "jakarta.xml.bind") + String packageName; + + @Option(displayName = "Group ID", + description = "The group ID of the API dependency.", + example = "jakarta.xml.bind") + String groupId; + + @Option(displayName = "Artifact ID", + description = "The artifact ID of the API dependency.", + example = "jakarta.xml.bind-api") + String artifactId; + + @Option(displayName = "Version", + description = "The version of the API dependency to add.", + example = "3.0.x") + String version; + + String displayName = "Add an API dependency for explicit imports"; + String description = "Add an API dependency to the nearest Maven module importing the package, including imports " + + "whose types could not be resolved by the parser because the JDK used to provide them. A module that " + + "already has the API in the needed scope, or from a dependency it declares as provided, is left alone."; static class Accumulator { final Set poms = new HashSet<>(); @@ -50,6 +75,7 @@ public Accumulator getInitialValue(ExecutionContext ctx) { @Override public TreeVisitor getScanner(Accumulator acc) { + String javaxPackage = packageName.startsWith("jakarta.") ? "javax." + packageName.substring("jakarta.".length()) : packageName; return new TreeVisitor() { @Override public Tree preVisit(Tree tree, ExecutionContext ctx) { @@ -59,7 +85,8 @@ public Tree preVisit(Tree tree, ExecutionContext ctx) { } else if (tree instanceof J.CompilationUnit) { J.CompilationUnit cu = (J.CompilationUnit) tree; for (J.Import anImport : cu.getImports()) { - if (anImport.getTypeName().startsWith("javax.xml.bind.")) { + String typeName = anImport.getTypeName(); + if (typeName.startsWith(packageName + ".") || typeName.startsWith(javaxPackage + ".")) { acc.sources.add(cu.getSourcePath()); break; } @@ -92,12 +119,29 @@ public TreeVisitor getVisitor(Accumulator acc) { @Override public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) { String scope = scopes.get(document.getSourcePath()); - if (scope == null || !getResolutionResult().findDependencies("jakarta.xml.bind", "jakarta.xml.bind-api", + if (scope == null || hasProvidedApi() || !getResolutionResult().findDependencies(groupId, artifactId, "test".equals(scope) ? Scope.Test : Scope.Compile).isEmpty()) { return document; } - return (Xml.Document) new AddDependencyVisitor("jakarta.xml.bind", "jakarta.xml.bind-api", - "2.3.x", null, scope, null, null, null, null, null).visitNonNull(document, ctx); + return (Xml.Document) new AddDependencyVisitor(groupId, artifactId, + version, null, scope, null, null, null, null, null).visitNonNull(document, ctx); + } + + // The provided resolution scope also holds compile and runtime dependencies, so look at declared scopes. + private boolean hasProvidedApi() { + MavenResolutionResult model = getResolutionResult(); + for (ResolvedDependency dependency : model.getDependencies().getOrDefault(Scope.Provided, emptyList())) { + if (dependency.isDirect() && dependency.findDependency(groupId, artifactId) != null) { + String declared = model.getPom().getValue(dependency.getRequested().getScope()); + Scope scope = declared == null ? model.getPom().getManagedScope(dependency.getGroupId(), + dependency.getArtifactId(), dependency.getType(), dependency.getClassifier()) : + Scope.fromName(declared); + if (scope == Scope.Provided) { + return true; + } + } + } + return false; } }; } diff --git a/src/main/resources/META-INF/rewrite/jakarta-ee-9.yml b/src/main/resources/META-INF/rewrite/jakarta-ee-9.yml index 6641bed5d3..e3c67bed18 100644 --- a/src/main/resources/META-INF/rewrite/jakarta-ee-9.yml +++ b/src/main/resources/META-INF/rewrite/jakarta-ee-9.yml @@ -996,6 +996,11 @@ recipeList: version: 3.0.x onlyIfUsing: javax.xml.bind..* acceptTransitive: true + - org.openrewrite.java.migrate.javax.AddApiDependencyForImports: + packageName: jakarta.xml.bind + groupId: jakarta.xml.bind + artifactId: jakarta.xml.bind-api + version: 3.0.x - org.openrewrite.java.ChangePackage: oldPackageName: javax.xml.bind newPackageName: jakarta.xml.bind diff --git a/src/main/resources/META-INF/rewrite/jaxb-apis.yml b/src/main/resources/META-INF/rewrite/jaxb-apis.yml index 47ce1cac25..5d108ddcdc 100644 --- a/src/main/resources/META-INF/rewrite/jaxb-apis.yml +++ b/src/main/resources/META-INF/rewrite/jaxb-apis.yml @@ -114,7 +114,11 @@ recipeList: newGroupId: jakarta.xml.bind newArtifactId: jakarta.xml.bind-api newVersion: 2.3.x - - org.openrewrite.java.migrate.javax.AddJaxbApiForImports + - org.openrewrite.java.migrate.javax.AddApiDependencyForImports: + packageName: javax.xml.bind + groupId: jakarta.xml.bind + artifactId: jakarta.xml.bind-api + version: 2.3.x # Add the jakarta JAXB artifact if it is missing but a project uses types in java.xml.bind - org.openrewrite.java.dependencies.AddDependency: groupId: jakarta.xml.bind diff --git a/src/main/resources/META-INF/rewrite/recipes.csv b/src/main/resources/META-INF/rewrite/recipes.csv index c3f77577dc..37655b288b 100644 --- a/src/main/resources/META-INF/rewrite/recipes.csv +++ b/src/main/resources/META-INF/rewrite/recipes.csv @@ -221,8 +221,8 @@ maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.j maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.jakarta.FileuploadToFileUpload2,Migrate deprecated `org.apache.commons.fileload` packages to `org.apache.commons.fileload.core`,Migrate deprecated `org.apache.commons.fileload` packages to `org.apache.commons.fileload.core`.,6,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.HasNoJakartaAnnotations,Project has no Jakarta annotations,Mark all source as found per `JavaProject` where no Jakarta annotations are found. This is useful mostly as a precondition for recipes that require Jakarta annotations to be present.,1,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JacksonJavaxToJakarta,Migrate Jackson from javax to jakarta namespace,Java EE has been rebranded to Jakarta EE. This recipe replaces existing Jackson dependencies with their counterparts that are compatible with Jakarta EE 9.,23,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JakartaEE10,Migrate to Jakarta EE 10,"These recipes help with the Migration to Jakarta EE 10, flagging and updating deprecated methods.",603,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JakartaEE11,Migrate to Jakarta EE 11,"These recipes help with the Migration to Jakarta EE 11, flagging and updating deprecated methods.",621,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JakartaEE10,Migrate to Jakarta EE 10,"These recipes help with the Migration to Jakarta EE 10, flagging and updating deprecated methods.",604,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JakartaEE11,Migrate to Jakarta EE 11,"These recipes help with the Migration to Jakarta EE 11, flagging and updating deprecated methods.",622,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JakartaFacesConfigXml4,Migrate xmlns entries in `faces-config.xml` files,Jakarta EE 10 uses Faces version 4.,3,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JakartaFacesEcmaScript,Migrate JSF values inside EcmaScript files,"Convert JSF to Faces values inside JavaScript,TypeScript, and Properties files.",4,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JakartaFacesTagLibraryXml4,Migrate xmlns entries in `taglib.xml` files,Faces 4 uses facelet-taglib 4.0.,3,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.,, @@ -252,7 +252,7 @@ maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.j maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.jakarta.JavaxJspToJakartaJsp,Migrate deprecated `javax.jsp` packages to `jakarta.jsp`,"Java EE has been rebranded to Jakarta EE, necessitating a package relocation.",6,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxJwsToJakartaJws,Migrate deprecated `javax.jws` packages to `jakarta.jws`,"Java EE has been rebranded to Jakarta EE, necessitating a package relocation.",6,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxMailToJakartaMail,Migrate deprecated `javax.mail` packages to `jakarta.mail`,"Java EE has been rebranded to Jakarta EE, necessitating a package relocation.",8,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxMigrationToJakarta,Migrate to Jakarta EE 9,Jakarta EE 9 is the first version of Jakarta EE that uses the new `jakarta` namespace.,377,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxMigrationToJakarta,Migrate to Jakarta EE 9,Jakarta EE 9 is the first version of Jakarta EE that uses the new `jakarta` namespace.,378,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxOrmXmlToJakartaOrmXml,Migrate xmlns entries in `orm.xml` files,"Java EE has been rebranded to Jakarta EE, necessitating an XML namespace relocation.",4,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxPersistenceToJakartaPersistence,Migrate deprecated `javax.persistence` packages to `jakarta.persistence`,"Java EE has been rebranded to Jakarta EE, necessitating a package relocation.",6,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxPersistenceXmlToJakartaPersistenceXml,Migrate xmlns entries in `persistence.xml` files,"Java EE has been rebranded to Jakarta EE, necessitating an XML namespace relocation.",6,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.,, @@ -266,7 +266,7 @@ maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.j maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.jakarta.JavaxWebXmlToJakartaWebXml,Migrate xmlns entries in `web.xml` files,"Java EE has been rebranded to Jakarta EE, necessitating an XML namespace relocation.",6,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxWebsocketToJakartaWebsocket,Migrate deprecated `javax.websocket` packages to `jakarta.websocket`,"Java EE has been rebranded to Jakarta EE, necessitating a package relocation.",9,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxWsToJakartaWs,Migrate deprecated `javax.ws` packages to `jakarta.ws`,"Java EE has been rebranded to Jakarta EE, necessitating a package relocation.",5,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxXmlBindMigrationToJakartaXmlBind,Migrate deprecated `javax.xml.bind` packages to `jakarta.xml.bind`,"Java EE has been rebranded to Jakarta EE, necessitating a package relocation.",20,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxXmlBindMigrationToJakartaXmlBind,Migrate deprecated `javax.xml.bind` packages to `jakarta.xml.bind`,"Java EE has been rebranded to Jakarta EE, necessitating a package relocation.",21,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxXmlSoapToJakartaXmlSoap,Migrate deprecated `javax.soap` packages to `jakarta.soap`,"Java EE has been rebranded to Jakarta EE, necessitating a package relocation.",5,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxXmlToJakartaXmlXJCBinding,Migrate XJC Bindings to Jakata XML,"Java EE has been rebranded to Jakarta EE, migrates the namespace and version in XJC bindings.",3,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.jakarta.JavaxXmlWsMigrationToJakartaXmlWs,Migrate deprecated `javax.xml.ws` packages to `jakarta.xml.ws`,"Java EE has been rebranded to Jakarta EE, necessitating a package relocation.",8,,Jakarta,Modernize,Java,,Recipes for migrating to [Jakarta EE](https://jakarta.ee/).,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.,, @@ -324,6 +324,7 @@ maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.j maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.javaee8.ApacheDefaultProvider,Flags any `org.apache.bval.jsr*` (bval 1.1) and `org.apache.bval.jsr303*` (bval 1.0) package references,This recipe flags any `org.apache.bval.jsr*` (bval 1.1) and `org.apache.bval.jsr303*` (bval 1.0) package references in validation.xml deployment descriptors. Bean Validation 2.0 and later use the Hibernate Validator implementation instead of the Apache BVal implementation which was used for Bean Validation 1.0 and 1.1.,6,,Java EE 8,Modernize,Java,,Recipes for migrating to [Java EE 8](https://javaee.github.io/javaee-spec/javadocs/).,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.javaee8.MigrateToServlet3x,Update Java EE Servlet Dependencies to 3.x,Update Java EE Servlet Dependencies to 3.x.,2,,Java EE 8,Modernize,Java,,Recipes for migrating to [Java EE 8](https://javaee.github.io/javaee-spec/javadocs/).,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.javaee8.ServletIsRequestedSessionIdFromURL,Replace `HttpServletRequestWrapper.isRequestedSessionIdFromUrl()` with `isRequestedSessionIdFromURL()`,The method `HttpServletRequestWrapper.isRequestedSessionIdFromUrl()` is deprecated in JavaEE8 and is replaced by `HttpServletRequestWrapper.isRequestedSessionIdFromURL()`.,2,,Java EE 8,Modernize,Java,,Recipes for migrating to [Java EE 8](https://javaee.github.io/javaee-spec/javadocs/).,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.javax.AddApiDependencyForImports,Add an API dependency for explicit imports,"Add an API dependency to the nearest Maven module importing the package, including imports whose types could not be resolved by the parser because the JDK used to provide them. A module that already has the API in the needed scope, or from a dependency it declares as provided, is left alone.",1,,`javax` APIs,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"":""packageName"",""type"":""String"",""displayName"":""Package name"",""description"":""The package whose imports need the API. A `jakarta` package also matches imports of its `javax` predecessor."",""example"":""jakarta.xml.bind"",""required"":true},{""name"":""groupId"",""type"":""String"",""displayName"":""Group ID"",""description"":""The group ID of the API dependency."",""example"":""jakarta.xml.bind"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact ID"",""description"":""The artifact ID of the API dependency."",""example"":""jakarta.xml.bind-api"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the API dependency to add."",""example"":""3.0.x"",""required"":true}]", maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.javax.AddColumnAnnotation,`@ElementCollection` annotations must be accompanied by a defined `@Column` annotation,"When an attribute is annotated with `@ElementCollection`, a separate table is created for the attribute that includes the attribute ID and value. In OpenJPA, the column for the annotated attribute is named element, whereas EclipseLink names the column based on the name of the attribute. To remain compatible with tables that were created with OpenJPA, add a `@Column` annotation with the name @@ -332,7 +333,6 @@ maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.j maven,org.openrewrite.recipe:rewrite-migrate-java,org.openrewrite.java.migrate.javax.AddDefaultConstructorToEntityClass,`@Entity` objects with constructors must also have a default constructor,"When a Java Persistence API (JPA) entity class has a constructor with arguments, the class must also have a default, no-argument constructor. The OpenJPA implementation automatically generates the no-argument constructor, but the EclipseLink implementation does not.",1,,`javax` APIs,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.javax.AddInjectDependencies,Add explicit Inject dependencies,Add the necessary `inject-api` dependency from Jakarta EE 8 to maintain compatibility with Java version 11 or greater.,3,,`javax` APIs,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.javax.AddJaxbAPIDependencies,Add explicit JAXB API dependencies,This recipe will add explicit API dependencies for Jakarta EE 8 when a Java 8 application is using JAXB. Any existing dependencies will be upgraded to the latest version of Jakarta EE 8. The artifacts are moved to Jakarta EE 8 version 2.x which allows for the continued use of the `javax.xml.bind` namespace. Running a full javax to Jakarta migration using `org.openrewrite.java.migrate.jakarta.JavaxMigrationToJakarta` will update to versions greater than 3.x which necessitates the package change as well.,15,,`javax` APIs,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.javax.AddJaxbApiForImports,Add JAXB API dependencies for explicit imports,"Add the JAXB API to the nearest Maven module importing javax.xml.bind types, including imports whose types could not be resolved by the parser.",1,,`javax` APIs,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.javax.AddJaxbDependenciesWithRuntime,Add explicit JAXB API dependencies and runtime,This recipe will add explicit dependencies for Jakarta EE 8 when a Java 8 application is using JAXB. Any existing dependencies will be upgraded to the latest version of Jakarta EE 8. The artifacts are moved to Jakarta EE 8 version 2.x which allows for the continued use of the `javax.xml.bind` namespace. Running a full javax to Jakarta migration using `org.openrewrite.java.migrate.jakarta.JavaxMigrationToJakarta` will update to versions greater than 3.x which necessitates the package change as well.,19,,`javax` APIs,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.javax.AddJaxbDependenciesWithoutRuntime,Add explicit JAXB API dependencies and remove runtimes,This recipe will add explicit API dependencies without runtime dependencies for Jakarta EE 8 when a Java 8 application is using JAXB. Any existing API dependencies will be upgraded to the latest version of Jakarta EE 8. The artifacts are moved to Jakarta EE 8 version 2.x which allows for the continued use of the `javax.xml.bind` namespace. All JAXB runtime implementation dependencies are removed.,20,,`javax` APIs,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.javax.AddJaxbRuntime,Use latest JAXB API and runtime for Jakarta EE 8,"Update build files to use the latest JAXB runtime from Jakarta EE 8 to maintain compatibility with Java version 11 or greater. The recipe will add a JAXB run-time, in Gradle `compileOnly`+`testImplementation` and Maven `provided` scope, to any project that has a transitive dependency on the JAXB API. **The resulting dependencies still use the `javax` namespace, despite the move to the Jakarta artifact**.",1,,`javax` APIs,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"":""runtime"",""type"":""String"",""displayName"":""JAXB run-time"",""description"":""Which implementation of the JAXB run-time that will be added to maven projects that have transitive dependencies on the JAXB API"",""example"":""glassfish"",""valid"":[""glassfish"",""sun""],""required"":true}]", diff --git a/src/test/java/org/openrewrite/java/migrate/jakarta/JavaxXmlBindMigrationToJakartaXmlBindTest.java b/src/test/java/org/openrewrite/java/migrate/jakarta/JavaxXmlBindMigrationToJakartaXmlBindTest.java index b8598c4c17..3c4141e0f3 100644 --- a/src/test/java/org/openrewrite/java/migrate/jakarta/JavaxXmlBindMigrationToJakartaXmlBindTest.java +++ b/src/test/java/org/openrewrite/java/migrate/jakarta/JavaxXmlBindMigrationToJakartaXmlBindTest.java @@ -20,14 +20,20 @@ import org.openrewrite.DocumentExample; import org.openrewrite.Issue; import org.openrewrite.config.Environment; +import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.JavaParser; +import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.JavaType; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; +import org.openrewrite.test.TypeValidation; import static org.assertj.core.api.Assertions.assertThat; import static org.openrewrite.gradle.Assertions.buildGradle; import static org.openrewrite.gradle.toolingapi.Assertions.withToolingApi; import static org.openrewrite.java.Assertions.java; +import static org.openrewrite.java.Assertions.mavenProject; +import static org.openrewrite.java.Assertions.srcMainJava; import static org.openrewrite.maven.Assertions.pomXml; @SuppressWarnings("LanguageMismatch") @@ -319,4 +325,61 @@ public class Test { ) ); } + + @Test + void addApiForUnattributedJdkAnnotation() { + rewriteRun( + spec -> spec.typeValidationOptions(TypeValidation.none()), + mavenProject("app", + srcMainJava( + java( + """ + import javax.xml.bind.annotation.XmlTransient; + class A { + @XmlTransient + String value; + } + """, + """ + import jakarta.xml.bind.annotation.XmlTransient; + class A { + @XmlTransient + String value; + } + """, + // Saved Java 8 models can have Unknown JAXB types instead of the parser's shallow types. + source -> source.mapBeforeRecipe(cu -> (J.CompilationUnit) + new JavaIsoVisitor() { + @Override + public J.Identifier visitIdentifier(J.Identifier id, Integer p) { + return id.getType() != null && id.getType().toString().startsWith("javax.xml.bind") ? + id.withType(JavaType.Unknown.getInstance()) : id; + } + + @Override + public J.FieldAccess visitFieldAccess(J.FieldAccess fa, Integer p) { + J.FieldAccess f = super.visitFieldAccess(fa, p); + return f.getType() != null && f.getType().toString().startsWith("javax.xml.bind") ? + f.withType(JavaType.Unknown.getInstance()) : f; + } + }.visit(cu, 0)) + ) + ), + pomXml( + """ + + 4.0.0 + com.example + app + 1.0 + + """, + spec -> spec.after(pom -> assertThat(pom) + .contains("jakarta.xml.bind-api") + .doesNotContain("test") + .actual()) + ) + ) + ); + } } diff --git a/src/test/java/org/openrewrite/java/migrate/javax/AddApiDependencyForImportsTest.java b/src/test/java/org/openrewrite/java/migrate/javax/AddApiDependencyForImportsTest.java new file mode 100644 index 0000000000..3deea646ba --- /dev/null +++ b/src/test/java/org/openrewrite/java/migrate/javax/AddApiDependencyForImportsTest.java @@ -0,0 +1,151 @@ +/* + * 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.javax; + +import org.junit.jupiter.api.Test; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.openrewrite.java.Assertions.*; +import static org.openrewrite.maven.Assertions.pomXml; + +class AddApiDependencyForImportsTest implements RewriteTest { + @Override + public void defaults(RecipeSpec spec) { + spec.recipe(new AddApiDependencyForImports("jakarta.xml.bind", "jakarta.xml.bind", "jakarta.xml.bind-api", "3.0.1")) + .parser(JavaParser.fromJavaVersion().dependsOn("package javax.xml.bind; public class JAXBContext {}")); + } + + private static final String POM = """ + + 4.0.0 + com.example + app + 1.0 + + """; + + private static final String USAGE = """ + import javax.xml.bind.JAXBContext; + class A { JAXBContext context; } + """; + + @Test + void testOnlyUsage() { + rewriteRun( + mavenProject("app", + srcTestJava(java(USAGE)), + pomXml(POM, spec -> spec.after(pom -> assertThat(pom) + .contains("jakarta.xml.bind-api") + .contains("test").actual())) + ) + ); + } + + @Test + void mainAndTestUsageRequiresCompileScope() { + rewriteRun( + mavenProject("app", + srcTestJava(java(USAGE.replace("class A", "class ATest"))), + srcMainJava(java(USAGE)), + pomXml(POM, spec -> spec.after(pom -> assertThat(pom) + .contains("jakarta.xml.bind-api") + .doesNotContain("test").actual())) + ) + ); + } + + @Test + void preservesProvidedApi() { + rewriteRun( + mavenProject("app", + srcMainJava(java(USAGE)), + pomXml(withDependency("provided")) + ) + ); + } + + @Test + void promotesTestApiForMainUsage() { + rewriteRun( + mavenProject("app", + srcMainJava(java(USAGE)), + pomXml(withDependency("test"), spec -> spec.after(pom -> assertThat(pom) + .contains("jakarta.xml.bind-api") + .doesNotContain("test").actual())) + ) + ); + } + + @Test + void promotesRuntimeApiForMainUsage() { + rewriteRun( + mavenProject("app", + srcMainJava(java(USAGE)), + pomXml(withDependency("runtime"), spec -> spec.after(pom -> assertThat(pom) + .contains("jakarta.xml.bind-api") + .doesNotContain("runtime").actual())) + ) + ); + } + + @Test + void runtimeProviderDoesNotSupplyCompileApi() { + rewriteRun( + mavenProject("app", + srcMainJava(java(USAGE)), + pomXml(withDependency("runtime") + .replace("jakarta.xml.bind", "org.glassfish.jaxb") + .replace("jakarta.xml.bind-api", "jaxb-runtime") + .replace("3.0.1", "3.0.2"), + spec -> spec.after(pom -> assertThat(pom) + .contains("jaxb-runtime") + .contains("jakarta.xml.bind-api") + .containsOnlyOnce("runtime").actual())) + ) + ); + } + + @Test + void leavesUnrelatedModuleAlone() { + rewriteRun( + mavenProject("app", + srcMainJava(java(USAGE)), + pomXml(POM, spec -> spec.after(pom -> assertThat(pom) + .contains("jakarta.xml.bind-api").actual())) + ), + mavenProject("other", + srcMainJava(java("class B {}")), + pomXml(POM.replace("app", "other")) + ) + ); + } + + private static String withDependency(String scope) { + return POM.replace("", """ + + + jakarta.xml.bind + jakarta.xml.bind-api + 3.0.1 + %s + + + """.formatted(scope)); + } +} diff --git a/src/test/java/org/openrewrite/java/migrate/javax/AddJaxbApiForUnattributedImportsTest.java b/src/test/java/org/openrewrite/java/migrate/javax/AddJaxbApiForUnattributedImportsTest.java index b1ade45286..339f5126c2 100644 --- a/src/test/java/org/openrewrite/java/migrate/javax/AddJaxbApiForUnattributedImportsTest.java +++ b/src/test/java/org/openrewrite/java/migrate/javax/AddJaxbApiForUnattributedImportsTest.java @@ -69,7 +69,7 @@ String encode(byte[] bytes) { @Test void scopeToNearestModuleAndTestSources() { rewriteRun( - spec -> spec.recipe(new AddJaxbApiForImports()).typeValidationOptions(TypeValidation.none()), + spec -> spec.recipe(new AddApiDependencyForImports("javax.xml.bind", "jakarta.xml.bind", "jakarta.xml.bind-api", "2.3.x")).typeValidationOptions(TypeValidation.none()), java( "import javax.xml.bind.DatatypeConverter; class Test {}", spec -> spec.path("app/src/test/java/Test.java")