Cover legacy Bouncy Castle artifacts and their API changes - #1189
Merged
Conversation
The `jdk18on` recipe only handled `-jdk15on` and `-jdk15to18`, and neither recipe touched code, leaving callers on a dependency that no longer compiles. Dependency coordinates: - Migrate `-jdk12`, `-jdk14`, `-jdk15`, `-jdk15+` and `-jdk16` to `-jdk18on`, for every artifact where both sides are published. - Add the `bcprov-ext` counterparts to the existing `-jdk15on` and `-jdk15to18` migrations. API changes between 1.70 and 1.85: - `BouncyCastleDerStringGetInstanceReturnType` widens declared types to `ASN1*String` where the value comes from `DER*String.getInstance(..)`, which 1.71 pulled up to the supertype. - `BouncyCastleSphincsPlusToPqcLegacy` renames the SPHINCS+ package that 1.78 moved to `pqc.legacy` to make room for SLH-DSA.
Both were called out as follow-ups on the PR; ChangeDependency already collapses duplicate coordinates, so the bctsp mapping needs nothing extra. - Map `bctsp-*` onto `bcpkix`, which absorbed the time stamp protocol support in 1.47, in both the `jdk18on` and `jdk15to18` recipes. A pom holding both `bctsp-jdk15on` and `bcpkix-jdk15on` collapses to a single `bcpkix-jdk18on` dependency, which is pinned by a test. - Mirror the `-jdk12`, `-jdk14`, `-jdk15`, `-jdk15+` and `-jdk16` migrations onto `-jdk15to18` for the Java < 8 recipe.
timtebeek
marked this pull request as ready for review
August 10, 2026 16:21
mergify Bot
added a commit
to robfrank/linklift
that referenced
this pull request
Aug 20, 2026
…41.0 to 3.42.0 [skip ci] Bumps [org.openrewrite.recipe:rewrite-migrate-java](https://github.com/openrewrite/rewrite-migrate-java) from 3.41.0 to 3.42.0. Release notes *Sourced from [org.openrewrite.recipe:rewrite-migrate-java's releases](https://github.com/openrewrite/rewrite-migrate-java/releases).* > 3.42.0 > ------ > > What's Changed > -------------- > > * Adopt upstream XML trailing-comment formatting by [`@timtebeek`](https://github.com/timtebeek) in [openrewrite/rewrite-migrate-java#1180](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1180) > * Add mapping for CheckForNull to JSpecify annotation by [`@zbynek`](https://github.com/zbynek) in [openrewrite/rewrite-migrate-java#1179](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1179) > * Skip `UseSetOf`/`UseListOf` for `HashSet`/`ArrayList` subclasses by [`@timtebeek`](https://github.com/timtebeek) in [openrewrite/rewrite-migrate-java#1182](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1182) > * Avoid hardcoded patch version in UpdateSdkManTest by [`@timtebeek`](https://github.com/timtebeek) in [openrewrite/rewrite-migrate-java#1183](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1183) > * Only add the Mockito surefire agent configuration when asked, and keep it minimal by [`@timtebeek`](https://github.com/timtebeek) in [openrewrite/rewrite-migrate-java#1184](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1184) > * Make subpackage recursion explicit in the Jackson JAX-RS JSON rename by [`@timtebeek`](https://github.com/timtebeek) in [openrewrite/rewrite-migrate-java#1185](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1185) > * Add the Mockito agent properties goal in its own execution by [`@MBoegers`](https://github.com/MBoegers) in [openrewrite/rewrite-migrate-java#1186](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1186) > * Derive SDKMAN test versions from the candidate list by [`@timtebeek`](https://github.com/timtebeek) in [openrewrite/rewrite-migrate-java#1188](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1188) > * Do not apply `var` when the generic return type needs the declared type by [`@jevanlingen`](https://github.com/jevanlingen) in [openrewrite/rewrite-migrate-java#1187](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1187) > * Cover legacy Bouncy Castle artifacts and their API changes by [`@timtebeek`](https://github.com/timtebeek) in [openrewrite/rewrite-migrate-java#1189](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1189) > * Add jakarta.validation-api dependency when migrating com.sun.istack.NotNull by [`@steve-aom-elliott`](https://github.com/steve-aom-elliott) in [openrewrite/rewrite-migrate-java#1190](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1190) > > New Contributors > ---------------- > > * [`@zbynek`](https://github.com/zbynek) made their first contribution in [openrewrite/rewrite-migrate-java#1179](https://redirect.github.com/openrewrite/rewrite-migrate-java/pull/1179) > > **Full Changelog**: <openrewrite/rewrite-migrate-java@v3.41.0...v3.42.0> Commits * [`1238ceb`](openrewrite/rewrite-migrate-java@1238ceb) OpenRewrite recipe best practices * [`01d0fe8`](openrewrite/rewrite-migrate-java@01d0fe8) Add `jakarta.validation-api` dependency when migrating `com.sun.istack.NotNul... * [`33354b5`](openrewrite/rewrite-migrate-java@33354b5) Cover legacy Bouncy Castle artifacts and their API changes ([#1189](https://redirect.github.com/openrewrite/rewrite-migrate-java/issues/1189)) * [`6c648a5`](openrewrite/rewrite-migrate-java@6c648a5) Update Gradle wrapper to 9.7.0 * [`7099ad3`](openrewrite/rewrite-migrate-java@7099ad3) Do not apply `var` when the generic return type needs the declared type ([#1187](https://redirect.github.com/openrewrite/rewrite-migrate-java/issues/1187)) * [`ccfa7b0`](openrewrite/rewrite-migrate-java@ccfa7b0) Derive SDKMAN test versions from the candidate list ([#1188](https://redirect.github.com/openrewrite/rewrite-migrate-java/issues/1188)) * [`96e8647`](openrewrite/rewrite-migrate-java@96e8647) [Auto] SDKMAN! Java candidates as of 2026-08-10T1102 * [`26f898e`](openrewrite/rewrite-migrate-java@26f898e) Add the Mockito agent properties goal in its own execution ([#1186](https://redirect.github.com/openrewrite/rewrite-migrate-java/issues/1186)) * [`d82dd47`](openrewrite/rewrite-migrate-java@d82dd47) OpenRewrite recipe best practices * [`55f2e93`](openrewrite/rewrite-migrate-java@55f2e93) Make subpackage recursion explicit in the Jackson JAX-RS JSON rename ([#1185](https://redirect.github.com/openrewrite/rewrite-migrate-java/issues/1185)) * Additional commits viewable in [compare view](openrewrite/rewrite-migrate-java@v3.41.0...v3.42.0)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
BounceCastleFromJdk15OntoJdk18Ononly handled-jdk15onand-jdk15to18, and neither Bouncy Castle recipe touched code. Since the dependency change pinslatest.release, users land on 1.85.2 in a single hop, where some of their code no longer compiles.Dependency coordinates
Added every legacy suffix that has a published counterpart, to both the
jdk18onrecipe (Java 8+) and thejdk15to18recipe (Java < 8):-jdk16-jdk15+-jdk15-jdk14-jdk12Only pairs that actually exist on Maven Central are listed — there is no
bcjmail-jdk14, andbcpkix/bcutil/bctlsnever shipped-jdk15/-jdk15+/-jdk16.bctsp-*is frozen at 1.46 and was folded intobcpkixat 1.47, so all five surviving suffixes map ontobcpkix. This is not a suffix swap, so the concern was duplicate coordinates — butChangeDependencyalready collapses those, verified end to end: a pom holding bothbctsp-jdk15on:1.46andbcpkix-jdk15on:1.70comes out with a singlebcpkix-jdk18onelement.bctspAlongsideBcpkixCollapsesToASingleDependencyasserts both the resolved model and that the raw XML contains the artifact exactly once.bcprov-extis also added to the pre-existing-jdk15onand-jdk15to18sections in both recipes; migratingbcprov-jdk15onwhile leavingbcprov-ext-jdk15onbehind was an oversight. Notebcprov-ext-jdk18onstops at 1.78.1 whilebcprov-jdk18onis at 1.85.2 — still an upgrade, just not to current.API changes
I diffed the public/protected API of
bcprov/bcpg/bcpkix/bctls/bcutil/bcmailat jdk15on 1.70 against jdk18on 1.85.2 by parsing the class files. Two findings were worth automating:BouncyCastleDerStringGetInstanceReturnType— 1.71 pulledgetInstance(..)up from the 12DER*Stringtypes to theirASN1*Stringsupertypes. The call site still compiles, because static methods are inherited; what breaks is the return type:So the recipe widens the declared type rather than retargeting the call. Both the
DER*andASN1*types exist with identicalgetInstancesignatures at 1.70, so this compiles against either artifact and can be applied ahead of the upgrade. A blanketChangeTypeis not an option — theASN1*Stringtypes are all abstract, sonew DERIA5String(..)has to stay.BouncyCastleSphincsPlusToPqcLegacy— 1.78 movedorg.bouncycastle.pqc.crypto.sphincsplustoorg.bouncycastle.pqc.legacy.sphincsplusto free the original package for FIPS 205 SLH-DSA. All 19 types map 1:1, so it is a plainChangePackage.Not covered
Deliberate omissions, all verified against the same diff:
ASN1TaggedObject.getObject()/getObjectParser(int, boolean)— genuinely removed. Replacements (getBaseObject(),getExplicitBaseObject()) exist at 1.70, but the correct one depends on whether the tag is explicit or implicit, and guessing wrong is a silent parsing bug rather than a compile error. Better as a search recipe.ASN1ApplicationSpecificfamily — deleted; the replacement isASN1TaggedObject+BERTags.APPLICATION, a structural rework rather than a rename.pqc.math.linearalgebra,oer.its— removed outright, nothing to migrate to.org.bouncycastle.openpgpAPI andBouncyCastleProviderhave zero public member removals across 1.70 → 1.85.Testing
BouncyCastleTestgoes from 21 to 76 cases; versions are pinned per suffix to one that actually resolves (1.70for jdk14/jdk15on/jdk15to18,1.46for jdk15/jdk15+/jdk16/bctsp,130for jdk12), since the previously hardcoded1.70does not exist for the older artifacts. NewBouncyCastleApiTestcovers the two code recipes, including that constructors are left alone.Full suite green: 1844 tests, 0 failures.
One wart worth flagging:
alreadyDeclaredAsAsn1StringneedsexpectedCyclesThatMakeChanges(1)even though the printed source is unchanged, because upstreamChangeMethodInvocationReturnTypere-attributes the invocation type on every match. Harmless in a real run — no diff is produced — but it may be worth an upstream issue.recipes.csvregenerated with./gradlew rCG.