Heim >Java >javaLernprogramm >JBang, das fehlende Skripttool des Java-Ökosystems

JBang, das fehlende Skripttool des Java-Ökosystems

Patricia Arquette
Patricia ArquetteOriginal
2025-01-05 04:01:39241Durchsuche

Das Java-Ökosystem verfügt bereits über zwei leistungsstarke Projektmanagement-Tools, nämlich Maven und Gradle, es fehlte jedoch ein einfaches und leistungsstarkes Skripting-Tool.
Hier kommt JBang ins Spiel.
Es ist ein minimalistischer, aber leistungsstarker Datei-Launcher für Java, Kotlin und Groovy.
Tatsächlich ermöglicht es Ihnen, Code genauso einfach auszuführen wie ein Skript.
Es bietet außerdem viele weitere Funktionen wie Abhängigkeitsmanagement, Vorlagen und einen App Store.
Lassen Sie uns in diesem Beitrag JBang und seine Funktionen erkunden.

Aufstellen

Die jbang-Befehlszeile kann unter Windows, Linux und macOS mit verschiedenen Methoden installiert werden, die hier ausführlich dokumentiert sind.
Wir können die Installation überprüfen, indem wir jbang --version.

ausführen

Darüber hinaus empfiehlt es sich, die zugehörige IDE-Erweiterung für unsere Lieblings-IDE zu installieren.
Die unterstützten IDE-Erweiterungen sind hier aufgelistet.

JBang ist nicht von einem JDK zu JRE abhängig, aber ein JDK ist erforderlich, um Skripte auszuführen, die Java verwenden.
Sie können eines mit JBang installieren, indem Sie jbang jdk install 23 ausführen, wodurch das JDK 23 installiert wird.

Wir sind jetzt bereit, unsere ersten Skripte zu schreiben.

Erstes Drehbuch

Lassen Sie uns ein einfaches Skript erstellen, das „Hello, World!“ ausgibt. zur Konsole.

> jbang init helloworld.java

Dadurch wird eine Datei mit dem Namen helloworld.java erstellt, die mit jbang helloworld.java ausgeführt werden kann.

> jbang helloworld.java
Hello world

Wenn Sie die Datei öffnen, werden Sie sehen, dass es sich um eine einfache Java-Datei mit einer Hauptmethode und einer bestimmten ersten Zeile handelt.

///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"); } }

Wie wir sehen werden, besteht das JBang-Skript aus drei Teilen: dem Shebang, optionalen Eigenschaften und dem Skript selbst.
In den nächsten Abschnitten werden wir im zweiten Teil einige Eigenschaften verwenden, aber konzentrieren wir uns auf den ersten Teil.

Dieser Teil ///usr/bin/env jbang "$0" "$@" ; beenden $? weist das System an, JBang zum Ausführen des Skripts zu verwenden.
Es wird im Unix-Ökosystem als Shebang bezeichnet und wird verwendet, um den Interpreter für das Skript anzugeben.
Wir können dies auf einem Unix-System (macOS, Linux) veranschaulichen, indem wir chmod x helloworld.java ausführen, um das Skript ausführbar zu machen, und dann ./helloworld.java ausführen.

/// 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()) { StructuredTaskScope.Subtask subtask1 = scope.fork(task1); StructuredTaskScope.Subtask subtask2 = scope.fork(task2); scope.join(); } catch (Exception e) { e.printStackTrace(); } }

