deploying-java-sdk-bundles について
Airflow Java SDK のタスクを Bundle にまとめ、Worker で利用可能にするデプロイガイドです。Gradle と Maven によるビルド、ログ連携、オープンソース版 Airflow と Astro へのデプロイを説明します。
主な機能
- 01Gradle と Maven による Bundle ビルド
- 02Fat JAR と Thin JAR のパッケージ化
- 03SDK のログ連携
- 04Worker の JRE と Bundle の設定
- 05オープンソース版 Airflow と Astro へのデプロイ
活用シーン
- 01Java タスククラスと SDK 依存関係のパッケージ化
- 02コーディネーターが走査するディレクトリへの Bundle 配置
- 03Docker、Kubernetes、Astro を使った Java Bundle のデプロイ
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ astronomer/ agents --skill deploying-java-sdk-bundlesインストール後、Claude Code で/deploying-java-sdk-bundlesを入力して読み込まれたか確認します。
詳細
Java SDK バンドルのデプロイ
Java SDK のデプロイで使用するアーティファクトは 1 つ、バンドルです。これは、コンパイル済みのタスククラスと SDK を JAR(または依存関係 JAR と組み合わせた薄型 JAR)としてパッケージ化したものです。Gradle または Maven でビルドした後、各ワーカー上の JavaCoordinator が毎回スキャンするディレクトリ(jars_root)に配置します。このスキルはプラットフォームに依存しません。ビルド方法を一度説明した後、オープンソース版と Astro の両方のデプロイ方法を紹介します。
試験的です。 Java SDK はプレビュー段階です。以下のアーティファクトのバージョンは
${version}として示しています。SDK がプレリリースである間は、アーティファクトを自分でローカルの Maven リポジトリにビルドする必要がある場合があります(プレビュービルドのセクションを参照してください)。
作業の順序: バンドルをビルドする(このスキル)→
jars_rootが指す場所に配置する → コーディネーターを設定する(configuring-airflow-language-sdks)。タスクコード自体については、authoring-java-sdk-tasks を参照してください。
Gradle でビルドする(推奨)
SDK の Gradle プラグインを適用し、build.gradle で依存関係を宣言します。
plugins {
id("org.apache.airflow.sdk") version "${version}"
}
repositories {
mavenCentral()
}
dependencies {
annotationProcessor("org.apache.airflow:airflow-sdk-processor:${version}") // annotation API only
implementation("org.apache.airflow:airflow-sdk:${version}")
// Optional logging integration, e.g.:
// implementation("org.apache.airflow:airflow-sdk-jpl:${version}")
}
airflowBundle {
mainClass = "com.example.Main" // your BundleBuilder entry point
// fatJar = false // opt out of the single-JAR build (see below)
}
ビルドします。
./gradlew bundle
これで build/bundle/ ディレクトリに必要な JAR がすべて格納されます。補足:
annotationProcessorの行が必要なのは、アノテーションベースの API を使用する場合のみです。インターフェースベースの API では不要です。- デフォルトでは、プラグインは ファット JAR(Shadow プラグイン経由)を生成します。これは自己完結型の単一ファイルで、プロジェクト間の依存関係の競合を回避できます。薄型 JAR を使用するには、
airflowBundleでfatJar = falseを設定します。その場合、すべての依存関係 JAR もデプロイする必要があります。 - Gradle プラグインは、ビルド時に
mainClassが存在することを検証します(verifyBundleMainClass)。
Maven でビルドする
BOM をインポートし、アーティファクトのバージョンと supervisor スキーマのバージョンを 1 か所で管理します。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.airflow</groupId>
<artifactId>airflow-sdk-bom</artifactId>
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.airflow</groupId>
<artifactId>airflow-sdk</artifactId>
</dependency>
</dependencies>
アノテーションプロセッサーは、実行時のクラスパスに含まれないように、maven-compiler-plugin 経由で設定します(アノテーション API のみ)。次に、パッケージ化方法を選択します。
- ファット JAR(推奨):
maven-shade-pluginを使用します。そのManifestResourceTransformerで、<mainClass>をBundleBuilderに設定し、BOM プロパティ${airflow.supervisor.schema.version}から解決したAirflow-Supervisor-Schema-Versionマニフェストエントリーを追加します(値をハードコードしないでください)。mvn packageを実行すると、JAR はtarget/に出力されます。 - 薄型 JAR:
maven-jar-pluginでMain-Classを設定し、maven-dependency-plugin(copy-dependencies)で実行時の JAR をtarget/bundle/に集めます。この場合、Airflow-Supervisor-Schema-Versionは不要です。Airflow はクラスパス上のairflow-sdkJAR から読み取ります。
Gradle とは異なり、Maven はビルド時に mainClass を検証しません。値が間違っている場合、実行時にのみ失敗します。
ログ連携
タスクのログレコードを Airflow のログストア(および UI のタスクログビュー)に送るには、バンドルに、使用するロギングファサードごとに SDK のロギングアーティファクトをちょうど 1 つ含める必要があります。バージョンは airflow-sdk-bom で管理されます。Maven の場合も同じアーティファクト ID を使用します。
ファサードの選択。 新規プロジェクトでは、JPL(System.Logger)を推奨します。JDK に組み込まれているため、タスクに追加のロギング API は必要ありません。統合するライブラリがすでに別のファサードを介してログを記録していて、そのレコードも Airflow に届くようにしたい場合に限り、別のファサードを選択してください。優先順位は JPL > SLF4J = Log4j 2 > JUL です。JUL はレガシー連携専用とし、新しいコードでは選択しないでください。
| ファサード | アーティファクト | 依存関係以外に必要な設定 |
|---|---|---|
System.Logger(JPL) | airflow-sdk-jpl | なし — プロバイダーは ServiceLoader を介して検出されます。 |
| SLF4J 2.x | airflow-sdk-slf4j | なし — バインディングは自動的に検出されます(slf4j-api も自動的に含まれます)。 |
| Log4j 2 | airflow-sdk-log4j2 | 実行時クラスパスに log4j-core を追加し、log4j2.xml で AirflowAppender を宣言します(以下を参照)。 |
java.util.logging(JUL) | airflow-sdk-jul | main() で AirflowJulHandler.setup() を呼び出すか(以下を参照)、logging.properties ファイルを使用します(configuring-airflow-language-sdks を参照)。 |
Log4j 2 — アペンダーを検出するプラグインローダーは log4j-core が提供します(log4j-api は推移的に含まれます)。
implementation("org.apache.airflow:airflow-sdk-log4j2:${version}")
runtimeOnly("org.apache.logging.log4j:log4j-core:${log4jVersion}")
<Configuration>
<Appenders>
<AirflowAppender name="Airflow"/>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Airflow"/>
</Root>
</Loggers>
</Configuration>
JUL — タスクが実行される前に AirflowJulHandler.setup() を呼び出してください。これにより、ルートロガーの既存のハンドラーがクリアされます(デフォルトの ConsoleHandler は stderr に書き込みます。設定しない場合、Airflow はこれを ERROR レベルの task.stderr として取り込み、各レコードが重複します)。
public static void main(String[] args) {
AirflowJulHandler.setup();
Server.create(args).serve(new MyBundle().build());
}
プロバイダーを重複させないでください。 airflow-sdk-jpl とともに 2 つ目の System.LoggerFinder 実装を追加したり、airflow-sdk-slf4j とともに 2 つ目の SLF4J バインディング(logback-classic、slf4j-simple)を追加したりすると、プロバイダーの選択が予測不能になります。
プレビュー版(安定版リリース前)
安定版リリースを使用する場合は、このセクションをスキップしてください。 Maven Central に公開されたリリース済みバージョン(例:1.0.0)を固定した後は、上記のビルドスニペットにある mavenCentral() リポジトリだけで十分です。
SDK がプレリリースの間は、Airflow リポジトリからアーティファクトと Gradle プラグインをビルドし、ローカル Maven リポジトリに配置する方法が推奨されています。
# in apache/airflow's java-sdk/ directory
./gradlew publishToMavenLocal -PskipSigning=true
次に、プロジェクトの pluginManagement(settings.gradle 内)とプロジェクトの repositories(build.gradle 内)の両方に mavenLocal() を追加します。これは、SDK 自身のサンプルプロジェクトで解決に使用している方法です。
-SNAPSHOT アーティファクトが Apache のスナップショット Nexus に公開された後は、同じ 2 か所でローカルビルドの代わりにそのリポジトリを使用できます。
maven {
name = "apacheSnapshots"
url = "https://repository.apache.org/content/repositories/snapshots/"
mavenContent { snapshotsOnly() }
}
スナップショットは更新されます。./gradlew bundle --refresh-dependencies を実行して強制的に更新してください。(Maven の場合は、同じリポジトリを <repositories> と <pluginRepositories> に追加します。)
コーディネーターがスキャンする場所にバンドルを配置する
コーディネーターは jars_root を再帰的にスキャンしてクラスパスを自動的に構築するため、出力ディレクトリ全体をコピーします。
cp build/bundle/* /opt/airflow/jars/ # /opt/airflow/jars == jars_root
ワーカーには JRE 17 以降 も必要です。コーディネーターをこのディレクトリに接続する方法については、configuring-airflow-language-sdks を参照してください。
デプロイ方法
Astronomer のツールは必須ではありません。SDK は Task SDK を備えたあらゆる Airflow で動作します。ユーザーのセットアップに合った方法を選択してください。
オープンソース(Docker / Kubernetes)
JRE とバンドルを Airflow イメージに組み込むか、マウントします。
FROM apache/airflow:3 # pin a specific 3.x in production
USER root
RUN apt-get update \
&& apt-get install -y --no-install-recommends default-jre-headless \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
RUN mkdir -p /opt/airflow/jars
COPY build/bundle/ /opt/airflow/jars/
USER airflow
Kubernetes(Helm チャート)では、上記のように JAR をカスタムイメージに組み込むか、共有ボリュームを介してマウントします。ワーカー/スケジューラーで環境変数を使って [sdk] 設定を指定してください。Docker Compose と Helm を含む、より広範なワークフローについては deploying-airflow を参照してください。
Astro(選択肢の一つであり、必須ではありません)
ユーザーが Astronomer の Astro CLI を使用している場合、同じ考え方を Astro プロジェクトに適用できます。
-
バンドルをビルドしてから、プロジェクト内に配置します:
mkdir -p include/jars && cp ../java-bundle/build/bundle/*.jar include/jars/。 -
プロジェクトの
Dockerfileを編集して、JRE をインストールし、JAR をコーディネーターのディレクトリにコピーします:FROM quay.io/astronomer/astro-runtime:<version> USER root RUN apt-get update \ && apt-get install -y --no-install-recommends default-jre-headless \ && apt-get clean && rm -rf /var/lib/apt/lists/* RUN mkdir -p /opt/airflow/jars COPY include/jars/ /opt/airflow/jars/ USER airflow -
コーディネーターの設定をプロジェクトの
.envに記述します(自動的に読み込まれます)。AIRFLOW__SDK__*の値については、configuring-airflow-language-sdks を参照してください。 -
astro dev startを実行します(変更後はastro dev restart)。イメージがビルドされ、Airflow がローカルで起動します。通常どおりastro deployでデプロイします。
Astro Runtime/Airflow のバージョンを記憶頼みで固定しないでください。生成された
Dockerfileを読むか、最新のドキュメントを確認してください。SDK と Airflow 3.3 がプレビュー段階の間は、ベータ版/開発版の Astro Runtime イメージが必要になる場合があります。
デプロイのチェックリスト
- バンドルがビルドされている(
./gradlew bundleまたはmvn package)こと、およびmainClassがBundleBuilderを指していること。 - アノテーション API を使用する場合に限り、
annotationProcessorが存在すること。 - JAR(複数可)がワーカーの
jars_rootディレクトリにコピーされていること。シン JAR の場合は、依存関係の JAR も含まれていること。 - ワーカーで JRE 17 以降が利用できること。
- コーディネーターと
queue_to_coordinatorが設定されていること(configuring-airflow-language-sdks)。 jars_rootの下に実行可能な JAR が複数ある場合は、main_classを明示的に設定していること。
関連スキル
- authoring-java-sdk-tasks:Java タスクコードと、対応する Python スタブを作成します。
- configuring-airflow-language-sdks:コーディネーターを登録し、キューをルーティングします。
- deploying-airflow:Airflow の一般的なデプロイ方法(Astro、Docker Compose、Kubernetes)。
- setting-up-astro-project:Astro プロジェクトを初期化して設定します。