国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Home Java javaTutorial JBang, the missing scripting tool of the Java ecosystem

JBang, the missing scripting tool of the Java ecosystem

Jan 05, 2025 am 04:01 AM

The Java ecosystem has already two powerful project management tools, namely Maven and Gradle, yet it lacked a simple and powerful scripting tool.
This is where JBang comes in.
It is a minimalist but powerful Java, Kotlin and Groovy file launcher.
In fact, it allows you to run code as easily as you would run a script.
It also provides many other features such as dependency management, templates, and an App Store.
Let's explore JBang and its features in this post.

Setup

The jbang command-line can be installed on Windows, Linux, and macOS using different methods which are well documented here.
We can verify the installation by running jbang --version.

In addition to that, it's preferable to install the accompanying IDE extension for our favorite IDE.
The supported IDE extensions are listed here.

JBang does not depend on a JDK to JRE but a JDK is required to run scripts that use Java.
You can install one with JBang by running jbang jdk install 23 which will install the JDK 23.

We are now ready to write our first scripts.

First script

Let's create a simple script that prints "Hello, World!" to the console.

> jbang init helloworld.java

This will create a file named helloworld.java that can be run with jbang helloworld.java.

> jbang helloworld.java
Hello world

When you open the file, you will see that it is a plain Java file with a main method and a particular first line.

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

As we will see, JBang script are made up of three parts: the shebang, optional properties and the script itself.
We'll use some properties the second part in the next sections but let's focus on the first part.

This part ///usr/bin/env jbang "$0" "$@" ; exit $? tells the system to use JBang to run the script.
It is called a shebang in the Unix ecosystem and is used to specify the interpreter for the script.
We can illustrate this on a Unix System (macOS, Linux) by running chmod x helloworld.java to make the script executable and then running ./helloworld.java.

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

We can now develop our script as we would with any Java file.
Once it is ready to be published, we can export it in different formats as follows:

  • A jar file: jbang export portable helloworld.java. If your script uses dependencies, the next commands are more recommended.
  • A fatjar: which contains all the dependencies: jbang export fatjar helloworld.java. This method still requires to install a JDK / JRE on the target machine. If you don't want to that, the next commands are more recommended.
  • A jlink binary that encompases a JDK: jbang export jlink helloworld.java. The binary to run is either helloworld-jlink/bin/helloworld on Unix or helloworld-jlink/bin/helloworld.bat on Windows.
  • A native imgae: jbang export native helloworld.java. This requires a GraalVM installation.

The script can also be exported as a mavenrepo with: jbang export mavenrepo helloworld.java

JDK management

As seen in a previous chapter, JBang can install JDKs on your machine.
You can list the installed JDKs with jbang jdk list, list available ones to install with jbang jdk list --available --show-details, install a new one with jbang jdk install [version]. Jbang also supports the use of SDKMAN to manage JDKs on supported systems.

Furthermore, it is possible to specify a JDK version in a scripts.
This is done by adding the following line to the script properties: //JAVA [version] if we want an exact version or //JAVA [version] if we want at least a specific version.
In that case JBang will automatically install the required JDK version and use it only for that script without changing the default JDK of the system.

For example, the following script uses Java 25 and some preview features.

> jbang init helloworld.java

Scripts without a "Main" class

Since script tend to be lightweight, it would be preferable to write them without a class and a main method.
Fortunately, Java has a feature called implicit declared classes and instance main methods (which is still in preview in Java 23).
This feature allows to write java programs and JBang script without a class and a static main method.

The following script will be compiled and executed without any problem.

> jbang helloworld.java
Hello world

This is made possible by adding the following properties to the script.

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

The first line, //JAVA 23 , tells JBang to use Java 23 or later.
The second and third lines, //COMPILE_OPTIONS --enable-preview -source 23 and //RUNTIME_OPTIONS --enable-preview, enable preview features for compilation and runtime, respectively.

Once the feature become stable, we can remove the 3 lines and the script will still work. Neat!

