Files
airflow/java-sdk
Kaxil Naik 872427c253 Version the worker-bound TaskInstance fields in the execution API schema (#68390)
The supervisor's task routing (added in #65958) reads queue, pool_slots and
priority_weight from the TaskInstance it receives, but those fields lived in
a TaskInstanceDTO duplicated between airflow-core and task-sdk and kept in
sync by an AST-comparison prek hook, outside the versioned execution API
schema the Task SDK datamodels are generated from.

Add the three fields to the execution API TaskInstance schema (with a Cadwyn
version change) and regenerate the SDK datamodels, so the generated
TaskInstance carries everything the supervisor needs. Re-point StartupDetails
and the coordinator interfaces at the generated model, fold the core
TaskInstanceDTO into a subclass of the schema model that only adds the
executor-side fields, and drop the duplicated task-sdk DTO and the sync hook.

The unused parent_context_carrier field (no readers or writers) is removed.

* Keep pool_slots and priority_weight executor-side; only queue joins the schema

The supervisor only routes on queue; pool_slots and priority_weight are
executor concerns (queued-workload priority ordering and edge concurrency
slot accounting) that the worker never reads. Keep them on the executor
DTO, serialized as before, and add only queue to the worker-facing schema.

The generated TaskInstance no longer accepts pool_slots/priority_weight
kwargs, its queue is Optional in the generated typing, and the DTO now
validates the inherited hostname field that the ECS adoption test's mock
did not set.
2026-06-11 19:39:21 +01:00
..
…
…
…

Airflow Java SDK

A JVM SDK for Apache Airflow. You can use any JVM-compatible language to write workflow bundles, and have Airflow consume the result.

The SDK and execution-time logic is implemented in Kotlin. An example is bundled showing how the SDK can be used in Java.

Building the SDK

./gradlew build

Building documentation

./gradlew dokkaGenerate

This uses Dokka to build documentation of the Java SDK. This generates both an HTML representation and Javadoc.

Running the example

  • Put the DAG with stub tasks to somewhere Airflow can find.

  • Ensure the java command is available in the same environment the Airflow task worker is in.

  • Package the example and its dependencies into JARs in ./example/build/install/example/lib

    ./gradlew :example:installDist
    
  • Configure Airflow to route tasks in the java queue to be run with Java:

    export AIRFLOW__SDK__COORDINATORS='{
      "java": {
        "classpath": "airflow.sdk.coordinators.java.JavaCoordinator",
        "kwargs": {"jars_root": ["/opt/airflow/java-sdk/example/build/install/example/lib"]}
      }
    }'
    export AIRFLOW__SDK__QUEUE_TO_COORDINATOR='{"java": "java"}'
    
  • Ensure the Connection and Variable needed by the example DAG are available:

    export AIRFLOW_CONN_TEST_HTTP='{
        "conn_type": "http",
        "login": "user",
        "password": "pass",
        "host": "example.com",
        "port": 1234,
        "extra": {"param1": "val1", "param2": "val2"}
    }'
    export AIRFLOW_VAR_MY_VARIABLE=123
    

Publishing

The SDK is published to Maven Central via the ASF Nexus staging repository. The full release process follows the ASF Maven publishing guide.

Prerequisites

Bump the version

Edit gradle.properties and set the version for this release:

sdkVersion=1.0.0

Commit the change and push it to the release branch.

Verify the POM locally

Before touching any remote repository, publish to your local Maven cache and inspect the generated POM:

./gradlew :sdk:publishToMavenLocal
cat ~/.m2/repository/org/apache/airflow/airflow-sdk/*/airflow-sdk-*.pom

Check that the coordinates, description, license, SCM, and organization fields look correct.

Dry-run against a local repository

To test the full publish flow without touching ASF infrastructure, override the repository URL to a local directory

./gradlew :sdk:publish -PmavenUrl=file:///tmp/local-maven-repo -PskipSigning
ls /tmp/local-maven-repo/org/apache/airflow/airflow-sdk/

NOTE: Signing is not required since nothing goes to Maven Central. If you want to test signing, set the GPG private key and passphrase as described in the next section, and remove -PskipSigning from the above command.

Publish to ASF Nexus staging

Store the credentials in ~/.gradle/gradle.properties so they are not exposed in your shell history:

mavenUsername=your-asf-nexus-token-username
mavenPassword=your-asf-nexus-token-password
signing.password=your-gpg-key-passphrase

Then run the publish task.

./gradlew :sdk:publish -P"signing.key=$(gpg --armor --export-secret-keys your-gpg-key-fingerprint)"

NOTE: The signing key is supplied through the command line since it contains newlines, which does not work well in a Gradle properties file.

NOTE: You can also use the following environment variables to provide the credentials instead: ASF_NEXUS_USERNAME, ASF_NEXUS_PASSWORD, SIGNING_KEY, and SIGNING_PASSWORD. This is especially useful on e.g. CI.

Technical Details

The user uses the SDK to implement a Java application that implements task methods, and metadata on which DAG and task each method should be used for.

When the Airflow Supervisor identifies a task should be run with Java, it launches the Java application as a subprocess. The Java application accepts flags --comm and --logs from the command line to identify TCP sockets it should connect to, and communicates with the Supervisor through these channels during execution.

  1. On connection, the Supervisor immediately sends a StartupDetails message through the comm socket.
  2. The Java application finds and executes the relevant method.
  3. During execution, the Java application uses the comm socket to retrieve information (e.g. Variable) from, and send data (e.g. XCom) to Airflow.
  4. The Java application informs the comm socket to tell the Supervisor the task's terminal state.
  5. The Java application exits.

During the Java application's lifetime, it also sends log messages generated by the SDK (not user code) through the logs socket, so the Supervisor can append them to Airflow logs.

Communication uses the same formats as the Python-based processes.

See Architectural Design Records in the adr directory to learn more.