Wir können unser Skript jetzt wie mit jeder Java-Datei entwickeln.
Sobald es zur Veröffentlichung bereit ist, können wir es wie folgt in verschiedene Formate exportieren:

  • Eine jar-Datei: jbang export portable helloworld.java. Wenn Ihr Skript Abhängigkeiten verwendet, werden die nächsten Befehle eher empfohlen.
  • Ein Fatjar: das alle Abhängigkeiten enthält: jbang export fatjar helloworld.java. Diese Methode erfordert weiterhin die Installation eines JDK/JRE auf dem Zielcomputer. Wenn Sie das nicht möchten, empfehlen sich die nächsten Befehle.
  • Eine jlink-Binärdatei, die ein JDK umfasst: jbang export jlink helloworld.java. Die auszuführende Binärdatei ist entweder helloworld-jlink/bin/helloworld unter Unix oder helloworld-jlink/bin/helloworld.bat unter Windows.
  • Ein natives Bild: jbang export native helloworld.java. Dies erfordert eine GraalVM-Installation.

Das Skript kann auch als Mavenrepo exportiert werden mit: jbang export mavenrepo helloworld.java

JDK-Verwaltung

Wie in einem vorherigen Kapitel gesehen, kann JBang JDKs auf Ihrem Computer installieren.
Sie können die installierten JDKs mit jbang jdk list auflisten, die zur Installation verfügbaren JDKs mit jbang jdk list --available --show-details auflisten und mit jbang jdk install [version] ein neues installieren. Jbang unterstützt auch die Verwendung von SDKMAN zur Verwaltung von JDKs auf unterstützten Systemen.

Darüber hinaus ist es möglich, in einem Skript eine JDK-Version anzugeben.
Dies geschieht durch Hinzufügen der folgenden Zeile zu den Skripteigenschaften: //JAVA [Version], wenn wir eine genaue Version wünschen, oder //JAVA [Version], wenn wir mindestens eine bestimmte Version wünschen.
In diesem Fall installiert JBang automatisch die erforderliche JDK-Version und verwendet sie nur für dieses Skript, ohne das Standard-JDK des Systems zu ändern.

Das folgende Skript verwendet beispielsweise Java 25 und einige Vorschaufunktionen.

> jbang init helloworld.java

Skripte ohne eine „Main“-Klasse

Da Skripte in der Regel leichtgewichtig sind, wäre es vorzuziehen, sie ohne eine Klasse und eine Hauptmethode zu schreiben.
Glücklicherweise verfügt Java über eine Funktion namens implizit deklarierte Klassen und Instanzhauptmethoden (die sich in Java 23 noch in der Vorschau befindet).
Diese Funktion ermöglicht das Schreiben von Java-Programmen und JBang-Skripten ohne eine Klasse und eine statische Hauptmethode.

Das folgende Skript wird problemlos kompiliert und ausgeführt.

> jbang helloworld.java
Hello world

Dies wird ermöglicht, indem dem Skript die folgenden Eigenschaften hinzugefügt werden.

///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"); } }

Die erste Zeile, //JAVA 23 , weist JBang an, Java 23 oder höher zu verwenden.
Die zweite und dritte Zeile, //COMPILE_OPTIONS --enable-preview -source 23 und //RUNTIME_OPTIONS --enable-preview, aktivieren Vorschaufunktionen für die Kompilierung bzw. Laufzeit.

Sobald die Funktion stabil ist, können wir die drei Zeilen entfernen und das Skript funktioniert weiterhin. Ordentlich!

Abhängigkeiten

JBang unterstützt das Hinzufügen von Abhängigkeiten zu Skripten in Form von Abhängigkeiten im Gradle-Stil, indem für jede Abhängigkeit eine //DEPS atrefact-id:atrefact-name:version-Zeile hinzugefügt wird.
Um beispielsweise die jfiglet-Bibliothek zu verwenden, können wir dem Skript die folgende Zeile hinzufügen: //DEPS com.github.lalyos:jfiglet:0.0.8.

> jbang init helloworld.java

Kataloge

Kataloge in JBang ermöglichen die effiziente Organisation und gemeinsame Nutzung von Skripten und Vorlagen.
Diese Funktion ist besonders nützlich für Teams oder Communities, die eine Sammlung von Skripten für allgemeine Aufgaben oder Arbeitsabläufe teilen möchten.
Es ist auch nützlich für Lehrer, die Startercodes verteilen oder Übungsergebnisse anzeigen möchten, ohne den Quellcode bereitzustellen.