Dependencies

JBang supports adding dependencies to scripts in the form of Gradle style dependencies by adding a //DEPS atrefact-id:atrefact-name:version line for each dependency.
For example, to use the jfiglet library, we can add the following line to the script: //DEPS com.github.lalyos:jfiglet:0.0.8.

> jbang init helloworld.java

Catalogs

Catalogs in JBang allow to organize and share scripts and templates efficiently.
This feature is particularly useful for teams or communities that want to share a collection of scripts for common tasks or workflows.
It is also useful for teachers who want to distribute starter codes or show results of exercises without providing the source code.

A catalog is a JSON file named jbang-catalog.json that contains two groups of items: aliases and templates.
Aliases allow to run scripts from a catalog using a simple command, while templates provide a starting point for new scripts.
Catalogs can be remote or local and it is possible to add and use as many local or remote repositories as needed.
It is interesting to point out that JBang creates, during its setup, a local catalog with some aliases and templates out of the box.

JBang looks for local catalogs in these directories in the following order (source JBang docs):

  1. Current directory, ./jbang-catalog.json
  2. In ./.jbang/jbang-catalog.json
  3. In the parent directory, ../jbang-catalog.json
  4. In the parent’s .jbang directory, ../.jbang/jbang-catalog.json
  5. And repeating steps 3 and 4 recursively upwards to the root of the file system
  6. As the last step it will look in $HOME/.jbang/jbang-catalog.json

JBang will look for remote the catalogs in many open source repositories like GitHub, GitLab, Bitbucket, and others.
I'll use GitHub as an example in this post.
To create a remote catalog, you need to add jbang-catalog.json to the root folder of your repository.
The catalog is then referred to by account/repository_name.
If your repository is named jbang-catalog, then you can refer to it by account.
So, for example, if my GitHub account is named yostane and I have a repository named cours-java that contains a catalog which a file named jbang-catalog.json, I can refer to that catalog by yostane/cours-java. Furthermore, if I have a jbang-catalog.json in a repository named jbang-catalog then I can refer to it by yostane/jbang-catalog or simply yostane.

> jbang helloworld.java
Hello world

The following chapters will show how to use aliases and templates from a catalog.

Aliases

Aliases in JBang allow to run scripts from a catalog.
The full syntax is jbang alias@account/repository [args] and jbang alias [args] for respectively a remote and local alias.

Aliases can be defined in the aliases section of the catalog file using the following format:

> jbang init helloworld.java

Here is the catalog I used during my session at DevoxxMA 2024.

> jbang helloworld.java
Hello world

You can run these aliases with the following commands:

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

The official JBang GitHub account provides a catalog with many aliases and templates.
Let's run some of them:

  • jbang httpd@jbangdev run a local webserver.
  • jbang gavsearch@jbangdev [arg] search for [arg] on search.maven.org.

Templates

Templates, which are pre-defined scripts that can be used as a starting point for new scripts.
They are defined in the templates section of the catalog file using the following format:

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

When a template is used, JBang creates copies of all the files int the file-refs property.
When a file-ref contains {basename}, JBang replaces it with the name of the script being created.
When a file-ref uses the .qute extension, JBang uses the Qute templating engine

Here are some examples of some templates available out of the box:

  • A CLI script that uses picocli: jbang init -t cli hellocli.java
  • A Quarkus single file REST API: jbang init -t qrest helloqrest.java

We can also use templates from the internet shared by the community.
For example, this command creates a JUnit unit test file: jbang init -t junit@jbangdev file_to_test.java.
From the command we can locate the jbang-catalog.json that defined the tempalte in the jbangdev/jbang-catalog repository.

/// 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

The JBang App Store is a web app that allows to browse aliases of indexed catalogs.
It provides a convenient way to discover and use various tools and utilities without the need for complex setup or installation processes.
For example, when we search for yostane, we should be able to find the different aliases that I have defined in my different catalogs.
The following image shows the result of the search.

