How would I remake a Batch File into a Shell Script - java

I'm using Sublime Text 2, and I want to be able to compile and run Java Files with one button.
When running Windows, the Batch file Required is:
#ECHO OFF
cd %~dp1
javac %~nx1
java %~n1
I'm wondering what that would look like in a Shell Script, cause I don't know much about Shell Scripts...
I'm using the Open JDK and JRE in case it matters.
Thanks for the help,
Kelan

The bash equivalent to that script would be something like:
#!/bin/bash
cd "$(dirname "$1")"
javac "$(basename "$1")"
java "$(basename "$1" ".${1##*.}")"

A shell script would STILL require running a batch file to start it. For example, you could write a Ant task that could do what you are asking, or perhaps a Beanshell script. But, you still wont be able to avoid making a batch file that launches it. The batch file that you are using now is as close as you'll get to a single click solution. Not even a PowerShell script would give you better convenience.

Related

How to run jlink-generated Java runtime image without CMD window?

I've created Java runtime image for a simple OpenJFX application. In order to run this app, jlink auto-generated two lauch scripts under %image_path%/bin directory. This how it looks like (the one for Windows):
#echo off
set JLINK_VM_OPTIONS=
set DIR=%~dp0
"%DIR%\java" %JLINK_VM_OPTIONS% -m app/com.package.Launcher %*
Obviously, when I run this batch file it opens new shell window, which is not what I want to. I've tried all common approaches: use javaw instead of java, run script via start command etc. Nothing works.
Is it possible to avoid shell window or somehow create native launcher?
Ok, I've figured out it's not posiible to eliminite shell window completely. In the best scenario it's just flickers for ~1sec. This is how it can be achieved:
#echo off
set JLINK_VM_OPTIONS=
set DIR=%~dp0
start "" "%DIR%\javaw" %JLINK_VM_OPTIONS% -m app/com.package.Launcher %* && exit 0
There is a feature request about native laucher implementation but it's not discussed actively.
Nonetheless I've solved the problem. There is "Batch to EXE Converter" tool. It can generate executable (basically the same batch file) which can run your app silently.
This looks to be possible using vbscript. If you put the following script into a .vbs file next to the launcher.bat file (or whatever the name of the batch file is):
CreateObject("Wscript.Shell").Run CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName) & "\launcher.bat " & WScript.Arguments(0) & " > " & CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName) & "\launch-log.log", 0, False
This runs the batch file in the same directory, and also redirects stdout to a log file.
What you´d like to achieve is very well possible. It is actually even quite easy and I use this every day. There already is an early access build of jpackage available here: http://jdk.java.net/jpackage/ Creating executables works already
nicely (I use it on Mac and Windows). Only creating installers is still a bit problematic.
It's very easy to run a bat file without showing the cmd window.
you just need to create VBS file to run bat file with the following cmd
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & ".\bin\launcher.bat" & Chr(34), 0
Set WshShell = Nothing
Save cmd in the file out of the bin folder with any name like
Launcher.vbs.

Shell script that sets LD_LIBRARY_PATH=`pwd` does not work from Java

shell script file directory: /some/location/myShellScript.sh
Properties-Type: shell script (application/x-shellscript)
EDIT
content of shell script:
#!/bin/bash
export LD_LIBRARY_PATH=`pwd`
echo `pwd`
./someExecutable ../input/cfg/test1.ini
The test1.ini is generated one step before in the java code,
it provides settings for some testing, which is done in the background. Then the shell script ends up with the file I need for further processing.
/EDIT
When I am running this shell script on linux terminal in its own directory just with "./myShellScript.sh" it works perfectly fine...
The part my shell script shall be executed:
//Do something before
//Shell scripts creates a file
String cmd = /some/location/myShellScript.sh;
ProcessBuilder pb = new ProcessBuilder(cmd);
Process process = pb.start();
int exitValue = process.waitFor();
System.out.println(exitValue);
//Afterwards I am processing the generated file
When running my java program as an executable .jar file, this process gets not executed and the exitValue is 127, but I don't know why...
I tried many things like:
using the Runtime to exec
adding #!/bin/bash or #!/bin/sh on top of the shell script
adding a "sh" parameter to the process command in form of String[]
In my execution directory, I changed the permission with chmod 755 -R * recursively so every associated library used by the shell script is indeed available (also due to the fact, that I can just execute it on the terminal).
I really tried to find a proper answer on the internet but I wasn't successful.
And no, I cannot just do everything in java, the shell script is mandatory and cannot be replaced in this case.
Thanks in advance for helpful suggestions!
The script you are executing is highly sensitive to its working directory. It uses pwd to set the LD_LIBRARY_PATH and it attempts to execute another program via a relative path to that program, providing a relative path as a command-line argument, as well.
The working directory for an execution of the script has no essential relationship with the directory in which the script resides -- it completely depends on how and in what context the script is launched. For example, you report that the script works as you expect "When I am running this shell script [...] in its own directory." But when you run the script from Java you very likely are not running it with its own directory as the working directory, and that will strongly affect this script's behavior.
One solution would be to hardcode the script's installation path into the script itself, and to express all your paths relative to that:
#!/bin/bash
installation_dir=/path/to/the/script/dir
export LD_LIBRARY_PATH=$installation_dir
"$installation_dir"/someExecutable "$installation_dir"/../input/cfg/test1.ini
It's a bit kludgy to hardcode the path, though. You could further improve it by having the script identify its own directory at runtime:
#!/bin/bash
installation_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
export LD_LIBRARY_PATH=$installation_dir
"$installation_dir"/someExecutable "$installation_dir"/../input/cfg/test1.ini
That's obviously Bash-specific, but you were using bash anyway. Alternatively, if the executable your script launches is also sensitive to its working directory, then perhaps you just want the script to change directory (which will be effective only for the script and processes downstream from it, not for its parent process):
#!/bin/bash
cd "$( dirname "${BASH_SOURCE[0]}" )"
export LD_LIBRARY_PATH=`pwd`
./someExecutable ../input/cfg/test1.ini
The 127 exit status means that a command used in the script is not found.
EDIT
Debug the script, when bash is used, add the line below on the second line:
exec > /tmp/debug.txt 2>&1 ; set -x
After the next attempt, analyze the traces generated into the /tmp/debug.txt file.
OLD INTRO
(the script content was not yet provided)
The Java program which executes the myShellScript.sh script has probably not the same PATH environment variable than the one which is set in your environment when you execute the script manually from a terminal.

