Run bash file from java - java

I want to run bash file from java, i am using play framework.
any idea how to do that??
is this code enough:
new ProcessBuilder("pathToYourShellScript").start();

Possible duplicate of How to run Unix shell script from Java code? (don't have the reputation to put that in a comment, sorry).
In a nutshell - your line of code will work and the shell script will run by just doing that (tested on a SUSE Linux box).
However, if you want to do anything with the output or to know that it has completed, you'll have to add more code to check its state (check out the Process.waitFor() API) or to capture its output in Java (e.g. by capturing Standard out in a BufferedReader) - check Process.getInputStream() API.

Related

Using PHP (may be commandline using shell_exec() function), how can I determine if a Java application/jar file is currently running or not?

I have a PHP application which executes a Java .jar file through shell_exec():
shell_exec("java jar myJarProgram.jar");
I have a need to determine if an instance this java program myJarProgram.jar is already running, because if it is not, then I can start it using the above PHP statement.
How can I do that?
You can use "jps" utility to grep your process with java
jps -mlvV | grep myJarProgram.jar
jps is a good candidate for this, but please note that
To use the jps command-line tool you need to install a JDK.
Otherwise, you can parse the output of another shell_exec call that uses ps with the arguments you want in order to get the running processes: at this point you can check if the process is present.
$search_string = "[j]ava jar myJarProgram.jar";
$running = shell_exec("ps -A -ww | grep '$search_string'");
or similar.
If $running is empty, you can launch the jar.
Another option is to perform everything with a single shell_exec, both with commands concatanation (simple && and ||) or creating a .sh script and shell_executing that.
EDIT:
According to the user comment, the script must work both for Windows and Linux.
You can use the php PHP_OS predefined constant to check if it's Windows or Linux:
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') etc....
If it's Linux, you can use the shell_exec as reported above.
If it's Windows, you can change the shell_exec string using the tasklist Windows command. I don't know it, but there are already dedicated questions and answers like this one.

Get status report from shell script to java code

Can any one tell me how to get status report from shell script to java code.
Use case : I run a shell script from java code and if I get any error in shell script(while running) then I need to send some message from shell script to my java code.
So how I can acheive that.
I'm sure there is a better way, but an easy way to do this is to have the shell script pipe error output to a file, which you then read by the Java application.
I'm assuming you are using a ProcessBuilder launch your shell script.
Once you build the process you can use getInputStream() which will give you the output stream from the Shell Script, then just copy the stream to where you want to go.
There also is a redirectOutput but I have limited experiences using it. I'm assuming it does what I'm describing above.
You can use something like this:
Process proc = Runtime.getRuntime().exec("ls -la")
// To get the error code (0=success)
int outCode = proc.exitValue()
If you need to send something from the script to the application executing it, you may be able to do that writing to stdErr in the script and using proc.getErrorStream in your java program.

Redirecting INTO a Java program?

In a project, I'm trying to set up an automated build system for Apache Karaf (there are several commands I need to run in Karaf to set up a working environment on a fresh install). Karaf contains a batch/script file that sets several parameters, and then calls the actual Java program. Essentially, I'd like to be able to do something like:
java MyProgramClass.class < commandTextFile.txt
But when I try this it doesn't do anything. My goal is to simply copy the karaf.bat file, modify it slightly (as below) to make a "karaf-install.bat" that I can just run. The part I've modified of karaf.bat is below, and all I've done is add < "C:\commandFile.txt at the end (the following is all on one line, broken for readability):
"%JAVA%" %JAVA_OPTS% %OPTS% -classpath "%CLASSPATH%"
-Djava.endorsed.dirs="%JAVA_HOME%\jre\lib\endorsed;%JAVA_HOME%\lib\endorsed;%KARAF_HOME%\lib\endorsed"
-Djava.ext.dirs="%JAVA_HOME%\jre\lib\ext;%JAVA_HOME%\lib\ext;%KARAF_HOME%\lib\ext"
-Dkaraf.instances="%KARAF_HOME%\instances" -Dkaraf.home="%KARAF_HOME%"
-Dkaraf.base="%KARAF_BASE%" -Dkaraf.data="%KARAF_DATA%"
-Djava.util.logging.config.file="%KARAF_BASE%\etc\java.util.logging.properties"
%KARAF_OPTS% %MAIN% %ARGS% < "C:\commandFile.txt"
However, Karaf shows nothing. It just runs as if I executed it as normal; my commands are not executed. Is there a way to redirect INTO a java program from the console? Am I doing it way wrong?
For what it's worth, this will eventually be done on both Windows and OS X, but I'm focusing on Windows at the moment.
Update: turns out that this seems to work for me on OS X (Karaf struggles (by saying "Command not found: "), but I think it's because it's getting the commands before it's initialized everything), but Windows is still doesn't even get the commands. I'll poke around more.
When piping INTO, you can read it from System.in.
Consider it a Reader, not an InputStream.
I'm just going to write this issue off as Karaf weirdness, seeing as it works on OS X. I was able to work around it by using the client program that comes with Karaf by doing (on OS X in a .sh file):
"$KARAF/bin/client" "karaf_command_here"
or (on Windows in a .bat file)
call "%KARAF%\bin\client.bat" "karaf_command_here"
And instead of having a list of commands to pipe into Karaf, I just made the list of commands a shell/batch script file that would call Karaf's client for each command. Not as pretty as I'd have liked it, but it got the job done.
(Note you need to start Karaf before using the client with start (and close it with stop)).

How can I test input and output of a Java Application?

I have a simple Java console application and would like to test its input / output automatically. The input is always only one line, but the output is sometimes more than one line.
How can I do this? (with a Linux shell / Python / Eclipse / Java)
You could use pipes in Linux. For example, run your problem like this:
java myProgram < input_file > output_file
This will run myProgram and feed input from input_file. All output will be written to a file called output_file.
Now create another file called expected_file which you should handcreate to specify the exact output you expect on some input (specifically, the input you have in input_file).
Then you can use diff to compare the output_file and the expected_file:
diff output_file expected_file
This will output any differences between the two files. If there are no differences, nothing will be returned. Specifically, if something gets returned, your program does not work correctly (or your test is wrong).
The final step is to link all these commands in some scripting language like Ruby (:)) or Bash (:().
This is the most straight-forward way to do this sort of testing. If you need to write more tests, consider using some test frameworks like junit.
In eclipse you can log your console output to a physical file using the Run configuration settings. Run-> Run Configuration-> Select your application->go to common tab-> in 'Standard input and output' section specify physical file path.
You can execute any Unix command using watch command. Watch command will be executed until you terminate it either by CTRL+C or kill the process.
$ watch -n 5 ls
By default watch command uses 2 second interval, you can change it using -n option.
Or you could write a function like this in your .bashrc (from here)
function run() {
number=$1
shift
for i in {1..$number}; do
$#
done
}
And use it like this
run 10 command

Calling java from PHP exec

I am doing the following in PHP:
exec('java -jar "/opt/flex3/lib/mxmlc.jar" +flexlib "/opt/flex3/frameworks" MyAS3App.as -default-size 360 280 -output MyAS3App.swf');
When I run this from the command line, it runs fine and finishes in a second or two.
When I run this command from PHP exec, the java process takes 100% CPU and never returns.
Any ideas?
I have also tried running the above command with '/usr/bin/java -Djava.awt.headless=true'.
I am running Mac OS X 10.5.5, MAMP 1.7, PHP 5.2.5
Turns out it was a bug specific to the PHP stack MAMP (http://www.mamp.info/).
Turns out any invocation of the JVM following fails under MAMP, e.g.:
exec('java -version');
The fix is to prefix the command with
export DYLD_LIBRARY_PATH="";
Also I realized there's no reason to use that method of invoking mxmlc.
So here's the final, working command:
exec('export DYLD_LIBRARY_PATH=""; mxmlc MyAS3App.as -default-size 360 280 -output MyAS3App.swf');
I manage to get this to work togheter with MAMP. The solution was to include the:
export DYLD_LIBRARY_PATH="";
in the exec call:
$argss = "export DYLD_LIBRARY_PATH=\"\"; /usr/bin/java -jar /Applications/yourjarfile.jar";
$resultXML = exec($argss, $output);
Is there a reason why your using the mxmlc jar file to compile your flex application? have you tried using the executable or an ant task, instead?
Maybe the compiling is taking too long so that your PHP script times out?
Exec is always tricky, on any language :-)
Try to:
use background execution (add &
symbol at the end)
use shell_exec instead
specify the full path to
java executable (may be the one
available to PHP is not the one you
need?)
run a simple HelloWorld java
app to see if the problem is in Java or
in mxmlc specifically
It's strange that java takes 100% CPU. I cannot explain it with any common mistake made when using exec()... try to send it a SIGQUIT to dump the threads, then read the dump -- may be you'll figure something out.

Categories