[Canonical page](<https://docs.dhtmlx.com/planning-engine/java/api/engine-schedule/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# Engine.schedule

Schedules a [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/java/api/data/project-data.md>) snapshot once and returns the result. The call is stateless: it's the same as `new Project().solve(data, options)` on a temporary [`Project`](<https://docs.dhtmlx.com/planning-engine/java/api/project/project.md>) that's discarded when the call returns. Nothing is kept between calls. For a project that receives edits after the first schedule, use [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>).

## Signature

```java
public static ScheduleResult schedule(ProjectData data, SolveOptions options)
```

Synchronous and CPU-only. The same `data` and `options` always produce the same result.

## Parameters

| Name | Type | Description |
|---|---|---|
| `data` | [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/java/api/data/project-data.md>) | The full snapshot to schedule. Must not be `null` |
| `options` | [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md>) | Subtree, analytics and reporting switches. `new SolveOptions()` schedules the whole project. Must not be `null` |

## Behavior

`data` is deep-copied before scheduling, so the call never changes the caller's object. Validation always runs with [`Validation.STRICT`](<https://docs.dhtmlx.com/planning-engine/java/api/project/validation.md>).

## Returns

The [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md>). Its `baselineId` is set, but it names the baseline of the temporary project, so no later call can use it.

## Errors

All exceptions are unchecked.

| Error | When |
|---|---|
| [`InputException`](<https://docs.dhtmlx.com/planning-engine/java/api/errors/input-exception.md>) | `data` fails strict validation. The rules are listed on [`ProjectData`](<https://docs.dhtmlx.com/planning-engine/java/api/data/project-data.md>) |
| `NullPointerException` | `data` or `options` is `null` |

`schedule` never throws [`ProjectException`](<https://docs.dhtmlx.com/planning-engine/java/api/errors/project-exception.md>): each call starts from a fresh project.

## Example

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

public class ScheduleExample {
  public static void main(String[] args) throws Exception {
    Moment monday = Moment.fromYmdHm(2026, 1, 5, 8, 0);

    ProjectData data = new ProjectData()
        .withTasks(List.of(
            new TaskData(Id.str("design")).withStartDate(monday).withDuration(2.0),
            new TaskData(Id.str("build")).withStartDate(monday).withDuration(3.0)))
        .withLinks(List.of(
            new LinkData().withId(Id.str("l1"))
                .withSource(Id.str("design"))
                .withTarget(Id.str("build"))));

    ScheduleResult result = Engine.schedule(data, new SolveOptions());

    // Only tasks whose dates changed are reported.
    for (Mutation update : result.updates) {
      System.out.println(update.id + ": " + update.startDate + " .. " + update.endDate);
      // build: 2026-01-07 08:00 .. 2026-01-12 08:00
    }
  }
}
```

## Related

- [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/java/api/project/solve-options.md>) - subtree, analytics and reporting switches
- [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/java/api/results/schedule-result.md>) - the scheduled dates, conflicts and analytics it returns
- [`Project#solve`](<https://docs.dhtmlx.com/planning-engine/java/api/project-solve.md>) - the stateful call that keeps the project for later edits
- [One-shot scheduling](<https://docs.dhtmlx.com/planning-engine/java/scheduling/scheduling-a-project.md#one-shot-scheduling>) - when to schedule a snapshot without a project
- [Quick start](<https://docs.dhtmlx.com/planning-engine/java/quick-start.md#schedule-a-snapshot>) - scheduling two linked tasks end to end
