Skip to content

Instantly share code, notes, and snippets.

@joewalnes
Last active December 10, 2023 11:58
Show Gist options
  • Save joewalnes/e200c21288edaa970453ec47b6711254 to your computer and use it in GitHub Desktop.
Save joewalnes/e200c21288edaa970453ec47b6711254 to your computer and use it in GitHub Desktop.
Make a single file Java jar launcher

This is a little trick to turn an executable Java jar.

It works on all unixy like systems including Linux, MacOS, Cygwin, and Windows Linux subsystem.

Step 1 Start with an all-in-one jar (with entry point and all deps within)

$ ls 
hello.jar

$ java -jar hello.jar
Hello from Java

Step 2: Prepend launcher to beginning of jar file

Add a shell script to the header of the jar, rename to anything, and make it executable

$ (echo '#!/bin/sh' && echo 'exec java -jar $0 "$@"' && cat hello.jar) > hello
$ chmod +x hello
$ rm hello.jar

$ ls
hello

Step 3: Deploy a single all-in-one executable launcher

$ ./hello
Hello from Java

This single file can be copied to a server. The only dependency is it expects to find a java JVM in the PATH.

How does it work???

This relies on a little known trick about the Zip format allowing arbitrary data to be prepended/appended around the main zip file.

So:

  • The file looks like a shell script. Executing it will run it
  • The shell script calls exec java -jar [myfilename] [args...] replacing the current process
  • The Java VM loads, loads the same script as a Jar and happily ignores the initial shell script because Zip allows that

Bonus: It also works with Python!

Yep. This makes it much simpler to distribute Python tools without having to worry about pip, virtual-env, or Conda. Just ship a single self-contained executable.

In Python you use .pex files, which like .jar files are just Zips. See PEP-441.

Create a Zip containing all your Python files (and dependencies). Include __main__.py as the entry point. Prepend #!/usr/bin/env python to the Zip, make executable, remove the .zip suffix. This is easy to script, but if you want something out of the box there's an existing tool

@charity1475
Copy link

Can it work if i use it to call .java ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment