mcpField
D
deploying-java-sdk-bundles

deploying-java-sdk-bundles

github.com/astronomerクラウド・DevOps457161 回インストール3 週間前に更新
リポジトリ

deploying-java-sdk-bundles について

Airflow Java SDK のタスクを Bundle にまとめ、Worker で利用可能にするデプロイガイドです。Gradle と Maven によるビルド、ログ連携、オープンソース版 Airflow と Astro へのデプロイを説明します。

主な機能

  1. 01Gradle と Maven による Bundle ビルド
  2. 02Fat JAR と Thin JAR のパッケージ化
  3. 03SDK のログ連携
  4. 04Worker の JRE と Bundle の設定
  5. 05オープンソース版 Airflow と Astro へのデプロイ

活用シーン

  1. 01Java タスククラスと SDK 依存関係のパッケージ化
  2. 02コーディネーターが走査するディレクトリへの Bundle 配置
  3. 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-sdk JAR から読み取ります。

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.xairflow-sdk-slf4jなし — バインディングは自動的に検出されます(slf4j-api も自動的に含まれます)。
Log4j 2airflow-sdk-log4j2実行時クラスパスに log4j-core を追加し、log4j2.xml で AirflowAppender を宣言します(以下を参照)。
java.util.logging(JUL)airflow-sdk-julmain() で 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 プロジェクトに適用できます。

  1. バンドルをビルドしてから、プロジェクト内に配置します:mkdir -p include/jars && cp ../java-bundle/build/bundle/*.jar include/jars/。

  2. プロジェクトの 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
    
  3. コーディネーターの設定をプロジェクトの .env に記述します(自動的に読み込まれます)。AIRFLOW__SDK__* の値については、configuring-airflow-language-sdks を参照してください。

  4. 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 プロジェクトを初期化して設定します。

コメント