Upgrading
Sections run newest first: start at the top and read down to the section for the release after the one you are on. Each lists what the release notes flag as able to stop a build that compiled, or to change what a program does. Removals in 0.7.0 and Removals in 0.6.0 list the APIs due to go in those releases, with the recipe that migrates each, and Removals in 0.5.0 those 0.5.0 removed.
Removals in 0.7.0
Each of these compiles with javac's [removal] warning, which fails a -Werror build. The parCollect forms each gave the list toList() gives: a stream is read one pull at a time, so they ran nothing in parallel. The org.higherkindedj.openrewrite.MigrateDeprecationsTo0_7_0 recipe runs every recipe the table names, and marks each call it cannot rewrite safely, as 0.7.0 deprecation migration explains.
| Deprecated | Since | Use instead | Recipe |
|---|---|---|---|
VStream.closeAfterFailure(stream, failure) | 0.6.0 | stream.close(); a failed mapTask task gives a Step.Fail, whose tail you close as an Emit's | By hand |
VStreamPar.parCollect(stream, batchSize) | 0.6.0 | stream.toList() | ReplaceParCollectWithToListRecipe |
VStreamPath.parCollect(batchSize) | 0.6.0 | toList() on the path | ReplaceParCollectWithToListRecipe |
PathOps.parCollectVStream(path, batchSize) | 0.6.0 | path.toList() | ReplaceParCollectWithToListRecipe |
Try.foldFailureFirst and TryPath.foldFailureFirst | 0.6.0 | fold(failureMapper, successMapper), the same two functions in the same order | RenameTryFoldFailureFirst |
Operation.FOLD_FAILURE_FIRST | 0.6.0 | Operation.FOLD, which Try.fold reports | By hand |
NaturalTransformation<F, G>, in org.higherkindedj.hkt.effect | 0.6.0 | Natural<F, G>, which it extends | ReplaceNaturalTransformationWithNatural |
FreePath.foldMapWith(interpreter, monad) | 0.6.0 | foldMap(interpreter, monad) | ReplaceNaturalTransformationWithNatural |
FreeApPath.foldMapWith(interpreter, applicative) | 0.6.0 | foldMapKind(interpreter, applicative) | ReplaceNaturalTransformationWithNatural |
Removals in 0.6.0
Each of these compiles with javac's [removal] warning, which fails a -Werror build. A Focus path shortcut's replacement is its typed form: the same verb, given an instance that reads the element type from the path. So a typed form fits only a path that focuses on its container exactly. The org.higherkindedj.openrewrite.MigrateDeprecationsTo0_6_0 recipe runs every recipe the table names, and marks each call a typed form does not fit rather than rewriting it. 0.6.0 deprecation migration gives each such call its replacement.
| Deprecated | Since | Use instead | Recipe |
|---|---|---|---|
A Focus path's each(), on FocusPath, AffinePath, TraversalPath and a navigator | 0.5.0 | each(EachInstances.listEach()) | ReplaceUntypedPathShortcutsRecipe |
A Focus path's some() | 0.5.0 | some(FocusPaths.optionalSome()) | ReplaceUntypedPathShortcutsRecipe |
A Focus path's at(index) | 0.5.0 | via(FocusPaths.listAt(index)) | ReplaceUntypedPathShortcutsRecipe |
A Focus path's atKey(key) | 0.5.0 | via(FocusPaths.mapAt(key)) | ReplaceUntypedPathShortcutsRecipe |
A Focus path's traverseOver(traverse) | 0.5.0 | each(EachInstances.fromTraverse(traverse)) | ReplaceUntypedPathShortcutsRecipe |
A Focus path's head(), last(), tail() and init() | 0.5.0 | via(FocusPaths.listHead()), via(FocusPaths.listLast()), via(FocusPaths.listTail()) and via(FocusPaths.listInit()) | ReplaceUntypedPathShortcutsRecipe |
A Focus path's cons() and headTail() | 0.5.0 | via(FocusPaths.listCons()) and via(FocusPaths.listHeadTail()) | ReplaceUntypedPathShortcutsRecipe |
A Focus path's snoc() and initLast() | 0.5.0 | via(FocusPaths.listSnoc()) and via(FocusPaths.listInitLast()) | ReplaceUntypedPathShortcutsRecipe |
ScopeJoiner.resultEither() | 0.5.0 | joinEither() on the Scope, in place of join(); for a StructuredTaskScope you open yourself, the value its join() returns, or the cause of the FailedException it throws | By hand |
Removals in 0.5.0
0.5.0 removed each of these. The org.higherkindedj.openrewrite.MigrateDeprecationsTo0_5_0 recipe runs every recipe the table names, and finds each removed API only while the project is on 0.4.x, so run it before you move. See 0.5.0 deprecation migration.
| Deprecated | Since | Use instead | Recipe |
|---|---|---|---|
KindValidator.narrowWithPattern | 0.4.4 | KindValidator.narrowHolder | RenameKindValidatorNarrowWithPattern |
StateTKind.narrowK | 0.4.5 | StateTKind.narrow | RenameStateTKindNarrowK |
StateT.evalStateT(state) and execStateT(state), and the StateTKindHelper forms without a monad | 0.4.6 | The overloads that take the Monad<F> | By hand |
StateT.monadF() | 0.4.6 | The outer Monad<F> you built the stack with, kept in your own reference | By hand |
Try.fold and TryPath.fold, success first | 0.4.6 | foldFailureFirst(failureMapper, successMapper), or from 0.6.0 fold(failureMapper, successMapper) | SwapTryFoldToFoldFailureFirstRecipe |
Each.eachWithIndex() | 0.4.7 | Narrow to EachIndexed and call indexedTraversal() | By hand |
@PathConfig | 0.4.11 | Nothing, since it has no effect; to rename a Path, set suffix on @PathSource | RemovePathConfig |
@PathSource capability EFFECTFUL | 0.4.11 | CHAINABLE, which generates the same | ReplaceDeprecatedPathSourceCapabilitiesRecipe |
@PathSource capability ACCUMULATING | 0.4.11 | RECOVERABLE, which generates the same | ReplaceDeprecatedPathSourceCapabilitiesRecipe |
StateT also changes shape in 0.5.0: its monadF record component goes, so two StateT values with the same state function compare equal whichever Monad built them. Its equals, hashCode and toString change with it. Its constructor, StateT.create and StateTKindHelper.stateT take the state function alone, and StateT.mapT takes only the transformation. The RemoveStateTMonadArgument recipe drops the Monad argument from each call. It ships in hkj-openrewrite 0.5.0 and joins the same group, so run the group before your project moves off 0.4.11. A StateT held in var over a witness with a type argument, such as EitherKind.Witness<E>, then needs its types named: StateT.<S, EitherKind.Witness<E>, A>create(fn).
fold returns on Try and TryPath in 0.6.0, failure first. Going straight to 0.6.0 by hand, find each call while still on 0.4.x, where javac's deprecation warning names it. Swap its two functions in the change that moves to 0.6.0; on 0.5.x the name is foldFailureFirst. To 0.6.0 says why.
To 0.6.0
This release is not out yet. Upgrading from 0.5.0 collects what it changes so far, and Removals in 0.6.0 lists the APIs it is due to remove, with the recipe that migrates each.
0.6.0 brings back fold on Try and TryPath, failure first, so a success-first fold left over from 0.4.x compiles again wherever both its functions accept either argument, and runs the two the wrong way round. On a Try<String>, t.fold(v -> true, e -> false) gave true for a success on 0.4.x, and gives true for a failure on 0.6.0. A constant, Object::toString or String::valueOf in either place does the same. Nothing warns you, so a project on 0.4.x takes these steps in order, with hkj-openrewrite 0.6.x for each run:
- While the project still compiles against 0.4.x, run
MigrateDeprecationsTo0_5_0, which swaps each success-firstfoldintofoldFailureFirst, as To 0.5.0 says. Under-Werror, runMigrateDeprecationsTo0_6_0in the same pass. - Replace each jar compiled against 0.4.x: rebuild it from migrated source, or take a release of it built against 0.5.0 or later. Such a jar calls the same method signature, so on 0.6.0 it runs its
foldcalls swapped, or fails with aClassCastExceptioninside one, where on 0.5.0 it threwNoSuchMethodError. - Move to 0.6.0, then run
MigrateDeprecationsTo0_7_0, which renames eachfoldFailureFirstthe swap wrote tofold. 0.6.0 deprecatesfoldFailureFirst, so until then a-Werrorbuild fails, and a rewrite plugin that compiles the project first needs-Werrorlifted for the run.
Already moved without step 1? Run it on your last commit on 0.4.x, or check each fold on a Try or TryPath by hand. On 0.4.x the recipe swaps every fold, one written for 0.6.0 included.
To 0.5.0
The 0.5.0 notes give the details in Upgrading from 0.4.11. Run MigrateDeprecationsTo0_5_0 first, while the project is still on 0.4.11, since its recipes find the APIs in Removals in 0.5.0 only there. Before you upgrade lists that step and the others to take first. Then read What a running program can notice, most of it about null values, because the compiler cannot point at those changes. Each entry in What stops a build that compiled fails at a line the message names, with its fix. That table's entries for a nullness checker leave out a lambda that returns null through VTask.of, Try.of, IO.delay or another factory taking a JDK Supplier or Callable. NullAway flags one only with the two options in What a nullness checker sees.
To 0.4.11
The 0.4.11 notes give the details in Upgrading from 0.4.10. Read Before you upgrade first, since a library that publishes specs must be rebuilt before the builds that consume it. Then read What a running program can notice, because the processor cannot point at those changes. Each entry in What stops a build that compiled fails at a line the message names, with its fix.
To 0.4.10
The details are in each group of the 0.4.10 notes.
- A sparse PATCH scans a same-typed container for
null: anullelement, which used to reach the domain, now reports astags.1: must not be null. - Explicit type witnesses on some
@ImportOpticsmethods stop compiling: a generated method's type parameters can fall, asOpticsSpec<Pair<A, String>>now generates<A>. Drop the witnesses: the inferred result is unchanged. - The processor refuses some
@InstanceOffocuses: one naming a type argument the source does not pin, and a parameterised member of a generic type. - A resolved
copyConstructoris emitted as a cast: the cast can select a different constructor than ran in 0.4.9, so check overloaded types withLensLaws. - Generated signatures carry
@Nullable: a nullness checker in your build can report differently. @GenerateFocusrefuses a raw or wildcardSetorCollection: such a component used to throwClassCastExceptionon first use. Name the type argument.- Three navigator return types move to what the static method reports: a
Collectionsubtype such asArrayListis aFocusPathover the container. A nestedList<Optional<String>>composes to the leaf, so drop a trailing.some(). - An SPI container of non-navigable elements stops at the container: set
widenCollections = trueon the declaring record to widen it as before. - Four more
@Nullableannotations widen toAffinePath: JSpecify's, JetBrains', AndroidX's and SpotBugs'. Read such a component withgetOptional. Traversals.forSet()andtraverseSetreturn an unmodifiable set: they used to return a mutableLinkedHashSet.- A varargs bridge method takes a bare
nullonly with a cast: write(String[]) null. @GeneratePathBridgerefuses more shapes, and warns on an empty interface: it refuses a raw effect return type, a wildcardValidatederror type, and astaticorprivate@PathViamethod. An interface with no@PathViamethod draws a warning, which fails a-Werrorbuild.- A
@ComposeEffectssupport class changes shape: each field must be aClass<XOp<?>>naming an@EffectAlgebra, andBoundSet<F>becomesBoundSet. Fix any field the processor refuses, then recompile, and the last effect dispatches at its correct depth. discarded-effectreports a deferred Path dropped as a statement: such asPath.io(() -> 1).peek(log). The check is an error by default, so such a statement stops the build.
To 0.4.9
The details are in the 0.4.9 notes.
- An all-
FieldErrorresponse is a 422, not a 400 (#627): sethkj.web.validation-field-error-status: 400to keep the old status. - A
nullon a wire parses as a located error:parseand a fallibleassembleused to throwNullPointerException. At a Spring boundary a 500 becomes a 422. - A list element's failure carries its index:
emails: not an email addressbecomesemails.1: not an email address. - A leaf naming no domain component is a compile error: so is a spec method that collides with a generated member (#654).
- A leaf on a projected component now takes effect: the projection then offers the validated
patchin place ofasLens(), so a call toasLens()stops compiling. - Unused
hkj-springconfiguration properties are removed (#642): delete the keys, since none changed behaviour. Code that read them programmatically stops compiling. hkj.security.validated-user-detailsdefaults tofalseand starts empty (#642): the sample accounts moved toValidatedUserDetailsService.withSampleUsers(), so enabling it without registering accounts fails every login.- A JWT with a missing or malformed authorities claim is a 401 (#642): set
hkj.security.reject-missing-authorities-claim: falseto accept a missing claim. - An SSE response commits after the stream's first element (#642): a stream failing at its start returns the configured failure status. Emit an early heartbeat on a stream that stays idle.
- Ambiguous effect-boundary interpreters fail at startup (#642): the choice used to follow scan order silently.
To 0.4.1 through 0.4.8
Besides the deprecations in Removals in 0.5.0, the notes for these releases flag these changes.
- 0.4.1:
FreegainsHandleErrorandApcases: an exhaustiveswitchoverFreestops compiling until it handles them, andAddHandleErrorCaseRecipefinds such a switch.Free'sFbound tightens toWitnessArity<TypeArity.Unary>. See the 0.4.1 notes. - 0.4.2: Effect Path handlers honour
@ResponseStatus: an annotated handler method now answers with its status, such as201for a POST. See the 0.4.2 notes. - 0.4.2:
hkj.web.either.default-error-statustakes effect (#490): the property used not to bind. The flathkj.web.default-error-statusstill works as an alias. - 0.4.3: error class names match status keywords by whole word:
RevalidationErrorno longer matches thevalidationheuristic, so its status can change. See the 0.4.3 notes. - 0.4.5: the compile-time checker gains eleven checks: the build plugins enable it, so a finding at error stops the build and one at warning fails a
-Werrorbuild. See Compile-Time Checks. - 0.4.5: every Effect Path prints one
toStringform (#530): a test that compares the old text fails. See the 0.4.5 notes. - 0.4.7: the checker's
raw-kindcheck warns on a rawKind: the warning fails a-Werrorbuild. See the 0.4.7 notes. - 0.4.7:
recoverWithrejects anullargument at once (#553): on everyMonadError, where some instances used to fail later.
To 0.3.5
VTask.run()no longer declaresthrows Throwable: it wraps a checked exception inVTaskExecutionException, so code that caught a checked exception fromrun()catches the wrapper instead. See the 0.3.5 notes.
To 0.3.0
Kindcarries its arity from 0.3.0: type parameters used as witnesses needWitnessAritybounds, and theAddArityBoundsrecipe adds them. See Arity migration and the 0.3.0 notes.
Previous: Release History Next: Unreleased: 0.6.0