Project#solve#

Schedules a Project and accepts the scheduled dates as its baseline. Pass a ProjectData to load a project, or null to reschedule after apply. The other read-only calls (preview, evaluate, suggestAssignments and the rest) need a solved project.

For a one-shot run that keeps no state, use Engine.schedule.

Signature#

public ScheduleResult solve(ProjectData data, SolveOptions options)

Synchronous and CPU-only. Changes the project's state. Not synchronized: serialize calls on one instance.

Parameters#

Name Type Description
data ProjectData Replacement data, or null to schedule the current state
options SolveOptions Subtree, analytics and reporting switches. Must not be null

Behavior#

  • A non-null data is deep-copied, validated, installed, scheduled and accepted. The previous data is discarded. Later changes to the caller's ProjectData object don't reach the project. ProjectOptions.validation decides whether invalid data is rejected or repaired.
  • null schedules the current state when it has unsolved edits. When the project is already solved with equal options, solve returns the same cached result object without scheduling again. The cache key is the whole SolveOptions value, compared by value.

Tasks touched by successful apply calls since the last solve appear in updates as direct updates, even when the planner leaves them where the edit put them. A cyclic project returns unchanged dates and keeps those tasks pending.

The result's baselineId names the accepted baseline. It changes only when the data or the dates change, so solving an unchanged state keeps it.

Returns#

The ScheduleResult. The project keeps it as its cached result and shares it with later calls and copies. Treat it as read-only, or call deepClone() before changing it.

Errors#

All exceptions are unchecked.

Error When
InputException A non-null data fails validation. The previous state and cached result are kept.
ProjectException with code == ProjectError.NEEDS_RESYNC data is null after an apply rejected an operation and no solve(data, …) followed
NullPointerException options is null

Example#

Load a project, commit an edit and reschedule it.

import java.util.List;
import org.dhtmlx.plen.*;

public class SolveExample {
  public static void main(String[] args) throws Exception {
    Moment monday = Moment.fromYmdHm(2026, 8, 10, 8, 0);
    ProjectData data = new ProjectData()
        .withTasks(List.of(new TaskData(Id.str("a")).withStartDate(monday).withDuration(2.0)));

    SolveOptions options = new SolveOptions();
    Project project = new Project();
    ScheduleResult loaded = project.solve(data, options);

    // Nothing changed: the cached result comes back with the same baseline id.
    ScheduleResult again = project.solve(null, options);
    System.out.println(again.baselineId.equals(loaded.baselineId)); // true

    SchedulingChanges changes = new SchedulingChanges();
    changes.tasks.update.add(new TaskUpdate(Id.str("a")).withDuration(Patch.of(3.0)));
    project.apply(changes);

    ScheduleResult result = project.solve(null, options);
    for (Mutation update : result.updates) {
      System.out.println("task " + update.id + ": " + update.startDate + " .. " + update.endDate);
      // task a: 2026-08-10 08:00 .. 2026-08-13 08:00
    }
  }
}