Ein Katalog ist eine JSON-Datei mit dem Namen jbang-catalog.json, die zwei Gruppen von Elementen enthält: Aliase und Vorlagen.
Aliase ermöglichen die Ausführung von Skripten aus einem Katalog mit einem einfachen Befehl, während Vorlagen einen Ausgangspunkt für neue Skripte bieten.
Kataloge können remote oder lokal sein und es ist möglich, so viele lokale oder Remote-Repositorys wie nötig hinzuzufügen und zu verwenden.
Es ist interessant, darauf hinzuweisen, dass JBang während der Einrichtung einen lokalen Katalog mit einigen Aliasnamen und Vorlagen erstellt.

JBang sucht in diesen Verzeichnissen in der folgenden Reihenfolge nach lokalen Katalogen (Quell-JBang-Dokumente):

  1. Aktuelles Verzeichnis, ./jbang-catalog.json
  2. In ./.jbang/jbang-catalog.json
  3. Im übergeordneten Verzeichnis ../jbang-catalog.json
  4. Im .jbang-Verzeichnis des übergeordneten Verzeichnisses, ../.jbang/jbang-catalog.json
  5. Und Wiederholen der Schritte 3 und 4 rekursiv nach oben bis zum Stammverzeichnis des Dateisystems
  6. Im letzten Schritt wird in $HOME/.jbang/jbang-catalog.json gesucht

JBang sucht in vielen Open-Source-Repositories wie GitHub, GitLab, Bitbucket und anderen nach Remote-Katalogen.
Ich werde GitHub in diesem Beitrag als Beispiel verwenden.
Um einen Remote-Katalog zu erstellen, müssen Sie jbang-catalog.json zum Stammordner Ihres Repositorys hinzufügen.
Auf den Katalog wird dann über Konto/Repository-Name verwiesen.
Wenn Ihr Repository den Namen „jbang-catalog“ trägt, können Sie über das Konto darauf verweisen.
Wenn mein GitHub-Konto beispielsweise yostane heißt und ich ein Repository namens cours-java habe, das einen Katalog mit einer Datei namens jbang-catalog.json enthält, kann ich mit yostane/cours-java auf diesen Katalog verweisen. Wenn ich außerdem eine jbang-catalog.json in einem Repository namens jbang-catalog habe, kann ich mit yostane/jbang-catalog oder einfach yostane.
darauf verweisen

> jbang helloworld.java
Hello world

In den folgenden Kapiteln wird gezeigt, wie Sie Aliase und Vorlagen aus einem Katalog verwenden.

Aliase

Aliase in JBang ermöglichen die Ausführung von Skripten aus einem Katalog.
Die vollständige Syntax lautet jbang alias@account/repository [args] und jbang alias [args] für einen Remote- bzw. lokalen Alias.

Aliase können im Abschnitt „Aliase“ der Katalogdatei im folgenden Format definiert werden:

> jbang init helloworld.java

Hier ist der Katalog, den ich während meiner Sitzung bei DevoxxMA 2024 verwendet habe.

> jbang helloworld.java
Hello world

Sie können diese Aliase mit den folgenden Befehlen ausführen:

  • jbang palcli@yostane/cours-java Madam
  • jbang palqrest@yostane/cours-java
  • jbang hellojfx@yostane/cours-java

Der offizielle JBang GitHub-Account bietet einen Katalog mit vielen Aliasen und Vorlagen.
Lassen Sie uns einige davon ausführen:

  • jbang httpd@jbangdev führt einen lokalen Webserver aus.
  • jbang gavsearch@jbangdev [arg] Suche nach [arg] auf search.maven.org.

Vorlagen

Vorlagen, das sind vordefinierte Skripte, die als Ausgangspunkt für neue Skripte verwendet werden können.
Sie werden im Abschnitt „Vorlagen“ der Katalogdatei im folgenden Format definiert:

