sdk

Write Apache Airflow Dags and tasks in Java, Kotlin, Scala or any other JVM language.

It requires Java 11 or later.

Quick start

Apply the Gradle plugin, and add the SDK and its annotation processor:

plugins {
id("org.apache.airflow.sdk") version "<version>"
}

dependencies {
annotationProcessor("org.apache.airflow:airflow-sdk-processor:<version>")
implementation("org.apache.airflow:airflow-sdk:<version>")
}

airflowBundle {
mainClass = "com.mycompany.airflow.hello.Main"
}

Replace <version> with a release from Maven Central.

Declare a Dag with @Airflow.Dag, its tasks with @Airflow.Task, and its graph in an @Airflow.Deps class. Passing the value one task returns into another is how the tasks depend on each other:

package com.mycompany.airflow.hello;

import org.apache.airflow.sdk.*;

@Airflow.Dag(id = "java_hello", schedule = "@daily", queue = "java")
public class HelloDag {

@Airflow.Task
public long extract() {
return 42L;
}

@Airflow.Task
public void report(long rows) {
System.out.println("extracted " + rows + " rows");
}

@Airflow.Deps
static class Wiring implements HelloDagDeps {
void depends() {
report(extract());
}
}
}

Serve it from the main class:

package com.mycompany.airflow.hello;

import org.apache.airflow.sdk.Bundle;
import org.apache.airflow.sdk.Server;

public class Main {
public static void main(String[] args) {
Server.create(args).serve(new Bundle().register(HelloDag.class));
}
}

Build the bundle with ./gradlew bundle, and see the Java SDK guide for deploying it, and for everything a Dag declared in Java can do.

Language SDK compatibility matrix

Which Airflow TaskInstance states and capabilities the Java SDK currently supports. The normative meaning of each dimension is defined in the Language SDK conformance specification.

Min. Airflow version: 3.4.0 · supervisor schema: 2026-10-30

DimensionTierSupportedSince (Airflow)Since (SDK)Notes
TaskInstance states
state: successMUST✓3.4.01.0.0
state: failedMUST✓3.4.01.0.0
state: up_for_retryMUST✓3.4.01.0.0RetryTask
state: skippedSHOULD✓3.4.01.0.0a TriggerDagRun task that skips an existing run
state: deferredMAY✓3.4.01.0.0a TriggerDagRun task that waits with deferrable
state: up_for_rescheduleMAY✗––runtime does not emit RescheduleTask yet
state: awaiting_inputMAY✗––runtime does not emit AwaitInputTask yet
state: removedMAY✓3.4.01.0.0
Task runtime
capability: task-loggingMUST✓3.4.01.0.0SLF4J + JPL bridged to the task log
capability: xcom-read-writeMUST✓3.4.01.0.0
capability: connection-readMUST✓3.4.01.0.0
capability: variable-read-writeMUST✓3.4.01.0.0
capability: self-contained-bundleMUST✓3.4.01.0.0Airflow metadata embedded in the jar artifact
capability: retry-policyMAY✗––no task-facing retry-policy API yet
capability: task-state-storeMAY✓3.4.01.0.0Client.getTaskStateStore() get/set/delete/clear
capability: asset-state-storeMAY✗––no task-facing asset state-store API yet
capability: asset-event-emitMAY✗––runtime does not emit asset events yet
capability: asset-event-readMAY✗––no task-facing asset-event API yet
capability: object-storeMAY✗––no object-storage API yet
capability: listenersMAY✗––no hook into the Python listener API, so a task emits no OpenLineage facets of its own
Dag definition
capability: dag-definition-authoringSHOULD✓3.4.01.0.0
capability: dag-argsMUST †✓3.4.01.0.0
capability: task-argsMUST †✓3.4.01.0.0
capability: dag-paramsMUST †✗––
capability: dag-callbacksMAY †✗––
capability: explicit-dependenciesMUST †✓3.4.01.0.0before / after, or @Airflow.Deps
capability: edge-labelsMAY †✓3.4.01.0.0Label.of(text).on(task)
capability: taskflow-dependenciesMUST †✓3.4.01.0.0
capability: task-groupMAY †✓3.4.01.0.0
capability: task-loopsMAY †✗––
capability: if-else-branchingSHOULD †✓3.4.01.0.0DagDef.If or @Airflow.If
capability: switch-case-branchingSHOULD †✓3.4.01.0.0DagDef.Switch or @Airflow.Switch
capability: trigger-dag-runMAY †✓3.4.01.0.0TriggerDagRun
capability: dynamic-dag-generationMAY †✓3.4.01.0.0
capability: human-in-the-loopMAY †✗––
capability: dag-testSHOULD †✗––
capability: asset-definitionMAY †✗––
capability: asset-schedulingMAY †✗––
capability: mapped-tasksMAY †✗––
capability: asset-inlets-outletsMAY †✗––
capability: task-callbacksMAY †✗––no SDK-defined task callbacks
Python Dag with stub TaskHandler
capability: mixed-lang-stub-targetMUST✓3.4.01.0.0@task.stub
capability: taskflow-bindingMUST✓3.4.01.0.0mapped stubs excluded
capability: mapped-tasksMAY✗––Airflow does not bind arguments to mapped stubs yet
capability: asset-inlets-outletsMAY✗––runtime does not report task outlets yet
capability: task-callbacksMAY✗––a Python-declared task callback does not run for a stub task

Marks: ✓ supported · ✗ not supported · n/a not applicable. A tier marked † applies only when dag-definition-authoring is supported.

Packages

Link copied to clipboard