JBang, the missing scripting tool of the Java ecosystem

Here are some interesting and funny scripts that I found by browsing on the the App Store:

  • Cowsay. Here are some examples of running the script:
    • jbang cowsay@ricksbrown/cowsay MOO!
    • jbang cowsay@ricksbrown/cowsay -f dragon "I'm Veldora Tempest!"
  • Find substring like grep: jbang grep@a-services "hello" .
  • Create PDF from images: images2pdf@a-services. The following commands will create a PDF file from two images:
///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")); } }

When you publish a catalog, it will very probably appear after the next indexing of the JBang AppStore.
It is a scheduled GitHub action defined here.

Some examples with notable frameowrks

With JBang, we can create single file applications that use popular frameworks and libraries.
Some examples include Quarkus, picolcli, and JavaFX.
Let's explore some example in the following sections.

JavaFX (openjfx)

JavaFX is a desktop and UI framework.
Its official website is openjfx.io and is also supported by Gluon which provides additional UI components and brings mobile app support to JavaFX.
JBang supports this frameowrk and can be used to create signle file JavaFX applications.

Here are some examples JavaFX apps created with JBang:

  • Basic window
  • More beautiful example jbang https://gist.github.com/FDelporte/c69a02c57acc892b4c996a9779d4f830
  • A template jbang init -t javafx@yostane hellojfx

Quarkus

Quarkus is a Java framework that is optimized for Kubernetes and serverless environments.
It provides a fast boot time and low memory consumption, making it ideal for cloud-native applications.

Thanks to JBang, we can create single-file Quarkus applications that leverage the power of this framework.
The following example shows a rest API that tests if a string is a palindrome. It has JSON parsing, logging and provides an OpenAPI and Swagger documentation.

> jbang init helloworld.java

We may notice a //SOURCES PalindromeService.java line in the script.
It tells JBang to look for a file named PalindromeService.java in the same directory as the script.
This means that JBang supports multi-file scripts.

You can run the server with jbang palqrest@yostane/cours-java and call the endpoint with curl http://localhost:8080/palindrome?input=madam.

> jbang helloworld.java
Hello world

Other languages

JBang supports running Java, Kotlin, JShell and Groovy code.
It can even run Java code from markdown files.
Here are some examples of how to use JBang with different languages:

  • Kotlin: You can initialize a Kotlin script with jbang init -t hello.kt filename.kt. Please note that this is different from the official .main.kts Kotlin scripts. In fact, Kotlin scripts created by JBang can benefit from the catalog and App Store features. Here is an example of a Kotlin script created with JBang.
> jbang init helloworld.java
  • Interesting fact: the idea of JBang came from kscript which is targeted to the Kotlin ecosystem.
  • Kotlin already has native scripting support (with .main.kts scripts) but seems to lack the catalog, template, and App Store features.
    • Groovy: Initialize a Groovy script with jbang init -t hello.groovy filename.groovy. Here is an example of a Groovy script created with JBang.
> jbang helloworld.java
Hello world
  • JShell: JBang supports JShell scripts with .jsh or .jshell extensions and inline scripts using jbang -c 'System.out.println("Inline Java ? yay!")'. Here is an example of a JShell script created with JBang.
///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 with Java and JShell code blocks: You can run Java and JShell code blocks directly from a markdown file using jbang my_markdown.md.
/// 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(); } }

The above is the detailed content of JBang, the missing scripting tool of the Java ecosystem. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Difference between HashMap and Hashtable? Difference between HashMap and Hashtable? Jun 24, 2025 pm 09:41 PM

The difference between HashMap and Hashtable is mainly reflected in thread safety, null value support and performance. 1. In terms of thread safety, Hashtable is thread-safe, and its methods are mostly synchronous methods, while HashMap does not perform synchronization processing, which is not thread-safe; 2. In terms of null value support, HashMap allows one null key and multiple null values, while Hashtable does not allow null keys or values, otherwise a NullPointerException will be thrown; 3. In terms of performance, HashMap is more efficient because there is no synchronization mechanism, and Hashtable has a low locking performance for each operation. It is recommended to use ConcurrentHashMap instead.

