File Organization
Multiple source files
It is possible to use multiple source files just by having them in the same source directory. To a limited extend, it also works with packages.
For example the example below works by just calling jbang Main.java
:
import model.Person;
public class Main {
public static void main(String... args) {
Person p = new Person(args[0]);
System.out.println("Hello " + p.getName());
}
}
package model;
public class Person {
String name;
public String getName() { return name; }
public Person(String n) { this.name = n; }
}
There are some cases where the above does not work; i.e. if two packages refer to each other - i.e. model.Person
referring to util.Generator
will fail. Also jbang edit
does not know about multiple sources as it runs and must run before compilation occurs.
Since version 0.46 there is now support for having that all work with multiple source files. The main script file defines all the
dependencies and you add more source files into the application using //SOURCES <filename>
. If included source has //SOURCES
that will also get included recursively. In the case of .jsh
scripts, the included sources will be added in the order they are
found, depth-first.
The listed file name(s) gets added to source list when compiling.
Currently there is no *.java
style matching or support for .java
files to declare //DEPS
or other jbang configurations.
That will currently only be honored by the main script/app. These will be loosened up in future based on feedback.
Adding more resources
If you want to add a META-INF/application.properties
or META-INF/resource.index.html
or other files to the generated jar
you can use //FILES
to add them.
The format is //FILES <mountpoint>[=<sourcefile>]
.
Example:
//FILES resource.properties //FILES META-INF/resources/index.html=index.html
Here resource.properties
will be copied as is and META-INF/resources/index.html
gets its content from index.html
.
All locations need to be relative to the script location. |
Currently jbang edit and http(s) based script do not work with //FILES .
|
Extension-less/non-java files for cli-plugins
You can use jbang
to write plugins for cli’s like kubectl
, git
, etc.
They expect their plugins to be named like <cmd>-<plugin>
, i.e. kubectl-myplugin
.
Furthermore some of them, particularly kubectl
currently require the file to start with #!
otherwise you get a exec format error
.
There are two ways to have that work. The first recommended way is to use jbang app install
which setups an intermediate script
to avoid the issue, i.e. jbang app install --name kubectl-my-plugin myplugin.java
.
The second is to use a bit of auto-magic jbang
has to help in case you only want a single file, no intermediate script. That
is described below.
Kebab casing of filename
jbang
lets you name your file without a .java
or .jsh
extension, such
as kubectl-my-plugin
or myjavascript.sh
. jbang
will in this case copy the file to a temporary
directory using kebab-case to map the name to a proper java class name.
For example, if you make a file called kubectl-my-plugin
then jbang
will assume the actual class name to launch
to be KubectlMyPlugin
.
Note, similar is done when using jbang edit
, here the symbolic link will be made so the IDE will treat it as
regular camel cased java class.
If you do not follow this naming pattern you will get a compile error as javac expects both the public class and file names to be equal.
|
she-bang auto-stripped
For extension less scripts, you can put #!' header at the beginning to let apps recognize
it is to be treated as a script. To avoid issues when compiling, `jbang
will remove
that line before compilation.
For now this is required for kubectl
plugin but not git
. Issue opened on this limitation.