Using Java as scripting language has become a popular option in the last few years thanks to the JShell tool. In this article we will learn how the JBang scripting tool can take your Java scripting power at another level.
Automatic fetching of dependencies
The most impressing feature of JBang is dependency management. You can run a Java application as a script and configure dependencies in multiple ways. The simplest one is to specify your dependencies in your Java class using a Comment notation:
///usr/bin/env jbang "$0" "$@" ; exit $? //DEPS io.quarkus:quarkus-resteasy:2.7.2.Final import io.quarkus.runtime.Quarkus; import javax.enterprise.context.ApplicationScoped; import javax.ws.rs.GET; import javax.ws.rs.Path; @Path("/hello") @ApplicationScoped public class quarkus { @GET public String sayHello() { return "hello from Quarkus with jbang.dev"; } }
If you don’t want to hard code the dependencies in your Class, you can use the –deps command line option. For example, you can run the above example also with:
jbang --deps=io.quarkus:quarkus-resteasy:2.7.2.Final quarkus.java
Fetching dependencies from a Remote Repository
This is an awesome hack. Suppose you are working on a Repository that is going under development. Therefore, you don’t want to refer to a specific JAR file from your local Maven repository. Then, you can just add the GitHub repository reference in your code:
///usr/bin/env jbang "$0" "$@" ; exit $? //DEPS https://github.com/DiUS/java-faker import com.github.javafaker.Faker; public class Hello { public static void main(String[] args) { // Create a new instance of the Faker class Faker faker = new Faker(); // Use the "name" method to generate a random name String randomName = faker.name().fullName(); // Print the random name to the console System.out.println("Random name: " + randomName); } }
As you can see, JBang will (under the hoods) build the repository and add it as dependency for your Class:
jbang Hello.java [jbang] Resolving dependencies... [jbang] com.github.DiUS:java-faker:-SNAPSHOT [jbang] Dependencies resolved [jbang] Building jar... Random name: Laticia Gerlach
Using Command Line Options
JBangs allows to provide command line options to your script. When you use this feature in combination with the CommandLine template the result is amazing. An example is worth 1000 words:
import picocli.CommandLine; import io.quarkus.runtime.annotations.QuarkusMain; import io.quarkus.runtime.QuarkusApplication; import java.sql.*; @CommandLine.Command public class jdbc implements Runnable { @CommandLine.Option(names = {"-q", "--query"}, description = "SQL Query", defaultValue = "select now()") String QUERY; @CommandLine.Option(names = {"-url"}, description = "JDBC URL", defaultValue = "jdbc:postgresql://localhost:5432/postgres") String DB_URL; @CommandLine.Option(names = {"-u", "--user"}, description = "username", defaultValue = "postgres") String USER; @CommandLine.Option(names = {"-p", "--password"}, description = "password", defaultValue = "postgres") String PASS; @Override public void run() { try(Connection conn = DriverManager.getConnection(DB_URL, USER, PASS); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(QUERY);) { // Extract data from result set ResultSetMetaData meta = rs.getMetaData(); int colCount = meta.getColumnCount(); while (rs.next()) { for (int col=1; col <= colCount; col++) { Object value = rs.getObject(col); if (value != null) { System.out.print(value.toString()); } } } } catch (SQLException e) { e.printStackTrace(); } } }
So, the above example uses the Pico CLI template and contains multiple CommandLine.Option. Look at what you can do with it:
jbang --deps=org.postgresql:postgresql:42.3.3 jdbc.java --query="select now()" --user=postgres --password=postgres
In a nutshell, you can connect to any Database through a JDBC Driver and run a SQL Statement. You will pass the connection parameters as command line options.

Run scripts from remote sources
Another cool feature is the ability to run JBang Class files from remote (trusted sources). For example, we will execute the hello.java Class from JBang catalog
jbang https://github.com/jbangdev/jbang-catalog/blob/master/hello.java Frank Hello Frank
You can even use an alias to reference the remote repository. For example, to reference the hello.java which is in jbang-catalog repository of GitHub jbangdev user, you can simply use the jbangdev alias:
jbang hello@jbangdev
Execute Java code snippets from the shell
JBang lets you execute Java code snippets at your fingertips with the -c options. Here’s an example to generate a random String:
jbang -c 'System.out.println(java.util.UUID.randomUUID())' efa845ef-48c7-467d-a6b7-2994900d403f
On the other hand, you can pipe the result of a shell command into JBang. In this case, you will get as input the stream of characters through the Java String lines() method. Then, you can use the Java Stream API to elaborate on your lines of text. For example, to uppercase the content of a file you can use:
cat hello.txt | jbang -c 'lines().forEach(line -> System.out.println(line.toUpperCase()))' HELLO WORLD JBANG!
Remote File expansion
Version v0.104.0 of JBang allows you to perform Remote File Expansion of JBang Arguments. You need to prefix the remote file with the percent (%) symbol. This allows you utilize jbang’s file download and caching mechanism to let your scripts that deal with local files to handle remote urls.
For example:
jbang CountWords.java %https://github.com/dwyl/english-words/raw/master/words.txt
Manage JDK from JBang
Do you need a quick way to install Java? or force using a specific Java version? That’s a piece of cake.
To install Java 17, that’s enough:
jbang jdk install 17
On the other hand, to check the list of JDK installed:
jbang jdk list
Finally, to force JBang to use a specific Java version, use the //JAVA comment at the top of it:
///usr/bin/env jbang "$0" "$@" ; exit $? //JAVA 14 class helloworld { public static void main(String[] args) { if(args.length==0) { System.out.println("Hello World!"); } else { System.out.println("Hello " + args[0]); } } }
Aliases
To simplify the execution of JBang scripts, yo can add aliases to them. These aliases are stored locally in a jbang-catalog.json file, and can be as well accessed from everywhere.
For example, supposing you were to execute the following remote script:
jbang https://github.com/jbangdev/jbang-catalog/blob/main/hello.java Hey Hello Hey
You can create an alias to that script using the “jbang alias” command. For example:
jbang alias add -f . https://github.com/jbangdev/jbang-catalog/blob/main/hello.java [jbang] Alias 'hello' added to './jbang-catalog.json'
From now on, you can refer to that alias to run the hello.java script:
jbang hello Hey! Hello Hey!
In the above example, we have stored the alias locally. JBang can also use JBang aliases available on GitHub in JBang Catalogs
As an example, check this article to learn how to run the Camel JBang App: How to run JBangs apps from the Catalog.