Java JAR file does not execute in startup script in Ubuntu 14.04

The following process normally works for my startup scripts. However, when I introduce a command to execute a JAR file, it does not work. This script works while I am logged in. However, it does not work as a startup script.
In /etc/init.d I create a bash script (test.sh) with the following contents:
#!/bin/bash
pw=$(curl http://169.254.169.254/latest/meta-data/instance-id)
pwh=$(/usr/bin/java -jar PWH.jar $pw &)
echo $pwh > test.txt
Make script executable
In /etc/rc.local, I add the following line:
sh /etc/init.d/test.sh
Notes:
I make a reference to the script in /etc/rc.local, because this script needs to run last after all services have started.
Please do not ask me to change the process (i.e., create script in /etc/init.d/ and reference it from /etc/rc.local), because it works for my other startup scripts.
I have tried adding nohup in front of java command, and it still did not work.
Thanks
As written, there is insufficient information to say what is going wrong. There are too many possibilities to enumerate.
Try running those commands one at a time in an interactive shell. The java command is probably writing something to standard error, and that will give you some clues.

OSX How do I have a Shell script change directory to the one the script is in?

I'm using Apple's automator to create a Shell Script. I can get it to run if I change directory specifically to where the jar file is. But what if I want to change to directory to wherever the Shell script happens to be running?
Right now I have the following, which works:
cd desktop/CommonDenom/
java -XstartOnFirstThread -jar CommonDenom.jar
I know there's a way to target whatever directory the Shell script is launched from, but I can't seem to get anything to work. Please be specific with instructions as I havent been using Automator very long. Unless someone can specify how ot writ ethe script without Automator. Thanks in advance.
A standard idiom for this in shell scripts is dirname $0. The $0 variable is the path to the script that was executed, and the dirname command takes a path and strips off the last component to leave the path to the containing directory
cd "`dirname $0`"
Just wanted to weigh in here. I've seen some people with this problem. If you are JUST on OSX and making your own scripts. This will do the trick :) kind of a hack, but works like a charm.
#! /bin/bash
sudo /Applications/XAMPP/xamppfiles/xampp startapache
open /Applications/XAMPP/htdocs
#!/bin/bash
DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
cd "${DIR}"
...the rest of your script...
Credits to Ian C. on AskDifferent: https://apple.stackexchange.com/a/179064
I am not sure you mean "you want to change directory to wherever the script is run from" because you will be in the directory the script is run from when you start anyway, so there will be no need to change directory there. I think you mean you want the script to stay wherever it starts, yet still be able to find the jar file.
In which case, you probably jus need the following without any changing directory:
java -XstartOnFirstThread -jar ~/Desktop/CommonDemon/CommonDemon.jar

Can you run a Java program in Linux using the name only, without the "java" command?

If I am writing HelloWorld, is there a way I can run the program from any directory by just typing HelloWorld? Sort of the same way once you set up Ant, you can just run Ant from any directory?
Just for some details, we are creating a CLI based toolkit for a customer, and just curious if we can compile it, install it, and just have them run it using the toolkit name.
You can always create a shell script, call it HelloWorld and make it run java with your JAR.
You'll then need to chmod the script to make it executable, and place it somewhere in your $PATH.
The script would like something like:
#!/bin/bash
cd /path/to/helloworld
java -jar HelloWorld.jar "$#"
or
#!/bin/bash
java -jar /path/to/helloworld/HelloWorld.jar "$#"
depending on your exact requirements.
Common solution for your problem is to create a separate launcher application, which is non-java application that runs your Java program. Launcher can be written in some compilable language such as C/C++ and compiled into native executable. Also it can be written in some interpreted language such as Unix shell, perl, python etc and made executable by adding #!/path/to/interpreter line at the beginning of launcher file and setting executable flag on it. Also there are several utilities that can generate launcher for your program such as launch4j or jsmooth.
On Linux (specifically), you could use the /proc filesystem (see proc(5) man page) and its binfmt_misc (actually the /proc/sys/fs/binfmt_misc/register pseudo-file and other pseudofiles under /proc/sys/fs/binfmt_misc/) to register java as the handler for .class or .jar files. Read the Documentation/binfmt_misc.txt file in the kernel source for gory details.
Then any executable .jar file would be interpreted by java (or jexec)
I'm not sure it is worth the effort. I find that wrapping your Java program in some shell script is much more easy (and more portable, because few Linux systems actually use binfmt_misc, and your customer may need some sysadmin skills to enable it).

Categories