///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"); } }

Wenn eine Vorlage verwendet wird, erstellt JBang Kopien aller Dateien in der Eigenschaft „file-refs“.
Wenn eine Dateireferenz {basename} enthält, ersetzt JBang sie durch den Namen des zu erstellenden Skripts.
Wenn eine Dateireferenz die Erweiterung .qute verwendet, verwendet JBang die Qute-Templating-Engine

Hier sind einige Beispiele für einige Vorlagen, die sofort verfügbar sind:

  • Ein CLI-Skript, das picocli verwendet: jbang init -t cli hellocli.java
  • Eine Quarkus-Einzeldatei-REST-API: jbang init -t qrest helloqrest.java

Wir können auch Vorlagen aus dem Internet verwenden, die von der Community geteilt werden.
Mit diesem Befehl wird beispielsweise eine JUnit-Unit-Testdatei erstellt: jbang init -t junit@jbangdev file_to_test.java.
Mit dem Befehl können wir die jbang-catalog.json finden, die die Vorlage im jbangdev/jbang-catalog-Repository definiert hat.

/// 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()) { StructuredTaskScope.Subtask subtask1 = scope.fork(task1); StructuredTaskScope.Subtask subtask2 = scope.fork(task2); scope.join(); } catch (Exception e) { e.printStackTrace(); } }

App Store

Der JBang App Store ist eine Web-App, die das Durchsuchen von Aliasen indizierter Kataloge ermöglicht.
Es bietet eine bequeme Möglichkeit, verschiedene Tools und Dienstprogramme zu entdecken und zu verwenden, ohne dass komplexe Einrichtungs- oder Installationsprozesse erforderlich sind.
Wenn wir beispielsweise nach Yostane suchen, sollten wir in der Lage sein, die verschiedenen Aliase zu finden, die ich in meinen verschiedenen Katalogen definiert habe.
Das folgende Bild zeigt das Ergebnis der Suche.

JBang, the missing scripting tool of the Java ecosystem

Hier sind einige interessante und lustige Skripte, die ich beim Stöbern im App Store gefunden habe:

  • Cowsay. Hier sind einige Beispiele für die Ausführung des Skripts:
    • jbang cowsay@ricksbrown/cowsay MOO!
    • jbang cowsay@ricksbrown/cowsay -f Dragon „Ich bin Veldora Tempest!“
  • Suchen Sie einen Teilstring wie grep: jbang grep@a-services "hello" .
  • PDF aus Bildern erstellen: images2pdf@a-services. Die folgenden Befehle erstellen eine PDF-Datei aus zwei Bildern:
///usr/bin/env jbang "<pre class="brush:php;toolbar:false">  {
    "catalogs": {},
    "aliases": {
      // aliases
    },
    "templates": {
      // templates
    }
  }
" "$@" ; exit $? //DEPS com.github.lalyos:jfiglet:0.0.9 import com.github.lalyos.jfiglet.FigletFont; public class DependenciesDemo { public static void main(String... args) throws Exception { System.out.println(FigletFont.convertOneLine("JBang is amazing")); } }

Wenn Sie einen Katalog veröffentlichen, wird dieser höchstwahrscheinlich nach der nächsten Indizierung des JBang AppStore erscheinen.
Es handelt sich um eine geplante GitHub-Aktion, die hier definiert ist.

Einige Beispiele mit bemerkenswerten Rahmenwerken

Mit JBang können wir Einzeldateianwendungen erstellen, die gängige Frameworks und Bibliotheken verwenden.
Einige Beispiele sind Quarkus, Picolcli und JavaFX.
Sehen wir uns in den folgenden Abschnitten einige Beispiele an.

JavaFX (openjfx)

JavaFX ist ein Desktop- und UI-Framework.
Die offizielle Website ist openjfx.io und wird auch von Gluon unterstützt, das zusätzliche UI-Komponenten bereitstellt und JavaFX-Unterstützung für mobile Apps bietet.
JBang unterstützt dieses Framework und kann zum Erstellen von Einzeldatei-JavaFX-Anwendungen verwendet werden.

