Jekyll2024-03-19T05:22:24+00:00https://jbang.dev/feed.xmlJBangjbang is a tool that makes it easy to get started with java and enable experimentation and exploration without the traditional overhead and ceromony with traditional java toolsJBangjbang-python: Java in your Python2023-09-11T00:00:00+00:002023-09-11T00:00:00+00:00https://jbang.dev/learn/python-with-jbang<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Happy to announce <a href="https://github.com/jbangdev/jbang-python">jbang-python</a> - a pypi package which brings your Java to your Python project or notebook.</p>
</div>
<div class="paragraph text-center">
<p><span class="image"><img src="https://github.com/jbangdev/jbang-python/blob/main/python_jbang.png?raw=true" alt="python jbang" width="50%"></span></p>
</div>
<div class="paragraph">
<p><code>jbang-python</code> supports running any kind java code that JBang supports.</p>
</div>
<div class="paragraph">
<p>Wether that is a script from the <a href="https://jbang.dev/appstore">AppStore</a>, a Maven GAV, a jar or simply a java file stored in your project.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="example">Example</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In your <code>requirements.txt</code> add:</p>
</div>
<div class="paragraph">
<p><code>jbang-python</code></p>
</div>
<div class="paragraph">
<p>or install it using <code>pip install jbang</code></p>
</div>
<div class="paragraph">
<p>Then in your python code you can do:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">import jbang
output = jbang.exec('--java 21', 'properties@jbangdev', 'java').stdout
print(output)
output = jbang.exec('hello.java').stdout
print(output)</code></pre>
</div>
</div>
<div class="paragraph">
<p>With a <code>hello.java</code> that contains:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">//DEPS com.github.lalyos:jfiglet:0.0.8
import com.github.lalyos.jfiglet.FigletFont;
class hello {
public static void main(String... args) throws Exception {
System.out.println(FigletFont.convertOneLine(
"Hello " + ((args.length>0)?args[0]:"jbang"))); ;;
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When you run this it will automatically install JBang and Java if necessary and then run the requested alias and java code.</p>
</div>
<div class="paragraph">
<p>Besides using it in your python code locally you can also use it from Jupyter Notebooks.</p>
</div>
<div class="paragraph">
<p>The <code>jbang-python</code> package is available on <a href="https://pypi.org/project/jbang/">pypi</a> and the source code is available on <a href="https://github.com/jbangdev/jbang-python" class="bare">https://github.com/jbangdev/jbang-python</a>.</p>
</div>
<div class="paragraph">
<p>Have fun!</p>
</div>
</div>
</div>Max Rydahl AndersenHappy to announce jbang-python - a pypi package which brings your Java to your Python project or notebook.jbang-npm: Java Script in your JavaScript2022-04-01T00:00:00+00:002022-04-01T00:00:00+00:00https://jbang.dev/learn/jbang-npm<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Today we are announcing <a href="https://github.com/jbangdev/jbang-npm">jbang-npm</a> a npm package which brings you Java Script to your JavaScript project.</p>
</div>
<div class="paragraph">
<p><code>jbang-npm</code> joins <code><a href="https://github.com/jbangdev/jbang-maven-plugin">jbang-maven</a></code> and <code><a href="https://github.com/jbangdev/jbang-gradle-plugin">jbang-gradle</a></code> as tools that brings the power of Java Script to your favourite build setup.</p>
</div>
<div class="paragraph text-center">
<p><span class="image"><img src="https://github.com/jbangdev/jbang-npm/raw/main/java_script.png" alt="java script" width="50%"></span></p>
</div>
<div class="paragraph">
<p><code>jbang-npm</code> supports running any kind java code that JBang supports.</p>
</div>
<div class="paragraph">
<p>Wether that is a script from the <a href="https://jbang.dev/appstore">AppStore</a>, a Maven GAV, a jar or simply a java file stored in your project.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="example">Example</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Given you have a script name <code>test.js</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-javascript hljs" data-lang="javascript">#! /usr/bin/env node
const jbang = require('@jbangdev/jbang');
jbang.exec('--java 18', 'properties@jbangdev', 'java');
jbang.exec('hello.java', '"Java Script"')</code></pre>
</div>
</div>
<div class="paragraph">
<p>And in <code>package.json</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-json hljs" data-lang="json">{
"scripts": {
"test": "node test.js"
},
"devDependencies": {
"@jbangdev/jbang": "^0.1.4"
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>With a <code>hello.java</code> that contains:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">//DEPS com.github.lalyos:jfiglet:0.0.8
import com.github.lalyos.jfiglet.FigletFont;
class hello {
public static void main(String... args) throws Exception {
System.out.println(FigletFont.convertOneLine(
"Hello " + ((args.length>0)?args[0]:"jbang"))); ;;
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When you run this using <code>npm run test</code> it will automatically install JBang and Java if necessary and you get an output like:</p>
</div>
<div class="paragraph">
<p><span class="image"><img src="/images/jbang-npm-output.png" alt="jbang npm output"></span></p>
</div>
<div class="paragraph">
<p>In this case JBang was already installed but it did go transparently and downloaded Java 18 as one of the scripts was called with <code>--java 18</code>.</p>
</div>
<div class="paragraph">
<p>The opportunities are endless!</p>
</div>
<div class="paragraph">
<p><code>jbang-npm</code> was contributed by Peter Thomas and Pallafor Yodis from <a href="https://karatelabs.github.io/karate/">Karate</a> hall of fame.</p>
</div>
<div class="paragraph">
<p>Very much appreciated and looking forward to see what you make happen with Java Script in your JavaScript!</p>
</div>
<div class="paragraph">
<p>Have fun!</p>
</div>
</div>
</div>Max Rydahl AndersenToday we are announcing jbang-npm a npm package which brings you Java Script to your JavaScript project.JBang Rewind 2021!2022-01-03T00:00:00+00:002022-01-03T00:00:00+00:00https://jbang.dev/learn/jbang-rewind<div class="paragraph">
<p>We just closed on a very busy 2021 for JBang, and especially in the last few weeks, things progressed quite a bit. Therefore I thought it would be nice to give a quick overview to recognize the progress and give you a chance to catch up!</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">December 31st</dt>
<dd>
<p><a href="https://www.jdoodle.com/try-jbang/">JDoodle</a> updates their iOS and Android versions to include JBang support. You can now edit and run Java/JBang on the go.</p>
</dd>
<dt class="hdlist1">December 29th</dt>
<dd>
<p><a href="https://www.baeldung.com/jbang-guide">Guide to JBang</a> posted on baeldung.com</p>
</dd>
<dt class="hdlist1">December 25th</dt>
<dd>
<p>Free IntelliJ License giveaway for one <a href="https://github.com/jbangdev/jbang/blob/main/CONTRIBUTORS.md">recognized JBang contributor</a> following the steps outlined <a href="https://github.com/jbangdev/jbang/discussions/1155">here</a>. It is a time of writing still open; thus, if you ever opened an issue, contributed an idea or code, or want to contribute, it is still possible to get it!</p>
</dd>
<dt class="hdlist1">December 22nd</dt>
<dd>
<p><a href="https://plugins.jetbrains.com/plugin/18257-jbang">IntelliJ Plugin</a> made available. Provides direct execution with JBang, content assist for <code>//DEPS</code> and other keywords, and more.</p>
</dd>
<dt class="hdlist1">December 1st</dt>
<dd>
<p>JBang was the <a href="https://www.javaadvent.com/2021/12/jbang-gift-that-keeps-on-giving.html">first entry</a> of 2021 Java Advent Calendar.</p>
</dd>
<dt class="hdlist1">November 29th</dt>
<dd>
<p>JDoodle added <a href="https://www.jdoodle.com/try-jbang/">JBang to its list of supported languages</a>. Making it possible to edit/write Java code using dependencies in a browser without login and additionally embed JBang examples in your blog/guides.</p>
</dd>
<dt class="hdlist1">November 24th</dt>
<dd>
<p>Microsoft made a <a href="https://github.com/microsoft/jbang-catalog">JBang catalog available</a> providing easy launch of Minecraft and Playwright CLI.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>And in between, we had four releases of JBang in December with features and bug fixes - heading <a href="https://github.com/orgs/jbangdev/projects/2">towards the mythical 1.0</a> release.</p>
</div>
<div class="paragraph">
<p>The latest one is <a href="https://github.com/jbangdev/jbang/releases/tag/v0.86.0">0.86.0</a> which came on the second anniversary of JBang - or at least the <a href="https://twitter.com/maxandersen/status/1212714007301365761">first tweet</a> about it.</p>
</div>
<div class="paragraph">
<p>Here, one fix was how JBang deals with <code>lib</code> vs. <code>libs</code> that came from a conversation around using JBang in serverless lambda functions. Nándor Holozsnyák just made a <a href="https://dev.to/nandorholozsnyak/jbang-quarkus-aws-lambda-terraform-3-4ahk">blog</a> showing his explorations into this. I was happy to see this as Nandor looked into this because he felt JBang enabled a simple scripting approach comparable to Python/Node - but for Java.</p>
</div>
<div class="paragraph">
<p>That’s precisely what JBang is about - enabling easy use of Java - I’m expecting to see more enablement of using JBang for more than just scripts in 2022!</p>
</div>
<div class="paragraph">
<p>Here is to make 2022 about bringing JBang to version 1.0 and making Java fun!</p>
</div>Max Rydahl AndersenWe just closed on a very busy 2021 for JBang, and especially in the last few weeks, things progressed quite a bit. Therefore I thought it would be nice to give a quick overview to recognize the progress and give you a chance to catch up!JEP 408: Simple Web Server with JBang2021-06-03T00:00:00+00:002021-06-03T00:00:00+00:00https://jbang.dev/learn/jep-408-with-jbang<div class="paragraph">
<p>In March <a href="https://openjdk.java.net/jeps/408">JEP: 408: Simple Web Server</a> was announced. One of JEP 408’s goals is to make an easy to use web server available with Java using <code>java -m jdk.httpserver</code>.</p>
</div>
<div class="paragraph">
<p>It is a nice idea and I’m looking forward to see it happen.</p>
</div>
<div class="paragraph">
<p>That said - you do not need to wait for Java 18+ to get this. You can use <code>jbang httpd@jbangdev</code> today with Java 1.8 and upwards.</p>
</div>
<div class="paragraph">
<p>It is a <a href="https://github.com/jbangdev/jbang-catalog/blob/main/httpd.java">script</a> I wrote in a few hours after seeing <a href="https://twitter.com/sebi2706/status/1399966303625097217">yet another tweet</a> asking for a simple to use webserver. Like JEP 408 it only uses classes available in the JDK, meaning zero additonal download and setup besides <a href="https://jbang.dev/download">installing</a> <code>jbang</code>.</p>
</div>
<div class="paragraph">
<p>By default, <code>httpd@jbangdev</code> will serve the current directory on <a href="https://localhost:8000" class="bare">https://localhost:8000</a>.</p>
</div>
<div class="paragraph">
<p>Below is an example of using <code>httpd@jbangdev</code> to serve this website locally from its statically generated Jekyll <code>_site</code> folder on port 8080.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-shell hljs" data-lang="shell">$ jbang httpd@jbangdev -p 8080 -d _site
[jbang] Building jar...
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) from /Users/max/code/jbangdev/jbang-catalog/_site ...
127.0.0.1 - - [04/Jun/2021:00:50:36 +0200] "GET /" 200 -
127.0.0.1 - - [04/Jun/2021:00:50:36 +0200] "GET /assets/css/main.css" 200 -
127.0.0.1 - - [04/Jun/2021:00:50:36 +0200] "GET /assets/js/main.min.js" 200 -
127.0.0.1 - - [04/Jun/2021:00:50:36 +0200] "GET /assets/images/logo.png" 200 -
127.0.0.1 - - [04/Jun/2021:00:50:36 +0200] "GET /assets/images/carbon-deps.png" 200 -
127.0.0.1 - - [04/Jun/2021:00:50:36 +0200] "GET /assets/images/carbon-install.png" 200 -
127.0.0.1 - - [04/Jun/2021:00:50:36 +0200] "GET /assets/images/carbon-java.png" 200 -
127.0.0.1 - - [04/Jun/2021:00:50:36 +0200] "GET /assets/images/feature-ide.png" 200 -
127.0.0.1 - - [04/Jun/2021:00:50:36 +0200] "GET /assets/images/feature-version-juggle.svg" 200 -
127.0.0.1 - - [04/Jun/2021:00:50:36 +0200] "GET /assets/images/feature-appstore.png" 200 -
127.0.0.1 - - [04/Jun/2021:00:50:36 +0200] "GET /assets/images/slider/bg-1.jpg" 200 -</code></pre>
</div>
</div>
<div class="paragraph">
<p>As with any other <code>jbang</code> capable application you can also choose to install it in your <code>PATH</code> using <code>jbang app install http@jbangdev</code>. Once you do that you can run it from anywhere using just <code>httpd</code>.</p>
</div>
<div class="paragraph">
<p>In case you already have application called <code>httpd</code> you can use <code>--name</code> to give it a more unique name:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-shell hljs" data-lang="shell">$ jbang app install --name jhttpd httpd@jbangdev
[jbang] Command installed: jhttpd
$ jhttpd
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) from /Users/max/code/personal/jbangdev/jbang.dev ...</code></pre>
</div>
</div>
<div class="paragraph">
<p>Enjoy - and remember you can find <code>httpd@jbangdev</code> and other apps in <a href="https://jbang.dev/appstore">JBang AppStore</a>.</p>
</div>Max Rydahl AndersenIn March JEP: 408: Simple Web Server was announced. One of JEP 408’s goals is to make an easy to use web server available with Java using java -m jdk.httpserver.JBang Avatar2020-12-01T00:00:00+00:002020-12-01T00:00:00+00:00https://jbang.dev/learn/jbang-avatar<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>It is getting very close to the first anniversary of first commit of JBang.</p>
</div>
<div class="paragraph">
<p>To celebrate I looked around to see what we could do and was reminded about good old <a href="https://gource.io">Gource</a>.</p>
</div>
<div class="paragraph">
<p>With Gource you can render the history of a git repository and get a nice animated video, including flying icons for each author. Trouble is that by default they are just faceless heads - lets get some faces to all those names.</p>
</div>
<div class="paragraph">
<p>I found a <a href="https://gist.github.com/pmdgithub/706587">perl script</a> that took all committer emails and located their gravatar image; but it was Perl…​so lets make that java instead and use JBang.</p>
</div>
<div class="paragraph">
<p>The full example is available <a href="https://github.com/jbangdev/jbang/blob/HEAD/examples/grabavatars.java">here</a>, below I’ll walk through the various interesting parts.</p>
</div>
<div class="paragraph">
<p>If you want to just directly run it do this:</p>
</div>
<div class="paragraph">
<p><code>jbang <a href="https://github.com/jbangdev/jbang/blob/HEAD/examples/grabavatars.java" class="bare">https://github.com/jbangdev/jbang/blob/HEAD/examples/grabavatars.java</a></code></p>
</div>
<div class="paragraph">
<p>To begin with you just get started with <code>jbang init -t cli grab-avatar</code>.</p>
</div>
<div class="paragraph">
<p>This will create a file named <code>grabavatar.java</code> with some pre-seeded code that does a Hello World! style app using picocli plus it will mark the file as executable.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="setup-dependencies-and-main-class">Setup dependencies and main class</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Then in top we are going to add a few dependencies:</p>
</div>
<div class="listingblock">
<div class="title">Dependencies</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS info.picocli:picocli:4.5.0
//DEPS org.zeroturnaround:zt-exec:1.12
//DEPS commons-codec:commons-codec:1.15
//DEPS org.slf4j:slf4j-nop:1.7.30 </code></pre>
</div>
</div>
<div class="paragraph">
<p>The first line is the magic "shebang" line that bash and other shells will interpret but for java it is just a comment. This is what allows you to run the script directly using <code>./grab-avatar</code></p>
</div>
<div class="paragraph">
<p>The dependencies used are as follows:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Picocli for annotation based command line parsing and help generation.</p>
</li>
<li>
<p><code>zt-exec</code> is a nice library to execute processes in a nice fluent way.</p>
</li>
<li>
<p><code>commons-coded</code> just because default Java don’t have a one-liner for MD5 hash generation.</p>
</li>
<li>
<p>No Operation slf4j to avoid the default noise slf4j generates.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>When you run <code>./grabavatars.java</code> or <code>jbang grabavatars.java</code> these starting lines with <code>//DEPS</code> in them will be parsed and JBang fetches the dependencies to use during compilation and execution of your script.</p>
</div>
<div class="paragraph">
<p>The next is the class declaration which is mainly just annotations to define the main picocli command.</p>
</div>
<div class="listingblock">
<div class="title">class declaration</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">@Command(name = "GrabAvatars", mixinStandardHelpOptions = true, version = "GrabAvatars 0.1",
description = "GrabAvatars made with jbang")
class grabavatars implements Callable<Integer> {</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="iteration-over-execution">Iteration over execution</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Then the meat of the code is to run <code>git log --pretty=format:%ae|%an"</code> which will return a line for every commit with email and author, like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">max@xam.dk|Max Rydahl Andersen</code></pre>
</div>
</div>
<div class="paragraph">
<p>To do this I use <code>zt-exec</code> which has this great "one-liner" to run the process and for every line output let me process it.</p>
</div>
<div class="listingblock">
<div class="title">processing command</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> new ProcessExecutor().command("git", "log", "--pretty=format:%ae|%an")
.redirectOutput(new LogOutputStream() {
@Override
protected void processLine(String line) {
String[] data = line.split("\\|");
String email = data[0].toLowerCase();
String author = data[1];</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="md5-and-download">MD5 and Download</h2>
<div class="sectionbody">
<div class="paragraph">
<p>And finally for every identified email and author - generates MD5 and download the url.</p>
</div>
<div class="listingblock">
<div class="title">processing command</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> URL grav_url = new URL("http://www.gravatar.com/avatar/"
+ DigestUtils.md5Hex(email)
+ "?d=404&size=" + size);
try(InputStream in = grav_url.openStream()) {
Files.copy(in, authorImageFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="all-together-now">All together now</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Now to run this when I have it locally is just: <code>./grab-avatars</code> in root of a git repository.</p>
</div>
<div class="paragraph">
<p>But you can also run this directly from a url using:</p>
</div>
<div class="paragraph">
<p><code>jbang <a href="https://github.com/jbangdev/jbang/blob/HEAD/examples/grab-avatars" class="bare">https://github.com/jbangdev/jbang/blob/HEAD/examples/grab-avatars</a></code></p>
</div>
<div class="paragraph">
<p>And then then you can go full out and render with gource - notice the <code>--user-image-dir .git/avatar</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-shell hljs" data-lang="shell">gource --title JBang --stop-at-end --user-image-dir .git/avatar --seconds-per-day 0.05 --auto-skip-seconds 1 -1280x720 --hide filenames -o - | ffmpeg -y -r 60 -f image2pipe -vcodec ppm -i - -vcodec libx264 -preset ultrafast -pix_fmt yuv420p -crf 1 -threads 0 -bf 0 gource.mp4</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then you get a video which with a little bit of magic of video editing that looks something like this:</p>
</div>
<div class="videoblock">
<div class="content">
<iframe width="640" height="360" src="https://www.youtube.com/embed/da0CuVbvWLg?rel=0" frameborder="0" allowfullscreen></iframe>
</div>
</div>
<div class="paragraph">
<p>And that is about it - showed how to get started with jbang to port an existing perl script to java using a few dependencies.</p>
</div>
<div class="paragraph">
<p>See you next time!</p>
</div>
</div>
</div>Max Rydahl Andersen…​all just to gource JBang!Beyond Hello World!2020-05-28T00:00:00+00:002020-05-28T00:00:00+00:00https://jbang.dev/learn/beyondhello<div class="paragraph">
<p>A simple script you can run with <code>jbang</code> is "Hello World" using jshell (<code>.jsh</code>).</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java"> System.out.println("Hello " + ((args.length>0)?args[0]:"jbang"));</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can run the above by putting it in a file named: <code>hello.jsh</code> and run <code>jbang hello.jsh</code>.</p>
</div>
<div class="paragraph">
<p>To expand on this we will make a Java file (<code>.java</code>) which uses an external dependency to make the text a bit more fancy.</p>
</div>
<div class="paragraph">
<p>In this case we’ll use a library called <code>jfiglet</code>.</p>
</div>
<div class="paragraph">
<p>We use <code>//DEPS com.github.lalyos:jfiglet:0.0.8</code> to declare this script should run using the dependency with group id: <code>com.github.lalyos</code>, artifact id: <code>jfiglet</code> and with the version <code>0.0.8</code>.</p>
</div>
<div class="paragraph">
<p>These are called "artifacts coordinates" or "maven coordinates" as the system originates from the Maven build system; but is today used in almost all Java projects. You can use sites like <a href="https://mvnrepository.com" class="bare">https://mvnrepository.com</a> to locate the coordinates of projects, and otherwise find them on the website or source repository of the project them self.</p>
</div>
<div class="paragraph">
<p>Below is a repl.it instance preconfigured with <code>jbang</code> ready to run <code>hello.java</code> using the <code>figlet</code> dependency.</p>
</div>
<div class="paragraph">
<p>Try and press the Run button to see how it works and then try edit the code to see how it pick up the changes between each run.</p>
</div>
<iframe height="400px" width="100%" src="https://repl.it/@maxandersen/jbang-replit-demo?lite=true#hello.java" scrolling="no" frameborder="no" allowtransparency="true" allowfullscreen="true" sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals"></iframe>Max Rydahl AndersenSee the basics of jbang with a bit more than just Hello World!