I have written a Java application, and I have created an executable Jar file that successfully runs my application with java -jar myJar.jar. I have an executable shell script called launchMyProgram that wraps the launching of this Jar (and offers various flags like --help etc.). My target output directory looks like this:
$ ls /path/to/MyProject/target/
archive-tmp/ classes/ myJar.jar
What is the standard method for me to write an installer for my Unix-only application? I assume that I would be correct to drop the launchMyProgram executable in /usr/local/bin. But where do I put the Jar file? Should I make my own subdirectory somewhere for my program's files? Do I need to copy the classes directory from the above output into the same directory as the Jar? This will run via a Makefile so of course users may override my choices.
Basically, I want a user to be able to run make && make install, and be able to run my application with launchMyProgram, and I want place my files (one jar, a 'classes' folder, and a shell script) in the most typical places possible.
One of the best ways to do it has been reinvented many times but is unfortunately not yet standard.
Since a JAR is a ZIP file which is allowed to have an arbitrary prefix, you can prepend a launcher shell script to your jar, mark it executable, and treat that as a standalone binary.
$ echo '#!/bin/bash' > launchMyProgram
$ echo 'exec java -cp "${0}" com.example.program.Main "${#}"' >> launchMyProgram
$ cat myJar.jar >> launchMyProgram
$ chmod +x ./launchMyProgram
$ ./launchMyProgram
Hello, world!
See Simple & Easy Executable Jars for more details.
You should be able to pack everything in the classes/ folder into your jar and still have things work.
Also, if you want to provide RPMs or DEB packages or something for users, fpm makes that really easy.
Related
So I was wondering in bash is there a way to install a jar file like this:
java -jar /opt/install.*.jar
I will only have one .jar file in the /opt directory with the start of the name called install followed by some versioning e.g install6.5.3.jar.
Is there a way to do this or would i have to do an ls .jar and extract the name that way?
Bash would automatically expand that *, assuming you've not disabled globbing.
For example, if you've got a directory like:
mkdir /tmp/foo
touch /tmp/foo/bar.jar
and you executed
java /tmp/foo/*.jar
then bash would execute:
java /tmp/foo/bar.jar
So you don't have to do anything special.
There was a program that I used that made runnable .jar files.. All the ones I'm finding now are ones that make .exe files.. I remember it also has the option to make the file a .sh script as well. Anyone knows its name? I've been searching for hours with no avail :/
The command line
java -jar file.jar
Will run your jar file if it has a Main-Class defined as explained here.
You can use that command in a shell script.
You can create a runnable jar using NetBeans IDE or Eclipse IDE by just providing the main class to run. Rest of the things it will take automatically. That class must be having a main() method in it. Then you can run that jar file using java -jar yourjarfile.jar
Do you mean actually coding java and then compiling to .jar? If you do try
eclipse code editor
I used eclipse to make minecraft mods. It will work if you want to make .jar programs.
If you want to have a jar that you can execute using the usual syntax ./app.jar (instead of java -jar), here is a post explaining the process: how to create executable jars.
Basically, JAR is a variant of ZIP, which allows random bytes to be pre/appended to the JAR without corrrupting it. This means it is possible to prepend a launcher script at the beginning of the jar to make it "executable".
Here is a simple example of the process:
# Append a basic launcher script to the jar
cat \
<(echo '#!/bin/sh')\
<(echo 'exec java -jar $0 "$#"')\
<(echo 'exit 0')\
original.jar > executable.jar
# Make the new jar executable
chmod +x executable.jar
With this, you can now run ./executable.jar instead of java -jar original.jar. This works on all unix like systems including Linux, MacOS, Cygwin, and Windows Linux subsystem.
I'm having a strange issue trying to run classes from an executable .jar file on Linux that none of the existing question threads I've sorted through seem to be able to resolve. I'll preface this in that I've never had to use Linux before and am only using it in this situation out of necessity, so it's possible I have overlooked something simple that I just didn't know could be causing the problem.
I can launch the classes from my .jar file without any issues on Windows via a .bat file with the following settings:
start "MyServer1" java -classpath ./*;Server.jar infoServer/StartInfoServer
start "MyServer2" java -classpath ./*;Server.jar loginServer/StartLoginServer
start "MyServer3" java -classpath ./*;Server.jar chatServer/start
start "MyServer4" java -classpath ./*;Server.jar gameServer/start
However, when I move to trying to launch these classes from the .jar on Linux, I get a "could not find or load main class" error. My .sh file is set up like this, and is placed in the same directory as my .jar file:
echo Starting Servers
java -cp Server.jar infoServer.StartInfoServer
java -cp Server.jar loginServer.StartLoginServer
java -cp Server.jar chatServer.start
java -cp Server.jar gameServer.start
echo All Done Starting Server
I've used ls from the Terminal to verify the .jar and .sh were being recognized as existing where they should be. (For future note, I'm using the Terminal from inside the directory containing my files.) I've made sure to make use of chmod to be sure both the .jar and the .sh have read/write/execute permissions and used ls -l to verify those permissions were indeed present. I've tried various forms of explicitly defining the classpath, such as using "/home/machine/Desktop/Folder/MyJar.jar", using pwd from the Terminal to ensure I'm getting the filepath correct. I've checked over my Java compatibility. (1.7.0_65 on Linux, 1.8.0_45 on Windows, with the .jar being created in Eclipse using 1.7 Compliance settings.) I can use unzip MyJar.jar from the Terminal and it will properly extract all my class files, allowing me to verify that my .jar isn't corrupted on my Linux machine and that the paths to the classes I'm trying to run are still the same on Linux as they are on Windows.
I do apologize if this is just a problem of inexperience overlooking something, but I can't think of or find any indication of what the problem could possibly be.
EDIT:
I've updated the question with some screenshots related to the problem:
https://gyazo.com/0ae2a2701aae734db21ef7c29200283b - General File Setup.
https://gyazo.com/d735d9cee57b4a92078c4b624d012b8c - Running the Shell via Terminal.
Other notes: jar -tf Server.jar works from the Terminal but not from inside the Shell script, which leads me to believe this may be some kind of visibility or pathing error, but I can't find any reason why that would be the case.
I want to run my java algorithm from bash script. When i run my program from Netbeans i can specify my Working directory from application. So, how can i specify the Working directory from bash script ?
In Bash, you can just cd to the directory you'd like to work from. So, for example, if your app lives in ~/bin/app.jar, you'd have something like the following:
#!/bin/bash
WORKING_DIR=$HOME/lib # whichever directory you want to work from
cd $WORKING_DIR
java -jar ~/bin/app.jar
The trick is using an absolute path to your executable, or in this case, an absolute path to your Jar file.
I am working with pre-commit hook developed in java. Now i need to run it inside pre-commit.
List item
How can i run jar file with dependency?
Do I have to make executable jar file to run from pre-commit?
How to give classpath and parameter to jar file?
Currntly i am ruuning in this way inside pre-commit which is working fine. Now i need to move it to production
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/bin/java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=11111
$JAVA_OPTS -Dfile.encoding=MacRoman
-classpath
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/deploy.jar:
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/dt.jar:
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/javaws.jar:
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/jce.jar:
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/jconsole.jar:
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/management-agent.jar:
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/plugin.jar:
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/ext/sunjce_provider.jar:
/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/ext/sunpkcs11.jar:
/Users/testuser/Documents/Dev/projects/SCS/sc/SCS/SCS/SCSAPI/classes:
/Users/testuser/Documents/Dev/projects/SCS/sc/g3/_lib/hibernate-tools.jar:
/Users/testuser/Documents/Dev/projects/SCS/sc/g3/_lib/dom4j-1.4.jar:
/Users/testuser/Documents/Dev/projects/SCS/sc/g3/_lib/commons-logging.jar:
/Users/testuser/Documents/Dev/projects/SCS/sc/g3/_lib/commons-collections-2.1.1.jar:
/Users/testuser/Documents/Dev/projects/SCS/sc/g3/_lib/mysql-connector-java-5.1.22-bin.jar:
/Users/testuser/Documents/Dev/projects/SCS/sc/g3/_lib/hibernate2.jar:
/Users/testuser/Documents/Dev/projects/SCS/sc/g3/_lib/ehcache-1.1.jar
com.ticoon.scs.SCSMain
pre-commit file -c /Users/testuser/Documents/Dev/projects/SCS/sc/SCS/SCS/config.xml -v -repos $REPOS -trxn $TXN
Do I have to make an executable Jar file?
You don't need to create a runnable Jar, but that is advised because it make things easier.
Basically if you run a Jar file, you have to specify the class containing the main() method:
java -jar myjar.jar x.y.z.Main
If you have a Main-Class: x.y.z.Main attribute defined in your MANIFEST.MF file, you can run the Jar file by simply:
java -jar myjar.jar
How to give classpath to a Jar file?
When you run something with the java -jar ... command, the -classpath ... property is dropped. The reason is security (Jar files can be digitally signed to ensure they weren't modified and it would be so easy to make java load a different dependency Jar file with the same content but with hijacked functionality).
The solution is simple: include the Class-Path: ... attribute too in your MANIFEST.MF file as you do with Main-Class: ....
How to give parameters to a Jar file?
As you would give parameters to a simple Java program (and the manual specifies it):
java -jar myjar.jar arg1 arg2 ... argN
Yehh its working now with single file. thanks #rlegendi
Working copy
REPOS="$1"
TXN="$2"
java -jar /Users/testuser/Documents/SCS/SCS.jar pre-commit file -c /Users/testuser/Documents/SCSAPI/config.xml -repos $REPOS -trxn $TXN