Why do we need wrapper classes? Why do we need wrapper classes? Jun 28, 2025 am 01:01 AM

Java uses wrapper classes because basic data types cannot directly participate in object-oriented operations, and object forms are often required in actual needs; 1. Collection classes can only store objects, such as Lists use automatic boxing to store numerical values; 2. Generics do not support basic types, and packaging classes must be used as type parameters; 3. Packaging classes can represent null values ??to distinguish unset or missing data; 4. Packaging classes provide practical methods such as string conversion to facilitate data parsing and processing, so in scenarios where these characteristics are needed, packaging classes are indispensable.

What are static methods in interfaces? What are static methods in interfaces? Jun 24, 2025 pm 10:57 PM

StaticmethodsininterfaceswereintroducedinJava8toallowutilityfunctionswithintheinterfaceitself.BeforeJava8,suchfunctionsrequiredseparatehelperclasses,leadingtodisorganizedcode.Now,staticmethodsprovidethreekeybenefits:1)theyenableutilitymethodsdirectly

How does JIT compiler optimize code? How does JIT compiler optimize code? Jun 24, 2025 pm 10:45 PM

The JIT compiler optimizes code through four methods: method inline, hot spot detection and compilation, type speculation and devirtualization, and redundant operation elimination. 1. Method inline reduces call overhead and inserts frequently called small methods directly into the call; 2. Hot spot detection and high-frequency code execution and centrally optimize it to save resources; 3. Type speculation collects runtime type information to achieve devirtualization calls, improving efficiency; 4. Redundant operations eliminate useless calculations and inspections based on operational data deletion, enhancing performance.

What is an instance initializer block? What is an instance initializer block? Jun 25, 2025 pm 12:21 PM

Instance initialization blocks are used in Java to run initialization logic when creating objects, which are executed before the constructor. It is suitable for scenarios where multiple constructors share initialization code, complex field initialization, or anonymous class initialization scenarios. Unlike static initialization blocks, it is executed every time it is instantiated, while static initialization blocks only run once when the class is loaded.

What is the `final` keyword for variables? What is the `final` keyword for variables? Jun 24, 2025 pm 07:29 PM

InJava,thefinalkeywordpreventsavariable’svaluefrombeingchangedafterassignment,butitsbehaviordiffersforprimitivesandobjectreferences.Forprimitivevariables,finalmakesthevalueconstant,asinfinalintMAX_SPEED=100;wherereassignmentcausesanerror.Forobjectref

What is type casting? What is type casting? Jun 24, 2025 pm 11:09 PM

There are two types of conversion: implicit and explicit. 1. Implicit conversion occurs automatically, such as converting int to double; 2. Explicit conversion requires manual operation, such as using (int)myDouble. A case where type conversion is required includes processing user input, mathematical operations, or passing different types of values ??between functions. Issues that need to be noted are: turning floating-point numbers into integers will truncate the fractional part, turning large types into small types may lead to data loss, and some languages ??do not allow direct conversion of specific types. A proper understanding of language conversion rules helps avoid errors.

What is the Factory pattern? What is the Factory pattern? Jun 24, 2025 pm 11:29 PM

Factory mode is used to encapsulate object creation logic, making the code more flexible, easy to maintain, and loosely coupled. The core answer is: by centrally managing object creation logic, hiding implementation details, and supporting the creation of multiple related objects. The specific description is as follows: the factory mode handes object creation to a special factory class or method for processing, avoiding the use of newClass() directly; it is suitable for scenarios where multiple types of related objects are created, creation logic may change, and implementation details need to be hidden; for example, in the payment processor, Stripe, PayPal and other instances are created through factories; its implementation includes the object returned by the factory class based on input parameters, and all objects realize a common interface; common variants include simple factories, factory methods and abstract factories, which are suitable for different complexities.

See all articles