I personally always felt bad about the fact that we have to provide a shell script which runs the executable jar file. It would be nice if we could provide a self contained executable in a single file, right?

I just discovered a trick which works on unix, but it can possibly be adapted on Windows.

– a jar
– a bash script

Let’s start with the jar. Create an HelloWorld.java file:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");

I like to indicate the Main Class in the manifest, so we create a MANIFEST.MF:

$ echo Main-Class: HelloWorld > MANIFEST.MF

now, let’s put the jar together:

$ javac HelloWorld.java
$ jar -cvmf MANIFEST.MF hello.jar HelloWorld.class 

You can try it:

$ java -jar hello.jar 

It should print “Hello World!”. No surprise.

Now, let’s create, once and for all, the bash script “stub.sh”

java -jar $0 $*

Now let’s put together our self-executable java program:

$ cat stub.sh hello.jar > hello.sh
$ chmod +x hello.sh

And now we can run it!

$ ./hello.sh 
Hello World!

Cool uh?

I think, you can create a stub.bat on Windows; possibly you should just replace the first line with “@echo off” and the “$0 $*” with “%0 %1 %2 %3 %4 %5…”. It should work. Don’t ask me to test the Windows version. I’m allergic.

A shorter version of the stub script:

#!/usr/bin/java -jar

For windows, this should translate to stub.bat:

@java -jar %0 %1 %2 %3 %4 %5

For windows, depending on what you use to concatenate files (copy /b should work) make sure there is a newline between the end of the stub.bat and the beginning of the jar file. I didn’t test on Windows, but I’m pretty sure it will work. Let me know, if otherwise.

7 Responses to “Self executing jar files”  

  1. 1 Joeri Sykora

    Thanks for the cool trick. I just tried it on windows 7 and I can confirm that it works as you described.

  2. 2 laurent kubaski

    I’m not following you: first you say that you “always felt bad about the fact that we have to provide a shell script which runs the executable jar file”… and you then describe a solution where you provide a shell script to run a jar file ?

    Did I miss something ? ;-)

    On Windows, we would use a Java wrapper like WinRun4j. In the end, you would end up with an .exe file so that your program can be launched like every Windows binary: no command line to type, no .bat file to execute, just double click !

    That’s the approach taken by Intellij for example

  3. 3 Fernando Cassia


    I want to smack you with a large cluebat. People who insist on packing Java apps with native wrappers are negating the best part about Java: Cross-platform binaries (.jar files).

    And to the author of this post: it’s not a problem of Java if .jar files are not executed automagically, it’s a problem of misconfiguration of the OS.

    On Windows, you doublt-click on a .Jar file and it starts.

    So why not fix Gnome and KDE so that clicking on a .JAR automagically invokes openjdk’s java -jar %appname ?

    People who package their java apps with native wrappers make me lose respect of them fairly quickly. They don’t understand what Java is about…

    Also mandatory should be the use of One-Jar…


  4. 4 Luigi

    Fernando, if your users are fine with ‘java -jar’ or they use superior OSes, good for you. But there is no need to play the taliban of the cross-platform.

    Being cross-platform is just a feature of the language; if you don’t need it, just use the rest.

  5. 5 laurent kubaski

    Fernando: it’s OK to smack me if that makes you feel better, but you will then also need to smack people building software like Intellij or Eclipse or Netbeans… which are all launched using native .exe files on Windows.

    Also, double clicking a .jar file will only launch it if the JRE has been correctly installed and configured. If not: NOTHING happens and the user has no way to know what went wrong.

    Compare this with an .exe wrapper that checks if a JRE is installed and that will display a meaningful error dialog if that’s the case.

  6. 6 Noel

    I just tried this with multiple `.jar` files and the script isn’t able to find `Main`. Is the only solution to combine all the jars into one before `cat`ing them into the uber-script?

    Fernando, FWIW, my use case involves passing the uber-script as a parameter to another executable (ie `protoc`) so everything needs to be treated as one single unit.

  1. 1 Blog bookmarks 04/19/2012 « My Diigo bookmarks

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


April 2012
« Jan   Jul »

Follow me

twitter flickr LinkedIn feed

Subscribe by email

Enter your email address:



Tag Cloud