이 콘텐츠는 선택한 언어로 제공되지 않습니다.
Chapter 1. Changes that are not compatible with OptaPlanner 7.x or earlier
The changes listed in this section are not compatible with OptaPlanner 7.x or earlier versions of OptaPlanner.
Java 11 or higher required
Major, Public API
If you are using JRE or JDK 8, upgrade to JDK 11 or higher.
On Linux, get OpenJDK from your Linux software repository. On Fedora and Red Hat Enterprise Linux, enter the following command:
sudo dnf install java-11-openjdk-devel
sudo dnf install java-11-openjdk-develCopy to Clipboard Copied! Toggle word wrap Toggle overflow - On Windows and macOS, download OpenJDK from the AdoptOpenJDK website.
SolverFactory and PlannerBenchmarkFactory no longer support KIE containers
Major, Public API
Because OptaPlanner now aligns with Kogito, the KIE container concept no longer applies. Therefore, SolverFactory no longer allows you to create Solver instances from KIE containers. This also applies to PlannerBenchmarkFactory and benchmarks.
OSGi metadata removed
Major, Public API
Because of the limited usage of OSGi and the maintenance burden it brings, the OptaPlanner JAR files in the OptaPlanner 8.x series no longer include OSGi metadata in the META-INF/MANIFEST.MF file.
Refrain from using Java serialization
Minor, Public API
In OptaPlanner 8, most uses of the Serializable marker interface were removed from the public API. Consider serializing with JSON or another format.
SolverFactory.getScoreDirectorFactory() replaced with ScoreManager
Major, Public API
In version 7 of OptaPlanner, using ScoreDirectorFactory was necessary in order to explain the score. In version 8 of OptaPlanner, new functionality was added to the ScoreManager and as a result there is no longer any reason to create new instances of ScoreDirector.
An example from a *.java file in OptaPlanner 7:
ScoreDirectorFactory<CloudBalance> scoreDirectorFactory = solverFactory.getScoreDirectorFactory();
try (ScoreDirector<CloudBalance> scoreDirector = scoreDirectorFactory.buildScoreDirector()) {
scoreDirector.setWorkingSolution(solution);
Score score = scoreDirector.calculateScore();
}
ScoreDirectorFactory<CloudBalance> scoreDirectorFactory = solverFactory.getScoreDirectorFactory();
try (ScoreDirector<CloudBalance> scoreDirector = scoreDirectorFactory.buildScoreDirector()) {
scoreDirector.setWorkingSolution(solution);
Score score = scoreDirector.calculateScore();
}
An example from a *.java file in OptaPlanner 8:
ScoreManager<CloudBalance> scoreManager = ScoreManager.create(solverFactory); Score score = scoreManager.updateScore(solution);
ScoreManager<CloudBalance> scoreManager = ScoreManager.create(solverFactory);
Score score = scoreManager.updateScore(solution);
Methods that allowed you to retrieve an instance of ScoreDirector and ScoreDirectorFactory have been removed from the public API without replacement. A reduced version of the ScoreDirector interface was promoted to the public API to promote the ProblemFactChange interface to the public API.
SolverFactory: getSolverConfig() removed
Minor, Public API
The SolverFactory.getSolverConfig() method has been deprecated and replaced with the SolverFactory.create(SolverConfig) method. A SolverConfig instance is now instantiated before a SolverFactory instance is instantiated, which is more natural. The previous order has been removed.
An example from a *.java file in OptaPlanner 7:
SolverFactory<MySolution> solverFactory = SolverFactory.createFromXmlResource(".../mySolverConfig.xml");
SolverConfig solverConfig = solverFactory.getSolverConfig();
...
Solver<MySolution> solver = solverFactory.buildSolver();
SolverFactory<MySolution> solverFactory = SolverFactory.createFromXmlResource(".../mySolverConfig.xml");
SolverConfig solverConfig = solverFactory.getSolverConfig();
...
Solver<MySolution> solver = solverFactory.buildSolver();
An example from a *.java file in OptaPlanner 8:
SolverConfig solverConfig = SolverConfig.createFromXmlResource(".../mySolverConfig.xml");
...
SolverFactory<MySolution> solverFactory = SolverFactory.create(solverConfig);
Solver<MySolution> solver = solverFactory.buildSolver();
SolverConfig solverConfig = SolverConfig.createFromXmlResource(".../mySolverConfig.xml");
...
SolverFactory<MySolution> solverFactory = SolverFactory.create(solverConfig);
Solver<MySolution> solver = solverFactory.buildSolver();
If you were also passing a ClassLoader, pass it to both SolverConfig.createFromXmlResource() and SolverFactory.create().
SolverConfig: buildSolver() removed
Minor, Public API
The SolverConfig.buildSolver() method is an inner method that does not belong in the public API. Use the SolverFactory.buildSolver() method instead.
An example from a *.java file in OptaPlanner 7:
SolverConfig solverConfig = SolverConfig.createFromXmlResource(".../mySolverConfig.xml");
...
Solver<MySolution> solver = solverConfig.buildSolver();
SolverConfig solverConfig = SolverConfig.createFromXmlResource(".../mySolverConfig.xml");
...
Solver<MySolution> solver = solverConfig.buildSolver();
An example from a *.java file in OptaPlanner 8:
SolverConfig solverConfig = SolverConfig.createFromXmlResource(".../mySolverConfig.xml");
...
SolverFactory<MySolution> solverFactory = SolverFactory.create(solverConfig);
Solver<MySolution> solver = solverFactory.buildSolver();
SolverConfig solverConfig = SolverConfig.createFromXmlResource(".../mySolverConfig.xml");
...
SolverFactory<MySolution> solverFactory = SolverFactory.create(solverConfig);
Solver<MySolution> solver = solverFactory.buildSolver();
PlannerBenchmarkConfig: buildPlannerBenchmark() removed
Minor, Public API
The PlannerBenchmarkConfig.buildPlannerBenchmark() method is an inner method that does not belong in the public API. Use the PlannerBenchmarkFactory.buildPlannerBenchmark() method instead.
An example from a *.java file in OptaPlanner 7:
PlannerBenchmarkConfig benchmarkConfig = PlannerBenchmarkConfig.createFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
...
PlannerBenchmark benchmark = benchmarkFactory.buildPlannerBenchmark();
PlannerBenchmarkConfig benchmarkConfig = PlannerBenchmarkConfig.createFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
...
PlannerBenchmark benchmark = benchmarkFactory.buildPlannerBenchmark();
An example from a *.java file in OptaPlanner 8:
PlannerBenchmarkConfig benchmarkConfig = PlannerBenchmarkConfig.createFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
...
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.create(benchmarkConfig);
PlannerBenchmark benchmark = benchmarkFactory.buildPlannerBenchmark();
PlannerBenchmarkConfig benchmarkConfig = PlannerBenchmarkConfig.createFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
...
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.create(benchmarkConfig);
PlannerBenchmark benchmark = benchmarkFactory.buildPlannerBenchmark();
SolverFactory: cloneSolverFactory() removed
Minor, Public API
The SolverFactory.cloneSolverFactory() method has been deprecated and replaced with the new SolverConfig(SolverConfig) copy constructors and the SolverFactory.cloneSolverFactory() method has been removed.
An example from a *.java file in OptaPlanner 7:
An example from a *.java file in OptaPlanner 8:
SolverFactory: createEmpty() removed
Minor, Public API
The SolverFactory.createEmpty() method has been deprecated and replaced with the new SolverConfig() method. The SolverFactory.createEmpty() method has been removed.
An example from a *.java file in OptaPlanner 7:
SolverFactory<MySolution> solverFactory = SolverFactory.createEmpty(); SolverConfig solverConfig = solverFactory.getSolverConfig() ... Solver<MySolution> solver = solverFactory.buildSolver();
SolverFactory<MySolution> solverFactory = SolverFactory.createEmpty();
SolverConfig solverConfig = solverFactory.getSolverConfig()
...
Solver<MySolution> solver = solverFactory.buildSolver();
An example from a *.java file in OptaPlanner 8:
SolverConfig solverConfig = new SolverConfig(); ... SolverFactory<MySolution> solverFactory = SolverFactory.create(solverConfig); Solver<MySolution> solver = solverFactory.buildSolver();
SolverConfig solverConfig = new SolverConfig();
...
SolverFactory<MySolution> solverFactory = SolverFactory.create(solverConfig);
Solver<MySolution> solver = solverFactory.buildSolver();
XML <solver/> root element now belongs to the http://www.optaplanner.org/xsd/solver namespace
Major, Public API
OptaPlanner now provides an XML schema definition for the solver configuration. Although OptaPlanner retains compatibility with previous versions of the existing XML configuration, migrating to the XSD is strongly recommended because OptaPlanner might support only valid configuration XML in the future.
An example from the *SolverConfig.xml file in OptaPlanner 7:
<?xml version="1.0" encoding="UTF-8"?> <solver> ... </solver>
<?xml version="1.0" encoding="UTF-8"?>
<solver>
...
</solver>
An example from the *SolverConfig.xml file in OptaPlanner 8:
<?xml version="1.0" encoding="UTF-8"?> <solver xmlns="https://www.optaplanner.org/xsd/solver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.optaplanner.org/xsd/solver https://www.optaplanner.org/xsd/solver/solver.xsd"> ... </solver>
<?xml version="1.0" encoding="UTF-8"?>
<solver xmlns="https://www.optaplanner.org/xsd/solver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.optaplanner.org/xsd/solver https://www.optaplanner.org/xsd/solver/solver.xsd">
...
</solver>
Using the XSD might require reordering some of the XML elements of the configuration. Use code completion in the IDE to migrate to a valid XML.
Property subPillarEnabled in move selector configuration has been removed
Minor, Public API
The subPillarEnabled property in PillarSwapMoveSelector and PillarChangeMoveSelector has been deprecated and replaced with a new property, subPillarType. The subPillarEnabled property has been removed.
An example from the *SolverConfig.xml and *BenchmarkConfig.xml files in OptaPlanner 7:
An example from the *SolverConfig.xml and *BenchmarkConfig.xml files in OptaPlanner 8:
Solver: getScoreDirectorFactory() removed
Major, Public API
The getScoreDirectorFactory() method has been deprecated and has now been removed from both Solver and SolverFactory classes.
You no longer need to create a Solver instance just to calculate or explain a score in the UI. Use the ScoreManager API instead.
An example from a *.java file in OptaPlanner 7:
SolverFactory<VehicleRoutingSolution> solverFactory = SolverFactory.createFromXmlResource(...); Solver<VehicleRoutingSolution> solver = solverFactory.buildSolver(); uiScoreDirectorFactory = solver.getScoreDirectorFactory(); ...
SolverFactory<VehicleRoutingSolution> solverFactory = SolverFactory.createFromXmlResource(...);
Solver<VehicleRoutingSolution> solver = solverFactory.buildSolver();
uiScoreDirectorFactory = solver.getScoreDirectorFactory();
...
An example from a *.java file in OptaPlanner 8:
SolverFactory<VehicleRoutingSolution> solverFactory = SolverFactory.createFromXmlResource(...); ScoreManager<VehicleRoutingSolution> scoreManager = ScoreManager.create(solverFactory); ...
SolverFactory<VehicleRoutingSolution> solverFactory = SolverFactory.createFromXmlResource(...);
ScoreManager<VehicleRoutingSolution> scoreManager = ScoreManager.create(solverFactory);
...
ScoreDirectorFactory should not be used anymore because it has always been outside the public API and all of its functionality is exposed in various parts of the public API.
Solver.explainBestScore() has been removed
Major, Public API
The explainBestScore() method on the Solver interface was deprecated in 7.x and has now been removed. You can obtain the same information through the new ScoreManager API.
Red Hat recommends that you do not parse the results of this method call in any way.
An example from a *.java file in OptaPlanner 7:
solver = ...; scoreExplanation = solver.explainBestScore();
solver = ...;
scoreExplanation = solver.explainBestScore();
An example from a *.java file in OptaPlanner 8:
MySolution solution = ...; ScoreManager<MySolution> scoreManager = ...; scoreExplanation = scoreManager.explainScore(solution);
MySolution solution = ...;
ScoreManager<MySolution> scoreManager = ...;
scoreExplanation = scoreManager.explainScore(solution);
The Solver interface methods getBestSolution(), getBestScore(), and getTimeMillisSpent() have been removed
Minor, Public API
Several methods on the Solver interface were deprecated in 7.x and have been removed. You can obtain the same information by registering an EventListener through the Solver.addEventListener(…).
An example from a *.java file in OptaPlanner 7:
solver = ...; solution = solver.getBestSolution(); score = solver.getBestScore(); timeMillisSpent = solver.getTimeMillisSpent();
solver = ...;
solution = solver.getBestSolution();
score = solver.getBestScore();
timeMillisSpent = solver.getTimeMillisSpent();
An example from a *.java file in OptaPlanner 8:
Annotation scanning has been removed
Major, Public API
The <scanAnnotatedClasses/> directive in the solver configuration was deprecated in 7.x and is now removed.
An example from the *.xml file in OptaPlanner 7:
<solver>
...
<scanAnnotatedClasses/>
...
</solver>
<solver>
...
<scanAnnotatedClasses/>
...
</solver>
An example from the *.xml file in OptaPlanner 8:
New package for @PlanningFactProperty and @PlanningFactCollectionProperty
Major, Public API
The @PlanningFactProperty and @PlanningFactCollectionProperty annotations now share the same package with other similar annotations, such as @PlanningSolution. The old annotations were deprecated in 7.x and removed.
An example from a *.java file in OptaPlanner 7:
import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty; import org.optaplanner.core.api.domain.solution.drools.ProblemFactProperty;
import org.optaplanner.core.api.domain.solution.drools.ProblemFactCollectionProperty;
import org.optaplanner.core.api.domain.solution.drools.ProblemFactProperty;
An example from a *.java file in OptaPlanner 8:
import org.optaplanner.core.api.domain.solution.ProblemFactCollectionProperty; import org.optaplanner.core.api.domain.solution.ProblemFactProperty;
import org.optaplanner.core.api.domain.solution.ProblemFactCollectionProperty;
import org.optaplanner.core.api.domain.solution.ProblemFactProperty;
filterClassList replaced with a single filter class
Minor, Public API
The configuration of EntitySelector, ValueSelector, and MoveSelector now has a single filter class in both the configuration API and the solver configuration XML.
In practice, you do not need multiple selection filter classes often, and you can replace them with a single selection filter class that implements the logic of all of them. Passing a single selection class now requires less boilerplate code.
An example from a *.java file in OptaPlanner 7:
ValueSelectorConfig valueSelectorConfig = new ValueSelectorConfig(); valueSelectorConfig.setFilterClassList(Collections.singletonList(MySelectionFilterClass.class));
ValueSelectorConfig valueSelectorConfig = new ValueSelectorConfig();
valueSelectorConfig.setFilterClassList(Collections.singletonList(MySelectionFilterClass.class));
An example from a *.java file in OptaPlanner 8:
ValueSelectorConfig valueSelectorConfig = new ValueSelectorConfig(); valueSelectorConfig.setFilterClass(MySelectionFilterClass.class);
ValueSelectorConfig valueSelectorConfig = new ValueSelectorConfig();
valueSelectorConfig.setFilterClass(MySelectionFilterClass.class);
Replacing multiple selection filter classes with a single selection filter class
An example from the *.xml file in OptaPlanner 7:
An example from a *.java file in OptaPlanner 7:
An example from the *.xml file in OptaPlanner 8:
<swapMoveSelector>
<entitySelector>
<filterClass>com.example.SingleEntityFilter</filterClass>
</entitySelector>
</swapMoveSelector>
<swapMoveSelector>
<entitySelector>
<filterClass>com.example.SingleEntityFilter</filterClass>
</entitySelector>
</swapMoveSelector>
An example from a *.java file in OptaPlanner 8:
AcceptorConfig renamed to LocalSearchAcceptorConfig
Minor
This only impacts the configuration API. The solver configuration XML file remains intact.
Naming consistency with other local-search-specific configuration classes has been implemented.
An example from a *.java file in OptaPlanner 7:
LocalSearchPhaseConfig localSearchPhaseConfig = new LocalSearchPhaseConfig()
.withAcceptorConfig(new AcceptorConfig().withEntityTabuSize(5));
LocalSearchPhaseConfig localSearchPhaseConfig = new LocalSearchPhaseConfig()
.withAcceptorConfig(new AcceptorConfig().withEntityTabuSize(5));
An example from a *.java file in OptaPlanner 8:
LocalSearchPhaseConfig localSearchPhaseConfig = new LocalSearchPhaseConfig()
.withAcceptorConfig(new LocalSearchAcceptorConfig().withEntityTabuSize(5));
LocalSearchPhaseConfig localSearchPhaseConfig = new LocalSearchPhaseConfig()
.withAcceptorConfig(new LocalSearchAcceptorConfig().withEntityTabuSize(5));
Custom properties XML configuration format changes
Minor, Public API
This issue only impacts the solver configuration XML, specifically <scoreDirectorFactory/>, <moveIteratorFactory/>, <moveListFactory/>, <partitionedSearch/> and <customPhase/>.
This change was made to enforce the structure of the configuration XML in build time.
An example from the *.xml file in OptaPlanner 7:
An example from the *.xml file in OptaPlanner 8:
<variableNameInclude/> elements are now wrapped by the <variableNameIncludes/> element
Minor, Public API
This update only impacts the solver configuration XML, specifically the <swapMoveSelector/> and <pillarSwapMoveSelector/> elements.
This change was made to enforce the structure of the configuration XML in build time.
An example from the *.xml file in OptaPlanner 7:
<swapMoveSelector> <variableNameInclude>variableA</variableNameInclude> <variableNameInclude>variableB</variableNameInclude> </swapMoveSelector>
<swapMoveSelector>
<variableNameInclude>variableA</variableNameInclude>
<variableNameInclude>variableB</variableNameInclude>
</swapMoveSelector>
An example from the *.xml file in OptaPlanner 8:
Solution interface removed
Minor, Public API
The Solution interface was deprecated and removed. The AbstractSolution interface, which is only used by Business Central, has also been removed.
Remove the Solution interface, annotate the getScore() method with @PlanningScore, and replace the getProblemFacts() method with a @ProblemFactCollectionProperty annotation directly on every problem fact getter (or field).
An example from a *.java file in OptaPlanner 7:
An example from a *.java file in OptaPlanner 8:
For a single problem fact that is not wrapped in a Collection, use the @ProblemFactProperty annotation, as shown in the following example, with field annotations this time:
An example from a *.java file in OptaPlanner 7:
An example from a *.java file in OptaPlanner 8:
Do not add the @ProblemFactCollectionProperty annotation on getters (or fields) that have a @PlanningEntityCollectionProperty annotation.
BestSolutionChangedEvent: isNewBestSolutionInitialized() removed
Minor, Public API
The BestSolutionChangedEvent.isNewBestSolutionInitialized() method has been deprecated and replaced with the BestSolutionChangedEvent.getNewBestSolution().getScore().isSolutionInitialized() method. The BestSolutionChangedEvent.isNewBestSolutionInitialized() method has been removed.
An example from a *.java file in OptaPlanner 7:
An example from a *.java file in OptaPlanner 8:
If you check isFeasible(), it checks if the solution is initialized.
An example from a *.java file in OptaPlanner 8:
<valueSelector>: variableName is now an attribute
Minor, Public API
When power-tweaking move selectors, such as <changeMoveSelector>, in a use case with multiple planning variables, the <variableName> XML element has been replaced with a variableName="…" XML attribute. This change reduces the solver configuration verbosity. After being deprecated for the entire 7.x series, the old way has now been removed.
An example from the *SolverConfig.xml and *BenchmarkConfig.xml files in OptaPlanner 7:
<valueSelector>
<variableName>room</variableName>
</valueSelector>
<valueSelector>
<variableName>room</variableName>
</valueSelector>
An example from the *SolverConfig.xml and *BenchmarkConfig.xml files in OptaPlanner 8:
<valueSelector variableName="room"/>
<valueSelector variableName="room"/>
Partitioned Search: threadFactoryClass removed
Minor, Public API
Because <solver> has supported a <threadFactoryClass> element for some time, the <threadFactoryClass> element under <partitionedSearch> has been removed.
An example from the *SolverConfig.xml and *BenchmarkConfig.xml files in OptaPlanner 7:
An example from the *SolverConfig.xml and *BenchmarkConfig.xml files in OptaPlanner 8:
SimpleDoubleScore and HardSoftDoubleScore removed
Minor, Public API
The use of double-based score types is not recommended because they can cause score corruption. They have been removed.
An example from a *.java file in OptaPlanner 7:
An example from a *.java file in OptaPlanner 8:
Score.toInitializedScore() removed
Minor, Public API
The Score.toInitializedScore() method was deprecated and replaced with the Score.withInitScore(int) method in 7.x and is now removed.
An example from a *.java file in OptaPlanner 7:
score = score.toInitializedScore();
score = score.toInitializedScore();
An example from a *.java file in OptaPlanner 8:
score = score.withInitScore(0);
score = score.withInitScore(0);
Various justification Comparators removed
Minor, Public API
The following Comparator implementations were deprecated in 7.x and removed:
-
org.optaplanner.core.api.score.comparator.NaturalScoreComparator -
org.optaplanner.core.api.score.constraint.ConstraintMatchScoreComparator -
org.optaplanner.core.api.score.constraint.ConstraintMatchTotalScoreComparator -
org.optaplanner.core.api.score.constraint.IndictmentScoreComparator
An example from a *.java file in OptaPlanner 7:
NaturalScoreComparator comparator = new NaturalScoreComparator(); ConstraintMatchScoreComparator comparator2 = new ConstraintMatchScoreComparator();
NaturalScoreComparator comparator = new NaturalScoreComparator();
ConstraintMatchScoreComparator comparator2 = new ConstraintMatchScoreComparator();
An example from a *.java file in OptaPlanner 8:
Comparator<Score> comparator = Comparable::compareTo; Comparator<ConstraintMatch> comparator2 = Comparator.comparing(ConstraintMatch::getScore);
Comparator<Score> comparator = Comparable::compareTo;
Comparator<ConstraintMatch> comparator2 = Comparator.comparing(ConstraintMatch::getScore);
FeasibilityScore removed
Minor, Public API
The FeasibilityScore interface was deprecated in 7.x and its only method isFeasible() moved to the Score supertype. The interface has now been removed.
You should refer to Scores by their ultimate type, for example HardSoftScore instead of to Score.
@PlanningEntity.movableEntitySelectionFilter removed
Minor, Public API
The movableEntitySelectionFilter field on the @PlanningEntity annotation was deprecated in 7.x and a new field pinningFilter has been introduced with a name that shows the relation to the @PlanningPin annotation. This filter implements a new PinningFilter interface, returning true if the entity is pinned, and false if movable. The logic of this new filter is therefore inverted as compared to the old filter.
You should update your @PlanningEntity annotations by supplying the new filter instead of the old filter. The old filter has now been removed.
An example from a *.java file in OptaPlanner 7:
@PlanningEntity(movableEntitySelectionFilter = MyMovableEntitySelectionFilter.class)
@PlanningEntity(movableEntitySelectionFilter = MyMovableEntitySelectionFilter.class)
An example from a *.java file in OptaPlanner 8:
@PlanningEntity(pinningFilter = MyPinningFilter.class)
@PlanningEntity(pinningFilter = MyPinningFilter.class)
@PlanningVariable.reinitializeVariableEntityFilter removed
Minor, Public API
The reinitializeVariableEntityFilter field on the @PlanningVariable annotation was deprecated in 7.x and now removed.
*ScoreHolder classes turned into interfaces
Minor, Public API
In OptaPlanner 7, ScoreHolder classes, used exclusively for Drools score calculation, exposed a number of public methods which, if used, allowed the user to unintentionally corrupt or otherwise negatively affect their scores.
In OptaPlanner 8, these methods have been removed and the classes have been turned into interfaces. Most users do not use the removed and potentially harmful methods.
However, if you do use these methods, you will find suitable replacements in the public API in areas of score explanation and constraint configuration.
ValueRangeFactory class now final
Minor
ValueRangeFactory class is a factory class that has only static methods. There is no need for you to extend this class, and it has therefore been made final.
An example from a *.java file in OptaPlanner 7:
class MyValueRangeFactory extends ValueRangeFactory {
...
}
class MyValueRangeFactory extends ValueRangeFactory {
...
}
An example from a *.java file in OptaPlanner 8:
class MyValueRangeFactory {
...
}
class MyValueRangeFactory {
...
}
ConstraintMatchTotal and Indictment are now interfaces
Minor, Public API
ConstraintMatchTotal and Indictment classes have been converted into interfaces. As a result, their implementations were moved out of the public API, together with methods that allowed them to mutate their state. These methods were never intended for the public API, and therefore there is no replacement for them.
You might still need the instances themselves if you choose to implement ConstraintMatchAwareIncrementalScoreCalculator:
ConstraintMatchTotal maximumCapacityMatchTotal = new ConstraintMatchTotal(...);
ConstraintMatchTotal maximumCapacityMatchTotal = new ConstraintMatchTotal(...);
An example from a *.java file in OptaPlanner 8:
ConstraintMatchTotal maximumCapacityMatchTotal = new DefaultConstraintMatchTotal(...);
ConstraintMatchTotal maximumCapacityMatchTotal = new DefaultConstraintMatchTotal(...);
ScoreManager: generic type Score added
Major, Public API
The ScoreManager and ScoreExplanation APIs now have the generic type Score to avoid downcasts in your code, for example from Score to HardSoftScore.
An example from a *.java file in OptaPlanner 7:
@Inject // or @Autowired
ScoreManager<TimeTable> scoreManager;
@Inject // or @Autowired
ScoreManager<TimeTable> scoreManager;
An example from a *.java file in OptaPlanner 8:
@Inject // or @Autowired
ScoreManager<TimeTable, HardSoftScore> scoreManager;
@Inject // or @Autowired
ScoreManager<TimeTable, HardSoftScore> scoreManager;
An example from a *.java file in OptaPlanner 7:
ScoreExplanation<TimeTable> explanation = scoreManager.explainScore(timeTable);
HardSoftScore score = (HardSoftScore) explanation.getScore();
ScoreExplanation<TimeTable> explanation = scoreManager.explainScore(timeTable);
HardSoftScore score = (HardSoftScore) explanation.getScore();
An example from a *.java file in OptaPlanner 8:
ScoreExplanation<TimeTable, HardSoftScore> explanation = scoreManager.explainScore(timeTable);
HardSoftScore score = explanation.getScore();
ScoreExplanation<TimeTable, HardSoftScore> explanation = scoreManager.explainScore(timeTable);
HardSoftScore score = explanation.getScore();
ConstraintMatchTotal, ConstraintMatch, and Indictment: generic type Score added
Major
Similar to ScoreManager and ScoreExplanation, the ConstraintMatchTotal, ConstraintMatch, and Indictment APIs now have a generic type Score to avoid downcasts in your code, for example from Score to HardSoftScore.
An example from a *.java file in OptaPlanner 7:
ScoreExplanation<TimeTable> explanation = scoreManager.explainScore(timeTable);
Map<String, ConstraintMatchTotal> constraintMatchTotalMap = scoreExplanation.getConstraintMatchTotalMap();
ConstraintMatchTotal constraintMatchTotal = constraintMatchTotalMap.get(contraintId);
HardSoftScore totalScore = (HardSoftScore) constraintMatchTotal.getScore();
ScoreExplanation<TimeTable> explanation = scoreManager.explainScore(timeTable);
Map<String, ConstraintMatchTotal> constraintMatchTotalMap = scoreExplanation.getConstraintMatchTotalMap();
ConstraintMatchTotal constraintMatchTotal = constraintMatchTotalMap.get(contraintId);
HardSoftScore totalScore = (HardSoftScore) constraintMatchTotal.getScore();
An example from a *.java file in OptaPlanner 8:
ScoreExplanation<TimeTable, HardSoftScore> explanation = scoreManager.explainScore(timeTable);
Map<String, ConstraintMatchTotal<HardSoftScore>> constraintMatchTotalMap = scoreExplanation.getConstraintMatchTotalMap();
ConstraintMatchTotal<HardSoftScore> constraintMatchTotal = constraintMatchTotalMap.get(contraintId);
HardSoftScore totalScore = constraintMatchTotal.getScore();
ScoreExplanation<TimeTable, HardSoftScore> explanation = scoreManager.explainScore(timeTable);
Map<String, ConstraintMatchTotal<HardSoftScore>> constraintMatchTotalMap = scoreExplanation.getConstraintMatchTotalMap();
ConstraintMatchTotal<HardSoftScore> constraintMatchTotal = constraintMatchTotalMap.get(contraintId);
HardSoftScore totalScore = constraintMatchTotal.getScore();
An example from a *.java file in OptaPlanner 7:
ScoreExplanation<TimeTable> explanation = scoreManager.explainScore(timeTable);
Map<Object, Indictment> indictmentMap = scoreExplanation.getIndictmentMap();
Indictment indictment = indictmentMap.get(lesson);
HardSoftScore totalScore = (HardSoftScore) indictment.getScore();
ScoreExplanation<TimeTable> explanation = scoreManager.explainScore(timeTable);
Map<Object, Indictment> indictmentMap = scoreExplanation.getIndictmentMap();
Indictment indictment = indictmentMap.get(lesson);
HardSoftScore totalScore = (HardSoftScore) indictment.getScore();
An example from a *.java file in OptaPlanner 8:
ScoreExplanation<TimeTable, HardSoftScore> explanation = scoreManager.explainScore(timeTable);
Map<Object, Indictment<HardSoftScore>> indictmentMap = scoreExplanation.getIndictmentMap();
Indictment<HardSoftScore> indictment = indictmentMap.get(lesson);
HardSoftScore totalScore = indictment.getScore();
ScoreExplanation<TimeTable, HardSoftScore> explanation = scoreManager.explainScore(timeTable);
Map<Object, Indictment<HardSoftScore>> indictmentMap = scoreExplanation.getIndictmentMap();
Indictment<HardSoftScore> indictment = indictmentMap.get(lesson);
HardSoftScore totalScore = indictment.getScore();
ConstraintMatchAwareIncrementalScoreCalculator: generic type Score added
Minor
The interface ConstraintMatchAwareIncrementalScoreCalculator now also has a generic type parameter for Score to avoid raw type usages of ConstraintMatchTotal and Indictment.
An example from a *.java file in OptaPlanner 7:
An example from a *.java file in OptaPlanner 8:
AbstractCustomPhaseCommand was removed
Minor, Public API
The abstract class AbstractCustomPhaseCommand was removed. Any class that extends it should directly implement the CustomPhaseCommand interface.
An example from a *.java file in OptaPlanner 7:
An example from a *.java file in OptaPlanner 8:
Score calculators moved to the public API
Major
The interfaces EasyScoreCalculator, IncrementalScoreCalculator, and ConstraintMatchAwareIncrementalScoreCalculator have moved to a new package in the public API. Their deprecated counterparts have been removed. The deprecated class org.optaplanner.core.impl.score.director.incremental.AbstractIncrementalScoreCalculator has also been removed. Replace the use of the removed interfaces and classes with their counterparts in the public API.
An example from the EasyScoreCalculator.java file in OptaPlanner 7:
An example from the EasyScoreCalculator.java file in OptaPlanner 8:
An example from the IncrementalScoreCalculator.java file in OptaPlanner 7:
An example from the IncrementalScoreCalculator.java file in OptaPlanner 8:
An example from the ConstraintMatchAwareIncrementalScoreCalculator.java file in OptaPlanner 7:
An example from the ConstraintMatchAwareIncrementalScoreCalculator.java file in OptaPlanner 8:
PlannerBenchmarkFactory: createFromSolverFactory() removed
Major, Public API
The PlannerBenchmarkFactory.createFromSolverFactory() method has been deprecated and replaced with the PlannerBenchmarkFactory.createFromSolverConfigXmlResource(String) method. The PlannerBenchmarkFactory.createFromSolverFactory() method has been removed.
An example from a *.java file in OptaPlanner 7:
SolverFactory<CloudBalance> solverFactory = SolverFactory.createFromXmlResource(
".../cloudBalancingSolverConfig.xml");
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.createFromSolverFactory(solverFactory);
SolverFactory<CloudBalance> solverFactory = SolverFactory.createFromXmlResource(
".../cloudBalancingSolverConfig.xml");
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.createFromSolverFactory(solverFactory);
An example from a *.java file in OptaPlanner 8:
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.createFromSolverConfigXmlResource(
".../cloudBalancingSolverConfig.xml");
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.createFromSolverConfigXmlResource(
".../cloudBalancingSolverConfig.xml");
If you programmatically adjust the solver configuration, you can use PlannerBenchmarkConfig.createFromSolverConfig(SolverConfig) and then PlannerBenchmarkFactory.create(PlannerBenchmarkConfig) instead.
PlannerBenchmarkFactory: getPlannerBenchmarkConfig() removed
Minor, Public API
The PlannerBenchmarkFactory.getPlannerBenchmarkConfig() method has been deprecated and replaced with the PlannerBenchmarkFactory.create(PlannerBenchmarkConfig) method. A PlannerBenchmarkConfig instance is now instantiated before a PlannerBenchmarkFactory instance is instantiated. This order is more logical. PlannerBenchmarkFactory.getPlannerBenchmarkConfig() has been removed.
An example from a *.java file in OptaPlanner 7:
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.createFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
PlannerBenchmarkConfig benchmarkConfig = benchmarkFactory.getPlannerBenchmarkConfig();
...
PlannerBenchmark benchmark = benchmarkFactory.buildPlannerBenchmark();
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.createFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
PlannerBenchmarkConfig benchmarkConfig = benchmarkFactory.getPlannerBenchmarkConfig();
...
PlannerBenchmark benchmark = benchmarkFactory.buildPlannerBenchmark();
An example from a *.java file in OptaPlanner 8:
PlannerBenchmarkConfig benchmarkConfig = PlannerBenchmarkConfig.createFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
...
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.create(benchmarkConfig);
PlannerBenchmark benchmark = benchmarkFactory.buildPlannerBenchmark();
PlannerBenchmarkConfig benchmarkConfig = PlannerBenchmarkConfig.createFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
...
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.create(benchmarkConfig);
PlannerBenchmark benchmark = benchmarkFactory.buildPlannerBenchmark();
XML <plannerBenchmark/> root element now belongs to the http://www.optaplanner.org/xsd/benchmark namespace
Minor, Public API
OptaPlanner now provides an XML Schema Definition (XSD) for the benchmark configuration. Although OptaPlanner keeps compatibility with earlier versions of the existing XML configuration, migrating to the XSD is strongly recommended because OptaPlanner might support only valid configuration XML in the future.
An example from the *BenchmarkConfig.xml file in OptaPlanner 7:
<?xml version="1.0" encoding="UTF-8"?> <plannerBenchmark> ... </plannerBenchmark>
<?xml version="1.0" encoding="UTF-8"?>
<plannerBenchmark>
...
</plannerBenchmark>
An example from the *BenchmarkConfig.xml file in OptaPlanner 8:
<?xml version="1.0" encoding="UTF-8"?> <plannerBenchmark xmlns="https://www.optaplanner.org/xsd/benchmark" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.optaplanner.org/xsd/benchmark https://www.optaplanner.org/xsd/benchmark/benchmark.xsd"> ... </plannerBenchmark>
<?xml version="1.0" encoding="UTF-8"?>
<plannerBenchmark xmlns="https://www.optaplanner.org/xsd/benchmark" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.optaplanner.org/xsd/benchmark https://www.optaplanner.org/xsd/benchmark/benchmark.xsd">
...
</plannerBenchmark>
Using the XSD might require reordering some of the XML elements of the configuration. Use code completion in the IDE to migrate to a valid XML.
ProblemBenchmarksConfig: xStreamAnnotatedClass removed
Major, Public API
The <xStreamAnnotatedClass/> has been removed from the <problemBenchmarks/> configuration together with the corresponding getXStreamAnnotatedClassList() and setXStreamAnnotatedClassList() methods in the ProblemBenchmarksConfig class.
An example from a *.java file in OptaPlanner 7:
ProblemBenchmarksConfig problemBenchmarksConfig = new ProblemBenchmarksConfig(); problemBenchmarksConfig.setXStreamAnnotatedClassList(MySolution.class);
ProblemBenchmarksConfig problemBenchmarksConfig = new ProblemBenchmarksConfig();
problemBenchmarksConfig.setXStreamAnnotatedClassList(MySolution.class);
An example from a *.java file in OptaPlanner 8:
An example from the *BenchmarkConfig.xml file in OptaPlanner 7:
An example from the *BenchmarkConfig.xml file in OptaPlanner 8:
BenchmarkAggregatorFrame.createAndDisplay(PlannerBenchmarkFactory) removed
Minor
The BenchmarkAggregatorFrame.createAndDisplay(PlannerBenchmarkFactory) method has been deprecated and replaced with the BenchmarkAggregatorFrame.createAndDisplayFromXmlResource(String) method. The BenchmarkAggregatorFrame.createAndDisplay(PlannerBenchmarkFactory) method has been removed.
An example from a *.java file in OptaPlanner 7:
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.createFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
BenchmarkAggregatorFrame.createAndDisplay(benchmarkFactory);
PlannerBenchmarkFactory benchmarkFactory = PlannerBenchmarkFactory.createFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
BenchmarkAggregatorFrame.createAndDisplay(benchmarkFactory);
An example from a *.java file in OptaPlanner 8:
BenchmarkAggregatorFrame.createAndDisplayFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
BenchmarkAggregatorFrame.createAndDisplayFromXmlResource(
".../cloudBalancingBenchmarkConfig.xml");
If you programmatically adjust the benchmark configuration, you can use BenchmarkAggregatorFrame.createAndDisplay(PlannerBenchmarkConfig) instead.
Removed JavaScript expression support in configuration
Minor
Various elements of both the solver configuration and benchmark configuration no longer support nested JavaScript expressions. You must replace these with either auto-configuration or with integer constants.
An example from the solverConfig.xml file in OptaPlanner 7:
<solver>
...
<moveThreadCount>availableProcessorCount - 1</moveThreadCount>
...
</solver>
<solver>
...
<moveThreadCount>availableProcessorCount - 1</moveThreadCount>
...
</solver>
An example from the `solverConfig.xml`file in OptaPlanner 8:
<solver>
...
<moveThreadCount>1</moveThreadCount> <!-- Alternatively, use "AUTO" or omit entirely. -->
...
</solver>
<solver>
...
<moveThreadCount>1</moveThreadCount> <!-- Alternatively, use "AUTO" or omit entirely. -->
...
</solver>
An example from the benchmarkConfig.xml file in OptaPlanner 7:
<plannerBenchmark>
...
<parallelBenchmarkCount>availableProcessorCount - 1</parallelBenchmarkCount>
...
</plannerBenchmark>
<plannerBenchmark>
...
<parallelBenchmarkCount>availableProcessorCount - 1</parallelBenchmarkCount>
...
</plannerBenchmark>
An example from the benchmarkConfig.xml file in OptaPlanner 8:
<plannerBenchmark>
...
<parallelBenchmarkCount>1</parallelBenchmarkCount> <!-- Alternatively, use "AUTO" or omit entirely. -->
...
</plannerBenchmark>
<plannerBenchmark>
...
<parallelBenchmarkCount>1</parallelBenchmarkCount> <!-- Alternatively, use "AUTO" or omit entirely. -->
...
</plannerBenchmark>
Removed the deprecated variable listeners
Major, Public API
The deprecated interface VariableListener from the package org.optaplanner.core.impl.domain.variable.listener has been removed, along with the deprecated interface StatefulVariableListener and the deprecated class VariableListenerAdapter in that same package. Use a VariableListener interface from the org.optaplanner.core.api.domain.variable package instead.
An example of a VariableListener.java file in OptaPlanner 7:
An example from a VariableListener.java file in OptaPlanner 8:
An example of a StatefulVariableListener.java file in OptaPlanner 7:
An example from the StatefulVariableListener.java file in OptaPlanner 8: