Running
Interactive REPL
jbang --interactive
enables use of jshell
to explore and use your script and any dependencies in a REPL editor.
When using --interactive
for java/jar scripts/apps jbang sets up a jshell function named userMain
. userMain
delegates to
the main function that would have been called if not running in interactive. You can call it with arguments as follows userMain(args)
.
One caveat about jshell is that it cannot access classes in default package. Thus you will need to add a package statement to your script/class to see it. |
Flight Recorder
Flight recorder is a feature of the Java VM that lets you gather diagnostic and profiling data about your script.
You can use //RUNTIME_OPTIONS
to have full control over it; but for the easiest setup jbang
lets you just run with --jfr
, e.g.,
jbang --jfr myapp.java
By default --jfr
will start flight recorder and tell it to dump event recordings to myapp.jfr
(i.e. using base name of the script as its filename).
Then you can use tools like jvisualvm
or jmc
to explore the data.
If you want to tweak the configuration you can pass flight recorder options, like jbang --jfr=filename={basename}.jfr,maxage=24h
where {basename}
will be replaced
by the filename and then added maxage=24h
to flight recording options.
If you want further control use //COMPILE_OPTIONS -XX:StartFlightRecording=<your options>
instead.
java
, javac
and nativeimage
Options
You can pass options directly from JBang to the compiler and runtime tools that it uses to build and run your code.
The following source tags are available for setting JVM (java
) options, compiler options (javac
, kotlinc
, etc) and native image builders (nativeimage
) respectively: //RUNTIME_OPTIONS
, //COMPILE_OPTIONS
and //NATIVE_OPTIONS
.
You can also set the same options from the command line using: --runtime-option
, --compile-option
and --native-option
.
As an example, if you want to enable preview features you can set up the necessary options as in the following example that uses Java 14 experimental record
feature:
///usr/bin/env jbang "$0" "$@" ; exit $?
//COMPILE_OPTIONS --enable-preview -source 14
//RUNTIME_OPTIONS --enable-preview
import static java.lang.System.*;
public class records {
record Point(int x, int y) {}
public static void main(String[] args) {
var p = new Point(2,4);
out.println(p);
}
}
Since Java 9 JDK_JAVA_OPTIONS and JDK_JAVAC_OPTIONS are also picked up by the Java runtime and compiler automatically.
For Java 8 and if you want to set explicitly only for jbang
you can also add flags by setting JBANG_JAVA_OPTIONS
and JBANG_JAVAC_OPTIONS
respectively.
Module support (EXPERIMENTAL)
You can mark code as being part of a module by adding the following line:
//MODULE <module-name>
This will make JBang treat the code a being a module with the given name, and it will compile it as such. Any declared dependencies are automatically marked as being required.
You can also set this on the command line by using the --module=<name>
option on the jbang build
command.
The option also exists for jbang run
where it will treat anything to be run as a module.
Setting main class
Normally JBang will figure out by itself what your code’s main class is, but in case you want to override this behaviour in code, you can use the following line:
//MAIN <main-class-name>
The main class selected by the line is permanent and will be stored as the default main class in the resulting JAR file.
One can also override the main class on the command line by using --main <name>
or -m <name>
for jbang build
or jbang run
. Main classes set for jbang build
are permanent, just like
using a //MAIN
line in the code. But main classes set for jbang run
are temporary and will
only be used for that execution run.
Adding entries to MANIFEST.MF
If you want to set custom entries in the MANIFEST.MF
file of the Jar file generated by JBang then you can
do so adding a //MANIFEST
line to your source file. It takes a list of key=value items separated by spaces.
If an item has no equals sign and no value than the value is taken to be the string "true".
//MANIFEST Built-By=Shadowman Sealed
(Experimental) Application Class Data Sharing
If your scripts uses a lot of classes Class Data Sharing might help on your startup. The following requires Java 13+.
Using --cds
jbang will build the jar with Application Class Data Sharing enabled and when run have it load shared class data.
You can put //CDS
in the java file to enable it by default, or simply use --cds
to force it or --no-cds
to turn it off no matter what the jbang script file contains.
Java Agents
You can activate a javaagent using --javaagent=<agent>[=<options>]
where agent can be a already packaged agent jar from file, http url or Maven Coordinate.
It can also be a jbang script itself where you have put //JAVAAGENT
to activate agent packaging.
You can create a basic agent using jbang init -t agent myagent.java
to get started.
Remote File Arguments
The run
command has a special feature where any of the arguments for the code to be
executed can be a reference to a remote file by appending a %
in front of a URL.
Imagine for example a wordcount.java
script that takes as its argument a path
to a file. Now with this feature we could write:
$ jbang run wordcount.java %https://github.com/jbangdev/jbang/blob/main/README.md
JBang will download the given file to its local cache and then run the code with the path to the file substituted for the URL. It will be as if the code has suddenly acquired the feature to read and analyse remote files!
There is an alternative syntax in case the substitution needs to be part of an existing text, for example when it has to be part of a flag passed to an application:
$ jbang run analyse.java --file=%{https://github.com/jbangdev/jbang/blob/main/README.md}
In this case wrap the URL with braces to explicitly mark the beginning and end.
Remote-File for --javaagent
The remote-file syntax is also available for the --javaagent
option for the run
command, for example:
$ jbang —javaagent=byteman@maxandersen=script:%{https://xam.dk/myscript.btm myapp.java}
As you can see it’s necessary here to use the syntax with the braces because it’s part of larger string of text.
Escaping Remote-File Arguments
If, for some reason, you really need to be able to pass the text %http://some.url
to
an application without JBang downloading the file and turning it into a file path for you,
then you simply add an extra %
to the beginning. That will tell JBang to ignore what
follows and just treat it as an ordinary string of text. For example:
$ jbang run wordcount.java %%https://github.com/jbangdev/jbang/blob/main/README.md
Would simply pass %https://github.com/jbangdev/jbang/blob/main/README.md
to the script.