Usage
A minimal script is a single .java
file with a typical static void main
method or a .jsh
file which will be passed to jshell
.
Below is an (almost) minimal example you can save in helloworld.java
or simply run jbang init helloworld.java
:
///usr/bin/env jbang "$0" "$@" ; exit $? (1)
class helloworld { (2)
public static void main(String[] args) {
if(args.length==0) {
System.out.println("Hello World!");
} else {
System.out.println("Hello " + args[0]);
}
}
}
1 | By using this // style instead of shebang #! you trick bash , zsh etc. to run this as a script while still being valid java code. |
2 | A classname, can be anything when using jbang but to be valid java for most IDEs you’ll want to name it the same as the source file. |
Now to run this you can call it via jbang
:
jbang helloworld.java
or if on Linux/OSX/AIX run it directly. If you created it manually you need to mark it as executable before running it.
chmod +x helloworld.java
./helloworld.java jbang!
If you are using another shell than bash or zsh, like Fish shell be aware that such shell limits the syntax in top line to start with |
When no JDK version is available in the PATH, JDK 11 will be downloaded by default to bootstrap jbang.
If your script requires a higher version and you don' want to download two JDK’s, you can define an alternative default
with $ JBANG_DEFAULT_JAVA_VERSION=14 jbang my-script.java Note that if JDK is found in the PATH, It’s also possible to override the exact JDK distribution that will be used by setting the $ JBANG_DEFAULT_JAVA_VERSION=18 JBANG_JDK_VENDOR=oracle jbang my-script.java Note that if a JDK of matching version is already installed these env variables will have no effect! They only take effect when an actual JDK installation is performed. To force JBang to install such a JDK one would first have to uninstall the existing JDK and then reinstall it with these env variables set to their intended values. |
Default application
If you pass a directory or a url ending in /
jbang will look for main.java
to run as default application for that directory / location.
URLs from Trusted Sources
You can use http(s):/
and file:/
url’s for input:.
jbang https://gist.github.com/maxandersen/f43b4c52dfcfc42dcd59a04e49acf6ec
For safety reasons jbang will not run arbitrary urls before you indicated you trust their source. Thus when running the above for the first time you will see the following warning about the url not being a trusted source:
jbang https://gist.github.com/maxandersen/f43b4c52dfcfc42dcd59a04e49acf6ec
[jbang] https://gist.github.com/maxandersen/f43b4c52dfcfc42dcd59a04e49acf6ec is not from a trusted source thus not running it automatically.
If you trust the url to be safe to run you can do one of the following:
0) Trust once: Add no trust, just run this time
1) Trust this url in future:
jbang trust add https://gist.github.com/maxandersen/
Any other response will result in exit.
[jbang] Type in your choice (0 or 1) and hit enter. Times out after 10 seconds.
You can then choose 0 to run once or 1 to trust the suggested url. If you don’t answer within 10 seconds jbang will exit.
To enable running it without such question you need to mark that url or a sub part of it as a trusted source.
i.e. jbang trust add https://github.com/maxandersen/
will tell jbang
to trust anything with that base url.
You can see more in the comments of the ~/.jbang/trusted-sources.json
.
Sites such as GitHub, gitlab, bitbucket, gist, carbon.now.sh jbang will try and extract the proper source rather than the raw html.
i.e. doing |
URL’s will follow redirects. In case you need to use it with sites with self-signed/non-trusted certificates you can
if you trust the site use |
Build and run native image (Experimental)
There is support for using native-image
from GraalVM project to produce a binary executable.
Since not all java libraries can automatically be built with native-image
- especially if using reflection feature are considered highly experimental.
Just run jbang --native helloworld.java
and jbang
will use native-image
from either $JAVA_HOME/bin
or $GRAALVM_HOME/bin
or $PATH
to
produce a native image binary.
If you want to have a copy of the generated binary you can run jbang export local -n helloworld.java
.
You can install the native-image
utility binary e.g. by installing GraalVM from https://www.graalvm.org/downloads, and then once running gu install native-image
as per https://www.graalvm.org/reference-manual/native-image.
If you use |
Using .jsh
for jshell
There is support to run .jsh
via jshell
. The advantage of jshell
is that you do not need to have a class or static main method.
Classic jshell
does not support passing in arguments nor system properties, jbang
does.
In the case of .jsh
files jbang
injects a startup script that declares a String[] args
which will contain any passed in arguments,
and it sets any properties passed in as -Dkey=value
as parameters to jbang
.
That means you can run a script as jbang -Dkey=value helloworld.jsh World
and retrieve arguments and properties as:
System.out.println("Hello " + (args.length>0?args[0]:"World")); (1)
System.out.println(System.getProperty("key")); (2)
1 | Line where args are accessible without previous declaration. |
2 | System properties set when passed as -D arguments to jbang |
The script will have the output:
Hello World value
Please note that .jsh
files are source only, they are not compiled thus they are not cached nor can they be built as native images.
If you use |
Running Kotlin (.kt) (EXPERIMENTAL)
As an experiment since 0.71.0 JBang supports building Kotlin files using kotlinc
.
jbang init -t hello.kt hello.kt
./hello.kt
[jbang] Downloading Kotlin 2.0.21. Be patient, this can take several minutes...
[jbang] Installing Kotlin 2.0.21...
[jbang] Resolving dependencies...
[jbang] org.jetbrains.kotlin:kotlin-stdlib:2.0.21
[jbang] Dependencies resolved
[jbang] Building jar for hello.kt...
Hello World
Running Groovy (.groovy) (EXPERIMENTAL)
As an experiment since 0.85.0 JBang supports building Groovy files using groovyc
.
jbang init -t hello.groovy hello.groovy
jbang hello.groovy
[jbang] Downloading Groovy 3.0.9. Be patient, this can take several minutes...
[jbang] Installing Groovy 3.0.9...
[jbang] Resolving dependencies...
[jbang] Resolving org.codehaus.groovy:groovy:jar:3.0.9...Done
[jbang] Dependencies resolved
[jbang] Building jar...
Hello World
You can control the version of Groovy used via //GROOVY <version>
in the script.
For example //GROOVY 3.0.19
will use Groovy 3.0.19.
Running Markdowns (.md) (EXPERIMENTAL)
As an experiment since 0.85.0 JBang supports "running" Markdown files (.md)
I.e. if you save the following as readme.md
:
## Markdown Scripts
It is possible to write scripts using markdown.
JBang will extract code found in `java` or `jsh` or `jshelllanguage` code blocks.
Try run `jbang readme.md`.
```java
class Demo {
void test() {
System.out.println("Hello, World!");
}
}
```
It will take all blocks and execute via jshell by default and if main method found it will treat it as a .java file.
```jshelllanguage
new Demo().test();
```
You can of course also use `//DEPS` in the code blocks.
```jsh
//DEPS com.github.lalyos:jfiglet:0.0.8
import com.github.lalyos.jfiglet.FigletFont;
System.out.println(FigletFont.convertOneLine(
"Hello " + ((args.length>0)?args[0]:"jbang")));
```
Oh, and did you notice it handled arguments too?
```java
if(args.length==0) {
System.out.println("You have no arguments!");
} else {
System.out.printf("You have %s arguments! First is %s", args.length, args[0]);
}
```
You can run it with jbang readme.md YOLO!
and give it a result like:
Hello, World!
_ _ _ _ __ __ ___ _ ___ _
| | | | ___ | | | | ___ \ \ / / / _ \ | | / _ \ | |
| |_| | / _ \ | | | | / _ \ \ V / | | | | | | | | | | | |
| _ | | __/ | | | | | (_) | | | | |_| | | |___ | |_| | |_|
|_| |_| \___| |_| |_| \___/ |_| \___/ |_____| \___/ (_)
You have 1 arguments! First is YOLO!%
Running script passed as argument
jbang can run scripts that are passed directly on the command line using the --code
option:
jbang --code System.out.println("Hello World!")
Running script from standard input
jbang can run scripts directly from standard input using -
or /dev/stdin
as input.
i.e. then you can "pipe" the script to jbang:
echo 'System.out.println("Hello World!");' | jbang -
jbang will try and guess if the piped content is a java class and if not assume it it is jshell code.
To force jbang to run it as a jshell script you can use --jsh
flag.
If you use |
If your own code needs to handle chained pipes well it is recommended to add the following code:
It will give a compiler warning as it is internal API; but for now it works. |
Running .jar
's
jbang
will also run .jar
files directly.
i.e. jbang helloworld.jar
will run helloworld.jar
if found on your local file system.
The .jar
can be a local file or a http/https url.
You can also run a .jar
file referenced by a Maven coordinate, i.e.:
jbang info.picocli:picocli-codegen:4.6.3
This will fetch the dependency stated and put the transitive dependencies on the class-path.
If you need to specify a main class you can do so by using --main
i.e.
jbang --main picocli.codegen.aot.graalvm.ReflectionConfigGenerator info.picocli:picocli-codegen:4.6.3
A side effect of running GAV as a jar, the GAV could also be a |
Usage on Windows
Some JBang commands need to create symbolic links when running on Windows.
For example, this is required for editing the files with the edit
command.
If you encounter issues on Windows related to the creation of symbolic links follow these instructions:
-
From Windows 10 onwards you can turn on "Developer Mode", this will automatically enable the possibility to create symbolic links. Read here how to enable this mode: Enable your device for development. On Windows 11 this might already be enabled by default.
-
If you’re using a Java version equal to or newer than 13 then you’re good to go. This Java version already works correctly. Make sure that JBang is actually using that Java version, either by running
java -version
to check if the Java on thePATH
is version 13 or newer, or if you don’t have Java available on thePATH
by runningjbang jdk default 13
(or some newer version of course). -
If you need symbolic links to work on older Java versions as well, then there is no other option than setting the correct privileges for your user by enabling the
Create symbolic links
group policy setting. See the instruction on this page for more information on how to do this: Permission to make symbolic links in Windows.