7

I have been searching for many similar posts about this but I still can't find my answer. I want to convert a .java program into a Linux executable file, without the .jar extension. How can I do it? I am trying to use Launch4j java wrapper, JWrapper, IzPack, making a .sh, making a .bat, running it using java -jar myFile.jar etc. but none of them worked. Some procedures are complicated and difficult to debug. Is there any straightforward way to convert a .java file or .jar file into a Linux executable file?

I need to pass this program as a Linux executable as a whole into another program that takes this program as an argument.

hiew1
  • 1,394
  • 2
  • 15
  • 23
  • 1
    why you wanna make .sh file for linux only? i guess the beauty of java is cross platform you just need to install JRE and one single jar will run perfectly OK on any OS. – Muhammad Suleman Apr 03 '15 at 10:01
  • I have tried making a .sh file but it doesn't work. The reason is because I have a main program that is fixed and written by someone else and I can only pass in my program as a Linux executable (not a .jar) to it. And I am developing it using Java. – hiew1 Apr 03 '15 at 10:03
  • The easiest way is to dump the contents of the `.jar` into a [here doc](http://tldp.org/LDP/abs/html/here-docs.html) then write the rest of the script to unpack the data into a `.jar` and run it. – Boris the Spider Apr 03 '15 at 10:04
  • No it can't be a .jar. It has to be a Linux executable because I am passing it as an argument to another program. The program only takes Linux executable as an argument. – hiew1 Apr 03 '15 at 10:06
  • 1
    @pythonhiew : i guess you can also run jar using command like, java -jar fileName.jar. why don't you make a bash which run command and up your JAR. – Muhammad Suleman Apr 03 '15 at 10:14
  • 1
    I don't see why .sh script would be any different than "linux executable", it's executable as well. Large portion of linux executables are actually scripts - if that doesn't work then I don't see how any other executable would work either. Also: Launch4j is for creating native windows executables, I don't see how that would help you in Linux environment. – eis Apr 03 '15 at 11:26
  • 1
    Make sure your .sh file is really executable (chmod +x yourfile.sh), maybe that's the problem. If the tool you are passing the shell script to doesn't like the .sh ending, just rename it omitting the .sh ending. – muued Apr 03 '15 at 11:36
  • Hi folks thanks for all your sincere effort to help. I have found the solution and posted my answer below. Pretty useful and valuable after literally hours of searching on the internet and trying multiple different stuff. – hiew1 Apr 03 '15 at 13:19

4 Answers4

17

Let's say that you have a runnable jar named helloworld.jar

Copy the Bash script below to a file named stub.sh

#!/bin/sh
MYSELF=`which "$0" 2>/dev/null`
[ $? -gt 0 -a -f "$0" ] && MYSELF="./$0"
java=java
if test -n "$JAVA_HOME"; then
    java="$JAVA_HOME/bin/java"
fi
java_args=-Xmx1g
exec "$java" $java_args -jar $MYSELF "$@"
exit 1 

Than append the jar file to the saved script and grant the execute permission to the file resulting with the following command:

cat stub.sh helloworld.jar > helloworld.run && chmod +x helloworld.run 

That's all!

Now you can execute the app just typing helloworld.run on your shell terminal.

The script is smart enough to pass any command line parameters to the Java application transparently.

Credits: Paolo Di Tommaso

Source: https://coderwall.com/p/ssuaxa/how-to-make-a-jar-file-linux-executable

Dyorgio
  • 1,114
  • 13
  • 23
  • What is ``$java_args`` ? – Thomas Decaux May 03 '17 at 08:05
  • It could be any JVM arg, like -Xmx, -Xms, etc... Example updated. – Dyorgio May 03 '17 at 14:25
  • 1
    What is the point of this shell wrapper if the user still needs to have JRE installed on his machine. We need something like `pyinstaller` for java – pouya Dec 23 '18 at 15:40
  • Hi @pouya, the point is avoid to need to prefix every call to a java program (JAR file) with "java -jar your.jar", so you can just put your executable script on the system path and call it as any normal command/binary from anywhere. In particular, many domestic users don't understand what is a JAR file, and in my option, they don't need to use a software wrote in Java. – Dyorgio Dec 27 '18 at 11:53
10

I found a solution, which is exactly what I want after hours of searching and trying. It is to use the gcj command in linux.

It works like gcc for C and g++ for C++ which compile C or C++ programs into executables.

First install gcj by using the terminal by typing:

sudo apt-get install gcj-jdk

After that, cd into the directory of where the .jar file is located, let's say the .jar file is myFile.jar, then do:

gcj myFile.jar -o newNameofTheFile --main=theMainClassNameofTheFile

to compile the .jar file. And it should work like an executable by just running it in the command line like this:

./newNameofTheFile
hiew1
  • 1,394
  • 2
  • 15
  • 23
  • 4
    gcj has been considered obsolete for years. – chrylis -cautiouslyoptimistic- Apr 03 '15 at 13:26
  • 1
    Yeah chrylis however it works after all the methods I tried. Like running it with java -jar myFile.jar etc. or using .bat, .sh, all failed. Yet this works successfully. Because I have to pass this compiled program into another program as an argument and the other program does not take any form of argument, namely .jar, .sh, .bat, except after what is compiled by gcj. – hiew1 Apr 03 '15 at 13:30
  • @pythonhiew nice that it worked, but it will not work if you're using modern Java constructs, and doing this is really no good idea if you're interested the least in performance. It's an emergency solution, nothing more. – Marcus Müller Jul 02 '15 at 12:35
  • I haven't tried it myself but for anyone interested, [this](http://stackoverflow.com/questions/3032727/) should interest you (tl;dr: it really is obsolete). – MasterMastic Feb 22 '16 at 14:18
4

Another simple trick to convert a jar to a Linux executable is just putting a shebang before the jar file.

Say we have a hello.jar file.

$ java -jar hello.jar
hello world!

You can create an executable in following steps.

$ echo "#! /usr/bin/env java -jar" > hello
$ cat hello.jar >> hello
$ chmod +x hello

Then, you will be able to execute the hello file directly.

$ ./hello
hello world!
czheo
  • 1,771
  • 2
  • 12
  • 22
  • This just results in `/usr/bin/env: java -jar: No such file or directory` – chrixm Nov 29 '19 at 18:20
  • @chrixm Please make sure you have `/usr/bin/env` working. ref: https://unix.stackexchange.com/questions/257969/why-is-usr-bin-env-bash-not-working-on-my-system – czheo Nov 30 '19 at 19:51
2

What you can do is make a tiny little C-program, that calls the one of the exec functions (see man 3 exec) to the "java" binary, passing "-jar", "xxx.jar" as arguments, see also Forking a new process in C++ and executing a .jar file

Community
  • 1
  • 1
Bram
  • 479
  • 2
  • 10
  • Bram thanks for your answer. I have found an easy solution and I have posted the answer below. – hiew1 Apr 03 '15 at 13:20
  • I upvoted your answer anyway because it makes sense. I haven't tried it but it's quite a good idea. – hiew1 Apr 03 '15 at 13:51