Repository navigation
Parse native Java Dags and show their source - #74036
Merged
Merged
Conversation
This was referenced Oct 1, 2026
jason810496
added this pull request to stack #74038
October 1, 2026 13:38
1 task done
jason810496
removed this pull request from stack #74038
October 1, 2026 15:13
jason810496
changed the base branch from
jason/lang-sdk-e2e/03-native-dag-parse
to
jason/lang-sdk-e2e/03e-lang-sdk-dag-bag
October 1, 2026 15:16
jason810496
force-pushed
the
jason/lang-sdk-e2e/04-java-dag-importer
branch
from
October 1, 2026 15:16
8ffd19e to
fce2457
Compare
This was referenced Oct 1, 2026
jason810496
added this pull request to stack #74044
October 1, 2026 15:18
kaxil
reviewed
Oct 1, 2026
jason810496
force-pushed
the
jason/lang-sdk-e2e/04-java-dag-importer
branch
from
October 2, 2026 00:54
fce2457 to
5a8f7c4
Compare
jason810496
force-pushed
the
jason/lang-sdk-e2e/04-java-dag-importer
branch
2 times, most recently
from
October 2, 2026 05:44
47500af to
b045547
Compare
pierrejeambrun
force-pushed
the
jason/lang-sdk-e2e/04-java-dag-importer
branch
from
October 2, 2026 09:00
b045547 to
81f9527
Compare
jason810496
force-pushed
the
jason/lang-sdk-e2e/04-java-dag-importer
branch
from
October 2, 2026 11:41
81f9527 to
51198c6
Compare
jason810496
force-pushed
the
jason/lang-sdk-e2e/04-java-dag-importer
branch
from
October 2, 2026 14:07
51198c6 to
b3a04e2
Compare
JavaDagImporter now names its coordinator class and is registered in a Dag bundle when [sdk] coordinators has a JavaCoordinator, instead of being handed out by each coordinator. The importer asks the coordinator that parses its bundle for main_class, and keeps a JAR when there is none, so that parsing the JAR reports why.
A coordinator can raise TaskLaunchError from execute_task before it starts the runtime. The supervisor then starts the task instance, writes the reason to the task log, and puts the task up for retry or fails it, instead of letting the error escape without a state or a log. An error that is not retryable fails the task even when retries are left.
A task whose Dag file a coordinator Dag importer claims runs that file, at the version of the run, on a coordinator of the importer's class. It no longer scans the bundle for a JAR, so it cannot run another JAR, and a coordinator that cannot run it raises TaskLaunchError before the runtime starts. A task routed to a coordinator of another class, or in a bundle whose importers cannot be built, fails without retries. JavaCoordinator builds the command for a Dag JAR and for parsing it with one method, so both reject a JAR whose Main-Class another JAR sets. Stub tasks keep the scan and the bundle rules they have on main, so the Dag file plumbing of _build_execute_task_command is removed.
…load An unreadable Dag file and an importer whose coordinator class cannot be imported now raise TaskLaunchError, so the supervisor fails the task with the reason instead of leaking a raw OSError or ImportError.
airflow tasks list parses a native Java Dag, so it is not among the commands that refuse one. Also break the new Java SDK text only at sentence or clause ends.
The Dag processor and the CLI only run the JAR, so they need a JRE, as the prerequisites already say. The artifact bundle tests go back to main's MagicMock(spec=BundleInfo), which they no longer needed to drop.
jason810496
force-pushed
the
jason/lang-sdk-e2e/04-java-dag-importer
branch
from
October 5, 2026 11:39
6ea3559 to
3b6a9d0
Compare
This was referenced Oct 5, 2026
Open
kaxil
reviewed
Oct 6, 2026
phanikumv
reviewed
Oct 6, 2026
2 tasks
Two JARs that both shade the SDK classes must load the one `_build_jar_command` runs, not whichever sorts first alphabetically.
…dZipFile A corrupt deflate stream or an unsupported compression method on META-INF/MANIFEST.MF escaped both `might_contain_dag` and `_JarMetadata.from_jar`. `might_contain_dag` now keeps the JAR for any exception, like `ZipImporter` does; `from_jar` also catches `zlib.error` and `NotImplementedError`, while still letting `PermissionError` propagate.
`_JarInfo.find` kept overwriting `progress.main_class` on every matching JAR until one also carried the schema version, so a schema-only JAR appearing later could make a later Main-Class win.
`queue_coordinator` was a local instance the manager never builds, so comparing it by identity could not fail. Patching `get_parsing_coordinator` and asserting it is never called pins what the test promises.
Bare MagicMocks and unspecced patches let a typo'd bundle attribute or a renamed start() keyword pass silently, unlike TestExecuteTaskBundleWiring just above.
A bare * only hides everything safely when the JAR has its own bundle, and it is not valid regexp syntax, so dag_ignore_file_syntax = regexp silently drops it and still parses the JAR.
Member
Author
|
Thanks for the review, I addressed them all in the latest commits. Update: I will merge this with #74037 as soon as the CI pass there, so that we won't waste another CI run. |
phanikumv
approved these changes
Oct 6, 2026
1 task done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack (bottom to top): #74042, #74035, #74043, #74036, #74037, #73845, #73846, #73847
Why
With this PR,
JavaCoordinatorparses the native Dags a bundle JAR declares and runs their tasks from that JAR, and the Code view shows their Java source.What changes
JavaCoordinatoris configured, each.jarwhose manifest setsMain-Class(matchingmain_classif set) is parsed in every Dag bundle. An unreadable JAR is kept so its parse reports the error.java -classpath <bundle JARs> <jvm_args> <Main-Class>, with the same schema version lookup. A JAR it cannot run gets an import error.JavaCoordinatorits queue routes to.task_handler_bundle_namedoes not apply.execute_taskraises the newTaskLaunchErrorwhen a native Dag's JAR cannot run, and the supervisor fails the task with the reason in its task log. A routing mistake, such as a queue routed to another kind of coordinator, fails without retries.emailparser broke a foldedMain-Class.get_source_codereads thesources.jsonindex the Gradle plugin packs (Java SDK: Pack each native Dag's source file into the bundle JAR #74096), named by theAirflow-Java-SDK-Sourcesmanifest attribute, and returns the entrypoint (Main-Class) source, up to 1 MiB per file, or a placeholder. The index also maps each Java Dag to its own file for a per-Dag lookup.The Java runtime is unchanged here. The Java SDK layer above makes it answer the parse request, with a payload that passes
validate_serialized_dag.Deviations and limitations
get_source_codeopen for native Dags. This returns the source embedded as the pure Java Dags ADR (Move Lang-SDK ADRs from java-sdk/adr to airflow-core/adr/lang-sdk #70156) proposes, but underMETA-INF/airflow/sources/instead of the JAR root to avoid fat JAR collisions, and without itsairflow-metadata.yaml, since the parse runs the JVM.main_class, each is parsed, but a@task.stubtask runs the first one in path order (Coordinator: detect ambiguous entrypoints and duplicate dag_ids at import time #71134).max_active_tasks,max_active_runs,max_consecutive_failed_dag_runs,catchupanddisable_bundle_versioningwhen a Dag leaves them unset, so a native Java Dag does not get the Airflow config values that Parse native Lang-SDK Dags in the Dag processor with their runtime #74035 fills in.queueset, no Dag in both Java and Python in one bundle, no cluster policies,airflow dags reserializedoes not store a JAR's Dags, andairflow dags test,tasks testandtasks renderrefuse a native Java Dag.Was generative AI tooling used to co-author this PR?