このチュートリアルでは、Terraform を使用した Java アプリケーションのビルドの基本について説明します。
Bazel。ワークスペースを設定し、簡単な Java プロジェクトを作成します。
ターゲットや BUILD
ファイルなど、Bazel の主なコンセプトを示しています。
完了までの予想時間: 30 分。
学習内容
このチュートリアルでは、次の方法について学びます。
- ターゲットを構築する
- プロジェクトの依存関係を可視化する
- プロジェクトを複数のターゲットとパッケージに分割する
- パッケージ全体でターゲットの公開設定を制御する
- ラベルによる参照ターゲット
- ターゲットをデプロイする
始める前に
Bazel をインストールする
チュートリアルの準備として、次の場合は、まず Bazel をインストールします。 できます。
JDK をインストールする
Java JDK をインストールします(推奨バージョンは 11 ですが、バージョン 8 ~ 15 がサポートされています)。
JDK を指すように JAVA_HOME 環境変数を設定します。
Linux/macOS の場合:
export JAVA_HOME="$(dirname $(dirname $(realpath $(which javac))))"
Windows の場合:
- コントロール パネルを開きます。
- [システムとセキュリティ] に移動します>システム>[システムの詳細設定]>「上級」タブ >「環境変数...」.
- [ユーザー変数] で上部の [新規...] をクリックします。
- [変数名] で、フィールドに「
JAVA_HOME
」と入力します。 - [Browse Directory...] をクリックします。
- JDK ディレクトリ(
C:\Program Files\Java\jdk1.8.0_152
など)に移動します。 - [OK] をクリックします。すべてのダイアログウィンドウで 表示できます
サンプル プロジェクトを取得する
Bazel の GitHub リポジトリからサンプル プロジェクトを取得します。
git clone https://github.com/bazelbuild/examples
このチュートリアルのサンプル プロジェクトは examples/java-tutorial
にあります。
構成されており、次のように構成されています。
java-tutorial
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── cmdline
│ │ ├── BUILD
│ │ └── Runner.java
│ ├── Greeting.java
│ └── ProjectRunner.java
└── MODULE.bazel
Bazel を使用したビルド
ワークスペースを設定する
プロジェクトを作成する前に、ワークスペースを設定する必要があります。ワークスペースとは プロジェクトのソースファイルと Bazel のビルド出力を保持するディレクトリです。これは、 Bazel が特殊なファイルとして認識するファイルも含まれています。
MODULE.bazel
ファイル。ディレクトリとその内容を Bazel ワークスペースであり、プロジェクトのディレクトリ構造のルートに存在します。1 つ以上の
BUILD
ファイル。Bazel にさまざまな部分のビルド方法を指示します。 できます。(BUILD
ファイルを含むワークスペース内のディレクトリ) パッケージです。パッケージについては、このチュートリアルの後半で説明します)。
ディレクトリを Bazel ワークスペースとして指定するには、
そのディレクトリ内の MODULE.bazel
。
Bazel がプロジェクトをビルドする際、すべての入力と依存関係を同じものにする必要があります。 見てみましょう。別々のワークスペースに存在するファイルはそれぞれ別のワークスペースに存在する これについては、このチュートリアルでは扱いません。
BUILD ファイルについて
BUILD
ファイルには、Bazel に関するさまざまな種類の手順が含まれています。
最も重要なタイプはビルドルールです。これは、Bazel にビルド方法を指示します。
必要な出力(実行可能なバイナリやライブラリなど)を出力できます。各インスタンス
BUILD
ファイル内のビルドルールの「ターゲット」は、
特定のソースファイルと依存関係のセットを
提供しますまた、ターゲットは他の
できます。
java-tutorial/BUILD
ファイルを確認します。
java_binary(
name = "ProjectRunner",
srcs = glob(["src/main/java/com/example/*.java"]),
)
この例では、ProjectRunner
ターゲットが Bazel の組み込みツールをインスタンス化します。
java_binary
ルール。このルールは、Bazel に以下を指示します。
.jar
ファイルとラッパー シェル スクリプト(どちらもターゲットにちなんで名付けられています)をビルドします。
ターゲットの属性は、依存関係とオプションを明示的に記述します。
name
属性は必須ですが、多くは省略可能です。たとえば、
ProjectRunner
ルール ターゲット。name
はターゲットの名前、srcs
は指定します。
Bazel がターゲットのビルドに使用するソースファイル。main_class
で、
main メソッドを含むクラス。(先ほどの例で、
glob を使用して、一連のソースファイルを Bazel に渡します。
(1 つずつリストするのではなく)
プロジェクトをビルドする
サンプル プロジェクトをビルドするには、java-tutorial
ディレクトリに移動します。
次のコマンドを実行します。
bazel build //:ProjectRunner
ターゲット ラベルの //
部分は BUILD
ファイルの場所です。
ワークスペースのルート(この場合はルート自体)を基準とします。
ProjectRunner
は、BUILD
ファイルのターゲット名です。(
ターゲット ラベルの詳細については、このチュートリアルの最後に記載してください)。
Bazel は、次のような出力を生成します。
INFO: Found 1 target...
Target //:ProjectRunner up-to-date:
bazel-bin/ProjectRunner.jar
bazel-bin/ProjectRunner
INFO: Elapsed time: 1.021s, Critical Path: 0.83s
これで、最初の Bazel ターゲットがビルドされました。Bazel の場所のビルド
ワークスペースのルートの bazel-bin
ディレクトリに出力されます。探す
Bazel の出力構造を理解してください。
新しくビルドされたバイナリをテストします。
bazel-bin/ProjectRunner
依存関係グラフを確認する
Bazel では、ビルド依存関係を BUILD ファイルで明示的に宣言する必要があります。 Bazel はこれらのステートメントを使用して、プロジェクトの依存関係グラフを作成します。 正確な増分ビルドが可能になります。
サンプル プロジェクトの依存関係を可視化するために、サンプル プロジェクトの依存関係を 依存関係グラフの表現を ワークスペースのルート:
bazel query --notool_deps --noimplicit_deps "deps(//:ProjectRunner)" --output graph
上記のコマンドは、ターゲットのすべての依存関係を検索するよう Bazel に指示します
//:ProjectRunner
(ホストと暗黙的な依存関係を除く)を使用し、
グラフとして表示できます
次に、テキストを GraphViz に貼り付けます。
ご覧のとおり、プロジェクトには 1 つのターゲットがあり、このファイルで 2 つのソースファイルをビルドしています。 追加の依存関係はありません。
ワークスペースを設定したら、プロジェクトをビルドして内容を確認します。 複雑さが増す可能性があります。
Bazel ビルドの改良
小規模プロジェクトでは 1 つのターゲットで十分ですが、 大規模なプロジェクトを複数のターゲットとパッケージに分けて、 (変更された部分のみを再ビルドする)こともでき、 プロジェクトの複数の部分を一度に構築するのに適しています。
複数のビルド ターゲットを指定する
サンプル プロジェクトのビルドは、2 つのターゲットに分割できます。次の内容を置き換える
java-tutorial/BUILD
ファイルを次のように置き換えます。
java_binary(
name = "ProjectRunner",
srcs = ["src/main/java/com/example/ProjectRunner.java"],
main_class = "com.example.ProjectRunner",
deps = [":greeter"],
)
java_library(
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
)
この構成では、Bazel はまず greeter
ライブラリをビルドし、次に
ProjectRunner
バイナリ。java_binary
の deps
属性は、Bazel に次のことを通知します。
ProjectRunner
バイナリをビルドするには、greeter
ライブラリが必要です。
プロジェクトの新しいバージョンをビルドするには、次のコマンドを実行します。
bazel build //:ProjectRunner
Bazel は、次のような出力を生成します。
INFO: Found 1 target...
Target //:ProjectRunner up-to-date:
bazel-bin/ProjectRunner.jar
bazel-bin/ProjectRunner
INFO: Elapsed time: 2.454s, Critical Path: 1.58s
新しくビルドされたバイナリをテストします。
bazel-bin/ProjectRunner
ここで ProjectRunner.java
を変更してプロジェクトを再ビルドすると、Bazel のみが
そのファイルを再コンパイルします。
依存関係グラフを見ると、ProjectRunner
が
入力は以前と同じですが、ビルドの構造は異なります。
これで、2 つのターゲットを持つプロジェクトがビルドされました。ProjectRunner
ターゲットのビルド
1 つのソースファイルで、他の 1 つのターゲット(:greeter
)に依存します。このターゲットは、
追加のソースファイルです。
複数のパッケージを使用する
プロジェクトを複数のパッケージに分割しましょう。こちらの
src/main/java/com/example/cmdline
ディレクトリには、このフォルダにも
BUILD
ファイルといくつかのソースファイル。つまり Bazel では
//src/main/java/com/example/cmdline
と //
の 2 つのパッケージが含まれています(
(ワークスペースのルートに BUILD
ファイルがある)。
src/main/java/com/example/cmdline/BUILD
ファイルを確認します。
java_binary(
name = "runner",
srcs = ["Runner.java"],
main_class = "com.example.cmdline.Runner",
deps = ["//:greeter"],
)
runner
ターゲットは //
パッケージの greeter
ターゲットに依存します(したがって、
ターゲット ラベル //:greeter
) - Bazel は deps
属性を通じてこれを認識します。
依存関係グラフを見てみましょう。
ただし、ビルドを成功させるには、runner
ターゲットを明示的に指定する必要があります。
目標に対する//src/main/java/com/example/cmdline/BUILD
の公開設定
visibility
属性を使用する //BUILD
。これは、デフォルトでターゲットが
同じ BUILD
ファイル内の他のターゲットからのみ参照可能です。(Bazel はターゲット
実装の詳細を含むライブラリなどの問題を防止するための可視性
発生しがちです)。
これを行うには、visibility
属性を greeter
ターゲットに追加します。
java-tutorial/BUILD
を次のように変更します。
java_library(
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
visibility = ["//src/main/java/com/example/cmdline:__pkg__"],
)
これで、root で次のコマンドを実行し、新しいパッケージをビルドできます。 できます。
bazel build //src/main/java/com/example/cmdline:runner
Bazel は、次のような出力を生成します。
INFO: Found 1 target...
Target //src/main/java/com/example/cmdline:runner up-to-date:
bazel-bin/src/main/java/com/example/cmdline/runner.jar
bazel-bin/src/main/java/com/example/cmdline/runner
INFO: Elapsed time: 1.576s, Critical Path: 0.81s
新しくビルドされたバイナリをテストします。
./bazel-bin/src/main/java/com/example/cmdline/runner
これで、プロジェクトを 2 つのパッケージとしてビルドするよう変更できました。それぞれのパッケージには 1 つのパッケージが含まれています。 それらの依存関係を理解します。
ラベルを使用してターゲットを参照する
BUILD
ファイルとコマンドラインで、Bazel はターゲット ラベルを使用して参照します。
ターゲット(例: //:ProjectRunner
)
//src/main/java/com/example/cmdline:runner
。構文は次のとおりです。
//path/to/package:target-name
ターゲットがルール ターゲットの場合、path/to/package
はルール ターゲットのパス
BUILD
ファイルを含むディレクトリがあり、target-name
は名前を付けたものです
BUILD
ファイル内の(name
属性)ターゲット。ターゲットがファイルの場合
target の場合、path/to/package
はパッケージのルートへのパスです。
target-name
は、フルパスを含むターゲット ファイルの名前です。
リポジトリ ルートでターゲットを参照する場合、パッケージパスは空になります。
//:target-name
を使用してください。同じ BUILD
内でターゲットを参照する場合
//
というワークスペースのルート識別子を省略して、
:target-name
。
たとえば、java-tutorial/BUILD
ファイル内のターゲットでは、この操作を行う必要はありません。
ワークスペースのルート自体がパッケージ(//
)であるため、パッケージパスを指定します。
2 つのターゲット ラベルは単純に //:ProjectRunner
と //:greeter
でした。
ただし、//src/main/java/com/example/cmdline/BUILD
ファイルのターゲットについては、
//src/main/java/com/example/cmdline
のフル パッケージ パスを指定する必要がありました。
ターゲット ラベルは「//src/main/java/com/example/cmdline:runner
」でした。
デプロイ用に Java ターゲットをパッケージ化する
それでは、Java ターゲットをデプロイ用にパッケージ化しましょう。すべてのリソースでバイナリをビルドします。 依存関係を定義します。これにより、Cloud Shell の外部でバイナリを 開発環境です。
すでに説明したように、java_binary ビルドルールが
.jar
とラッパー シェル スクリプトを生成します。詳しくは、
このコマンドを使用した runner.jar
:
jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar
内容は次のとおりです。
META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/cmdline/
com/example/cmdline/Runner.class
ご覧のとおり、runner.jar
には Runner.class
が含まれていますが、依存関係は含まれていません。
Greeting.class
。Bazel が生成する runner
スクリプトが greeter.jar
を追加する
クラスパスに渡されるため、このままにするとローカルで実行されますが、
別のマシンではスタンドアロンで実行できません幸いなことに、java_binary
ルールは
を使用すると、デプロイ可能な自己完結型のバイナリを構築できます。これをビルドするには、
_deploy.jar
をターゲット名に追加します。
bazel build //src/main/java/com/example/cmdline:runner_deploy.jar
Bazel は、次のような出力を生成します。
INFO: Found 1 target...
Target //src/main/java/com/example/cmdline:runner_deploy.jar up-to-date:
bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
INFO: Elapsed time: 1.700s, Critical Path: 0.23s
runner_deploy.jar
をビルドしました。これは、
開発環境には必要なランタイムが含まれているので、
確認します。このスタンドアロン JAR の内容を確認するには、
実行します。
jar tf bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
コンテンツには、実行に必要なクラスがすべて含まれています。
META-INF/
META-INF/MANIFEST.MF
build-data.properties
com/
com/example/
com/example/cmdline/
com/example/cmdline/Runner.class
com/example/Greeting.class
関連情報
詳しくは以下をご覧ください。
rules_jvm_external: Maven の推移的な依存関係を管理するためのルールを使用します。
操作の詳細について確認する外部依存関係 作成することにしました
Bazel の詳細に関するその他のルール。
ビルドを開始するための C++ ビルドのチュートリアル Bazel を使用した C++ プロジェクト。
Android アプリケーションのチュートリアル iOS アプリケーションのチュートリアル)を使用して、Google Chat で Bazel を使用した Android および iOS 向けモバイルアプリのビルド
ご利用をお待ちしております。