subtask2 = scope.fork(task2);
scope.join();
} catch (Exception e) {
e.printStackTrace();
}
}
これで、Java ファイルと同じようにスクリプトを開発できるようになりました。
公開する準備ができたら、次のようにさまざまな形式でエクスポートできます:
-
jar ファイル: jbang エクスポート ポータブル helloworld.java。スクリプトで依存関係を使用している場合は、次のコマンドの方が推奨されます。
- A fatjar: すべての依存関係が含まれています: jbang export fatjar helloworld.java。この方法でも、ターゲット マシンに JDK / JRE をインストールする必要があります。それを望まない場合は、次のコマンドの方が推奨されます。
- JDK を含む jlink バイナリ: jbang export jlink helloworld.java。実行するバイナリは、Unix の場合は helloworld-jlink/bin/helloworld、Windows の場合は helloworld-jlink/bin/helloworld.bat です。
-
ネイティブ画像: jbang エクスポート ネイティブ helloworld.java。これには GraalVM のインストールが必要です。
スクリプトは、次のように mavenrepo としてエクスポートすることもできます: jbang export mavenrepo helloworld.java
JDK管理
前の章で説明したように、JBang はマシンに JDK をインストールできます。
jbang jdk list を使用してインストールされている JDK を一覧表示し、jbang jdk list --available --show-details を使用してインストール可能な JDK を一覧表示し、jbang jdk install [version] を使用して新しい JDK をインストールできます。 Jbang は、サポートされているシステム上で JDK を管理するための SDKMAN の使用もサポートしています。
さらに、スクリプト内で JDK バージョンを指定することができます。
これは、スクリプト プロパティに次の行を追加することで実行できます: //JAVA [version] 正確なバージョンが必要な場合、//JAVA [version] 少なくとも特定のバージョンが必要な場合。
その場合、JBang は必要な JDK バージョンを自動的にインストールし、システムのデフォルトの JDK を変更せずにそのスクリプトにのみ使用します。
たとえば、次のスクリプトは Java 25 といくつかのプレビュー機能を使用します。
> jbang init helloworld.java
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
「Main」クラスのないスクリプト
スクリプトは軽量になる傾向があるため、クラスや main メソッドを使用せずにスクリプトを記述することをお勧めします。
幸いなことに、Java には暗黙的に宣言されたクラスとインスタンスの main メソッドと呼ばれる機能があります (これは Java 23 ではまだプレビュー段階です)。
この機能を使用すると、クラスや静的メイン メソッドを使用せずに Java プログラムと JBang スクリプトを作成できます。
次のスクリプトは問題なくコンパイルされ、実行されます。
> jbang helloworld.java
Hello world
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
これは、次のプロパティをスクリプトに追加することで可能になります。
///usr/bin/env jbang "<pre class="brush:php;toolbar:false">> chmod +x helloworld.java
> ./helloworld.java
Hello world
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
" "$@" ; exit $?
import static java.lang.System.*;
public class helloworld {
public static void main(String... args) {
out.println("Hello world");
}
}
最初の行 //JAVA 23 は、JBang に Java 23 以降を使用するように指示します。
2 行目と 3 行目の //COMPILE_OPTIONS --enable-preview -source 23 と //RUNTIME_OPTIONS --enable-preview は、それぞれコンパイルとランタイムのプレビュー機能を有効にします。
機能が安定したら、3 行を削除してもスクリプトは引き続き機能します。素敵です!
依存関係
JBang は、依存関係ごとに //DEPS atrefact-id:atrefact-name:version 行を追加することで、Gradle スタイルの依存関係の形式でスクリプトへの依存関係の追加をサポートします。
たとえば、jfiglet ライブラリを使用するには、次の行をスクリプトに追加します: //DEPS com.github.lalyos:jfiglet:0.0.8.
> jbang init helloworld.java
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
カタログ
JBang のカタログを使用すると、スクリプトとテンプレートを効率的に整理して共有できます。
この機能は、一般的なタスクやワークフロー用のスクリプトのコレクションを共有したいチームやコミュニティに特に役立ちます。
また、ソース コードを提供せずにスターター コードを配布したり、演習の結果を示したりしたい教師にも役立ちます。
カタログは、エイリアスとテンプレートという 2 つの項目グループを含む jbang-catalog.json という名前の JSON ファイルです。
エイリアスを使用すると、単純なコマンドを使用してカタログからスクリプトを実行できますが、テンプレートは新しいスクリプトの開始点を提供します。
カタログはリモートまたはローカルにすることができ、必要に応じてローカルまたはリモートのリポジトリを追加して使用することができます。
興味深いのは、JBang がセットアップ中に、いくつかのエイリアスとテンプレートを含むローカル カタログをすぐに作成することです。
JBang は、これらのディレクトリ内のローカル カタログを次の順序で検索します (ソース JBang ドキュメント):
- 現在のディレクトリ、./jbang-catalog.json
- ./.jbang/jbang-catalog.json 内
- 親ディレクトリの ../jbang-catalog.json
- 親の .jbang ディレクトリ内、../.jbang/jbang-catalog.json
- そして、ファイル システムのルートに向かって手順 3 と 4 を再帰的に繰り返します
- 最後のステップとして、$HOME/.jbang/jbang-catalog.json を調べます。
JBang は、GitHub、GitLab、Bitbucket などの多くのオープン ソース リポジトリにあるカタログをリモートで検索します。
この投稿では例として GitHub を使用します。
リモート カタログを作成するには、jbang-catalog.json をリポジトリのルート フォルダーに追加する必要があります。
その後、カタログは account/repository_name.
によって参照されます。
リポジトリの名前が jbang-catalog の場合は、アカウントごとにそれを参照できます。
したがって、たとえば、私の GitHub アカウントの名前が yostane で、jbang-catalog.json というファイルというカタログを含む cours-java という名前のリポジトリがある場合、yostane/cours-java によってそのカタログを参照できます。さらに、jbang-catalog という名前のリポジトリに jbang-catalog.json がある場合、それを yostane/jbang-catalog または単に yostane で参照できます。
> jbang helloworld.java
Hello world
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
次の章では、カタログのエイリアスとテンプレートを使用する方法を説明します。
別名
JBang のエイリアスを使用すると、カタログからスクリプトを実行できます。
完全な構文は、それぞれリモート エイリアスとローカル エイリアスを表す jbang alias@account/repository [args] と jbang alias [args] です。
エイリアスは、次の形式を使用してカタログ ファイルのエイリアス セクションで定義できます。
> jbang init helloworld.java
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
これは DevoxxMA 2024 でのセッション中に使用したカタログです。
> jbang helloworld.java
Hello world
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
次のコマンドを使用してこれらのエイリアスを実行できます:
- jbang palcli@yostane/cours-java マダム
- jbang palqrest@yostane/cours-java
- jbang hellojfx@yostane/cours-java
公式 JBang GitHub アカウントは、多くのエイリアスとテンプレートを含むカタログを提供します。
それらのいくつかを実行してみましょう:
-
jbang httpd@jbangdev ローカル Web サーバーを実行します。
-
jbang gavsearch@jbangdev [arg] search.maven.org で [arg] を検索します。
テンプレート
テンプレート。新しいスクリプトの開始点として使用できる事前定義されたスクリプトです。
これらは、次の形式を使用してカタログ ファイルのテンプレート セクションで定義されます:
///usr/bin/env jbang "<pre class="brush:php;toolbar:false">> chmod +x helloworld.java
> ./helloworld.java
Hello world
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
" "$@" ; exit $?
import static java.lang.System.*;
public class helloworld {
public static void main(String... args) {
out.println("Hello world");
}
}
テンプレートが使用されると、JBang は file-refs プロパティ内のすべてのファイルのコピーを作成します。
ファイル参照に {basename} が含まれる場合、JBang はそれを作成中のスクリプトの名前に置き換えます。
ファイル参照で .qute 拡張子が使用されている場合、JBang は Qute テンプレート エンジンを使用します
すぐに使用できるテンプレートの例をいくつか示します:
- picocli を使用する CLI スクリプト: jbang init -t cli hellocli.java
- Quarkus の単一ファイル REST API: jbang init -t qrest helloqrest.java
コミュニティで共有されているインターネットのテンプレートを使用することもできます。
たとえば、次のコマンドは JUnit 単体テスト ファイルを作成します: jbang init -t junit@jbangdev file_to_test.java.
このコマンドから、jbangdev/jbang-catalog リポジトリでテンプレートを定義した jbang-catalog.json を見つけることができます。
/// usr/bin/env jbang "<pre class="brush:php;toolbar:false">///usr/bin/env jbang "<pre class="brush:php;toolbar:false">//JAVA 23+
//COMPILE_OPTIONS --enable-preview -source 23
//RUNTIME_OPTIONS --enable-preview
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
" "$@" ; exit $?
//JAVA 23+
//COMPILE_OPTIONS --enable-preview -source 23
//RUNTIME_OPTIONS --enable-preview
void main(String... args) {
System.out.println("Hello World");
}
" "$@" ; exit $?
//JAVA 25
//COMPILE_OPTIONS --enable-preview -source 25
//RUNTIME_OPTIONS --enable-preview
import java.util.concurrent.Callable;
import java.util.concurrent.StructuredTaskScope;
import static java.lang.System.*;
void main(String... args) {
out.println("Hello Java 25");
Callable task1 = () -> {
out.println("Task 1" + Thread.currentThread());
return "Task 1";
};
Callable task2 = () -> {
out.println("Task 2" + Thread.currentThread());
return 2;
};
try (
var scope = new StructuredTaskScope