Files
Donald Pinckney 0c8586b4c2 Add Java SDK support (#42)
* Add Java SDK reference files (11 files)

Create complete Java reference documentation covering:
- java.md: Entry point with quick start tutorial, key concepts
- patterns.md: 17 patterns (signals, queries, updates, child workflows,
  saga, cancellation scopes, heartbeating, etc.)
- determinism.md: Safe alternatives table, forbidden operations
- determinism-protection.md: Convention-based enforcement (no sandbox)
- error-handling.md: ApplicationFailure, retry/timeout config
- gotchas.md: Non-deterministic operations, cancellation, heartbeating
- testing.md: TestWorkflowEnvironment, Mockito mocking, replay testing
- versioning.md: Workflow.getVersion(), worker versioning
- data-handling.md: Jackson, PayloadConverter, encryption, search attributes
- observability.md: SLF4J logging, Micrometer metrics
- advanced-features.md: Schedules, async completion, worker tuning

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix Java alignment issues from self-review

- Reduce gotchas.md Non-Deterministic Operations from ~94 lines to ~12
  (reference determinism.md instead of duplicating)
- Remove Workflow Failure Exception Types duplication from error-handling.md
  (keep only in advanced-features.md)
- Expand versioning.md Worker Versioning with Key Concepts, PINNED vs
  AUTO_UPGRADE, Deployment Strategies subsections
- Fix section names to match Python reference style:
  Activity Heartbeat Details, Handling Activity Errors,
  Retry Policy Configuration, Workflow Test Environment,
  Mocking Activities, Workflow Replay Testing
- Reduce data-handling.md Payload Encryption verbosity
- Reduce observability.md Logger Customization verbosity
- Reduce testing.md to single approach per section
- Rename determinism.md "Convention-Based Enforcement" to "SDK Protection"
- Fix handler guidance in patterns.md to match Python

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fix correctness issues in Java reference files

- patterns.md: Fix Queries section — ActivityStub → typed interface
  (Workflow.newActivityStub returns the typed interface, not ActivityStub)
- data-handling.md: Add missing ProtobufPayloadConverter to default
  converter chain (4th of 5 converters)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add Java to SKILL.md and core/determinism.md

- SKILL.md: Add "Temporal Java" trigger phrase, update Overview to
  list Java, add Java entry to Getting Started references
- core/determinism.md: Add Java entry to SDK Protection Mechanisms
  (no sandbox, convention-based, NonDeterministicException at replay)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Apply manual editorial fixes to Java references

- java.md: Remove "Understanding Replay" section (covered by Overview),
  simplify File Organization note (no sandbox rationale)
- gotchas.md: Move Heartbeating before Cancellation, make Wrong Retry
  Classification brief with reference (not inline examples)
- error-handling.md: Remove editorializing from Workflow Failure note
- determinism-protection.md: Remove cross-language comparison paragraph
  (state Java's approach on its own terms)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Add temporal-workflowcheck static analysis to Java determinism docs

- determinism-protection.md: Add "Static Analysis with temporal-workflowcheck"
  section with Gradle/Maven setup, manual run, and suppression instructions.
  Beta warning included.
- determinism.md: Update overview and SDK Protection to reference workflowcheck
- core/determinism.md: Update Java entry in SDK Protection Mechanisms

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Integrate feedback from Go PR into Java patterns

- Updates: Add validator note — validators must not mutate state or
  block (matches note added to Python, TypeScript, Go, and core)
- Saga Pattern: Use Workflow.newDetachedCancellationScope() for
  compensations so they execute even if the workflow is cancelled
  (mirrors Go's workflow.NewDisconnectedContext pattern)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>

* docs: add @WorkflowInit description to java.md Key Concepts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* mark java as supported

* Apply suggestions from code review

Co-authored-by: Brian Strauch <brian@brianstrauch.com>

* strongly recommend java 21+

* Softened stance on static checker and replay testing.

* address python/typescript sandboxing comment

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Brian Strauch <brian.strauch@temporal.io>
Co-authored-by: Brian Strauch <brian@brianstrauch.com>
2026-04-02 17:07:33 -04:00

56 lines
3.3 KiB
Markdown

# Java SDK Determinism
## Overview
The Java SDK has **no sandbox** (only Python and TypeScript have sandboxing). The Java SDK relies on developer conventions to enforce determinism. The SDK provides `Workflow.*` APIs as safe replacements for common non-deterministic operations. A static analysis tool (`temporal-workflowcheck`, beta) can catch violations at build time — see `references/java/determinism-protection.md`.
## Why Determinism Matters: History Replay
Temporal provides durable execution through **History Replay**. When a Worker needs to restore workflow state (after a crash, cache eviction, or to continue after a long timer), it re-executes the workflow code from the beginning, which requires the workflow code to be **deterministic**.
## SDK Protection
Java workflow code runs in a cooperative threading model where only one workflow thread executes at a time under a global lock. The SDK does not intercept or block non-deterministic calls at runtime. If you call a forbidden operation, it will silently succeed during the initial execution but cause a `NonDeterministicException` when the workflow is replayed.
`temporal-workflowcheck` (static analysis, beta) and `WorkflowReplayer` (replay testing) can help uncover some violations, but they are not exhaustive — careful code review and adherence to the rules below remain essential.
## Forbidden Operations
- `Thread.sleep()` — blocks the real thread, bypasses Temporal timers
- `new Thread()` or thread pools — breaks the cooperative threading model
- `synchronized` blocks and explicit locks — can deadlock with the workflow executor
- `UUID.randomUUID()` — non-deterministic across replays
- `Math.random()` or `new Random()` — non-deterministic across replays
- `System.currentTimeMillis()` or `Instant.now()` — non-deterministic across replays
- Direct I/O (network, filesystem, database) — side effects must run in activities
- Mutable global/static state — shared state breaks isolation between workflow instances
- `CompletableFuture` — bypasses the workflow scheduler; use `Promise` instead
## Safe Builtin Alternatives
| Forbidden | Safe Alternative |
|-----------|------------------|
| `Thread.sleep(millis)` | `Workflow.sleep(Duration.ofMillis(millis))` |
| `UUID.randomUUID()` | `Workflow.randomUUID()` |
| `Math.random()` | `Workflow.newRandom().nextInt()` |
| `System.currentTimeMillis()` | `Workflow.currentTimeMillis()` |
| `new Thread(runnable)` | `Async.function(func)` / `Async.procedure(proc)` |
| `CompletableFuture<T>` | `Promise<T>` / `CompletablePromise<T>` |
| `BlockingQueue<T>` | `WorkflowQueue<T>` |
| `Future<T>` | `Promise<T>` |
## Testing Replay Compatibility
Use the `WorkflowReplayer` class to verify your code changes are compatible with existing histories. See the Workflow Replay Testing section of `references/java/testing.md`.
## Best Practices
1. Use `Workflow.currentTimeMillis()` for all time operations
2. Use `Workflow.newRandom()` for random values
3. Use `Workflow.randomUUID()` for unique identifiers
4. Use `Async.function()` / `Async.procedure()` instead of raw threads
5. Use `Promise` and `CompletablePromise` instead of `CompletableFuture`
6. Test with `WorkflowReplayer` to catch non-determinism
7. Keep workflows focused on orchestration, delegate I/O to activities
8. Use `Workflow.getLogger()` for replay-safe logging