Hier sind einige Beispiele für JavaFX-Apps, die mit JBang erstellt wurden:

  • Basisfenster
  • Schöneres Beispiel jbang https://gist.github.com/FDelporte/c69a02c57acc892b4c996a9779d4f830
  • Eine Vorlage jbang init -t javafx@yostane hellojfx

Quarkus

Quarkus ist ein Java-Framework, das für Kubernetes und serverlose Umgebungen optimiert ist.
Es bietet eine schnelle Startzeit und einen geringen Speicherverbrauch und ist somit ideal für Cloud-native Anwendungen.

Dank JBang können wir Einzeldatei-Quarkus-Anwendungen erstellen, die die Leistungsfähigkeit dieses Frameworks nutzen.
Das folgende Beispiel zeigt eine Rest-API, die testet, ob eine Zeichenfolge ein Palindrom ist. Es verfügt über JSON-Analyse und Protokollierung und bietet eine OpenAPI- und Swagger-Dokumentation.

> jbang init helloworld.java

Möglicherweise bemerken wir eine Zeile //SOURCES PalindromeService.java im Skript.
Es weist JBang an, im selben Verzeichnis wie das Skript nach einer Datei namens PalindromeService.java zu suchen.
Das bedeutet, dass JBang Skripte mit mehreren Dateien unterstützt.

Sie können den Server mit jbang palqrest@yostane/cours-java ausführen und den Endpunkt mit curl http://localhost:8080/palindrome?input=madam aufrufen.

> jbang helloworld.java
Hello world

Andere Sprachen

JBang unterstützt die Ausführung von Java-, Kotlin-, JShell- und Groovy-Code.
Es kann sogar Java-Code aus Markdown-Dateien ausführen.
Hier sind einige Beispiele für die Verwendung von JBang mit verschiedenen Sprachen:

  • Kotlin: Sie können ein Kotlin-Skript mit jbang init -t hello.kt Dateiname.kt initialisieren. Bitte beachten Sie, dass sich dies von den offiziellen .main.kts Kotlin-Skripten unterscheidet. Tatsächlich können von JBang erstellte Kotlin-Skripte von den Katalog- und App Store-Funktionen profitieren. Hier ist ein Beispiel eines mit JBang erstellten Kotlin-Skripts.
> jbang init helloworld.java
  • Interessante Tatsache: Die Idee zu JBang kam von kscript, das auf das Kotlin-Ökosystem ausgerichtet ist.
  • Kotlin verfügt bereits über native Skriptunterstützung (mit .main.kts-Skripten), aber es scheint, dass die Katalog-, Vorlagen- und App Store-Funktionen fehlen.
    • Groovy: Initialisieren Sie ein Groovy-Skript mit jbang init -t hello.groovy filename.groovy. Hier ist ein Beispiel eines mit JBang erstellten Groovy-Skripts.
> jbang helloworld.java
Hello world
  • JShell: JBang unterstützt JShell-Skripte mit .jsh- oder .jshell-Erweiterungen und Inline-Skripte mit jbang -c 'System.out.println("Inline Java ☕ yay!")'. Hier ist ein Beispiel eines mit JBang erstellten JShell-Skripts.
///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"); } }
  • Markdown mit Java- und JShell-Codeblöcken: Mit jbang my_markdown.md können Sie Java- und JShell-Codeblöcke direkt aus einer Markdown-Datei ausführen.
/// 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()) { StructuredTaskScope.Subtask subtask1 = scope.fork(task1); StructuredTaskScope.Subtask subtask2 = scope.fork(task2); scope.join(); } catch (Exception e) { e.printStackTrace(); } }

Das obige ist der detaillierte Inhalt vonJBang, das fehlende Skripttool des Java-Ökosystems. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn