Upgrade Timefold Solver to the latest version
As Timefold Solver 2.x continues developing, we occasionally have to bring changes to our APIs. We will not break backwards compatibility during the lifetime of Timefold Solver 2.x, and that means your current code will not break. But we still want you to upgrade to the new APIs easily and quickly. We provide this upgrade recipe for users who choose to keep up to date with the latest and greatest in the solver space.
Many of the upgrade steps can be applied automatically using our migration tooling, but some manual changes may still be required. This upgrade recipe is intended to help you navigate those changes and upgrade your codebase with confidence.
1. Before you start
Throughout this document, we assume that you are upgrading from the latest available version of the 1.x line. Make sure to first upgrade to the 2.x version and only then follow this recipe.
Please refer to upgrade recipe for Timefold Solver 1.x or even upgrade recipe for OptaPlanner if you go way back.
2. Automatic upgrade to latest Timefold Solver
For many of the upgrade steps mentioned later, we provide a migration tool that can automatically apply those changes to Java files and Maven POMs. This tool is based on OpenRewrite and can be run as a Maven or Gradle plugin. To run the tool, execute the following command in your project directory:
-
Maven
-
Gradle
mvn org.openrewrite.maven:rewrite-maven-plugin:6.28.1:run -Drewrite.recipeArtifactCoordinates=ai.timefold.solver:timefold-solver-migration:SNAPSHOT -Drewrite.activeRecipes=ai.timefold.solver.migration.ToLatest
curl https://raw.githubusercontent.com/TimefoldAI/timefold-solver/refs/tags/vSNAPSHOT/tools/migration/upgrade-timefold.gradle > upgrade-timefold.gradle ; gradle -Dorg.gradle.jvmargs=-Xmx2G --init-script upgrade-timefold.gradle rewriteRun -DtimefoldSolverVersion=SNAPSHOT ; rm upgrade-timefold.gradle
Having done that, you can check the local changes and commit them.
For the time being, Kotlin users need to follow the upgrade recipe and apply the steps manually.
3. Manual upgrade recipe
In addition to the automated changes listed above, there are some changes that require manual intervention. Every upgrade note indicates how likely your code will be affected by that change:
-
Major: Likely to affect your code.
-
Minor: Less likely to affect your code, especially if you’ve been upgrading Timefold Solver regularly, paying attention to new deprecations.
-
Recommended: We think this won’t affect you, but we’re listing this just to be safe.
The upgrade recipe often lists the changes as they apply to Java code. We kindly ask Kotlin users to translate the changes accordingly.
3.1. Conceptual changes
These changes are most likely to require you to change your code in a non-mechanical way, and they can only be automated partially, if at all.
Deprecation of @ShadowVariableInconsistent
Details
The solver can optionally increase the performance of shadow variable processing on dense variable graphs, in exchange for the user removing the @ShadowVariableInconsistent from their domain model. See the detailed migration guide.
Custom moves must declare exactly the list variable range they change
Details
A custom move that changes a list variable must bracket that change with beforeListVariableChanged(entity, variableName, fromIndex, toIndex) and a matching afterListVariableChanged(…).
The solver now verifies each such pair, and throws IllegalArgumentException if:
-
a second
beforeListVariableChangedopens for an entity whose previous one has not been closed yet, -
an
afterListVariableChangedhas no matchingbeforeListVariableChanged, or one arrives twice, -
the two calls disagree on
fromIndex, -
the reported range does not account for every element the move added or removed.
Previously the solver accepted these and silently corrupted the solution when the move was undone.
If your move now fails, make its range cover everything it changes.
For example, appending one element to the end of a list is beforeListVariableChanged(entity, "valueList", size, size) followed by afterListVariableChanged(entity, "valueList", size, size + 1).
4. Changes to preview features
The API of preview features is not yet entirely stable, and changes based on user feedback can be expected. This section lists all such changes, so that users of preview features can adapt. All feedback is much appreciated!
4.1. Timefold Solver 2.7.0 hides move implementations
The concrete Move implementations of the Neighborhoods API (such as ChangeMove and ListChangeMove) are no longer public.
Build moves through the Moves factory class instead;
see built-in moves for the replacement.