I want to run a jar script from within a Java program. The command is tested to run without problems if pasted sloley to the Windows cmd.
However, my Java script stucks at p.waitFor().
public class MyClass{
public static void main(String[] args) {
try {
// create a new process
System.out.println("Creating Process...");
Process p = Runtime.getRuntime().exec("U:\\locallib\\jdk-8u65-windows-x64\\tools\\bin\\java.exe -Xmx4g -jar U:\\path\\to\\my.jar arg1 arg2");
System.out.println("Process is running...");
p.waitFor();
System.out.println("Process is terminated...");
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
Ouput:
Creating Process...
Process is running...
...and nothing else.
Related
I have a code piece about killing the chrome drivers on Selenium/Java:
Runtime.getRuntime().exec("taskkill /f /im chromedriver.exe");
When I run this code piece in Eclipse, it works and kills all drivers but when I create jar file from same project and run this jar, exec command does not working and does not kill drivers.
public class CommonKillAllDrivers {
public void killAllDrivers() throws InterruptedException {
try{
Runtime.getRuntime().exec("taskkill /f /im chromedriver.exe");
}
catch (Exception e) {
System.out.println("error in catch");
}
}
}
This code is called from afterTest method:
#AfterTest(alwaysRun = true)
public void killDrivers() throws InterruptedException {
CommonKillAllDrivers killDrivers = new CommonKillAllDrivers();
killDrivers.killAllDrivers();
}
So I want this: all opened drivers while created with tests are killed at the end. ( I am observing these chromedriver.exe in Task Manager)
But when I run jar file from Powershell:
java -jar "C:\Users\mervey\eclipse-workspace\tvb2b\target\b2b-selenium-jar-with-dependencies.jar" "C:\Users\mervey\eclipse-workspace\tvb2b\testng-suite.xml"
...this line of code is not working and not kill drivers.
I want to check for some condition after every 4 minutes. If specified condition occurred I want to close firefox and restart it using batch script in windows 7. I created runnable jar of following code and run that with javaw but it is not working even if that condition occur. Same code worked in eclipse.
class WebAlert {
public static void main(String[] args) {
WebAlert w = new WebAlert();
while(true) {
try {
Thread.sleep(240000);
w.sendPost();
}catch(Exception e) {
System.out.println(e);
}
}
}
private void sendPost() {
if(somecondition){
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "restartFirefox.bat");
File dir = new File("C:\\");
pb.directory(dir);
pb.start();
}
}
}
Please set the directory to the batchfile path and use ProcessBuilder to pass the necessary argument.
File dir = new File("C:\\path_to_the_batchfile\\");
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", "Start", "restartFirefox.bat");
pb.directory(dir);
pb.start();
I am now executing java a java program like this:
package com.test;
public class Test {
public static void main(String[] args){
execute();
}
public static String execute(){
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "a";
}
}
I want to execute the Test.execute() method in linux shell script, wait until the method return and get return code . but the return of main() method is void , so what Can I do the get a return code or return msg from it ?
Any suggestions?
I find a solution:
package com.test;
public class Test {
public static void main(String[] args){
execute();
}
public static String execute(){
try {
System.out.println("sleeping");;
Thread.sleep(5000);
Runtime.getRuntime().exit(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "a";
}
}
And then my shell:
#!/bin/bash
java -cp test.jar com.test.Test
echo "The return code of the java application is $?"
I can get the value n which is in Runtime.getRuntime().exit(n);
First change the signature of main method in your code example:
public static void main() to public static void main(String[] args)
Then instead of just calling the execute method from main, try to print the result using System.out.println :
System.out.println(execute());
and then in linux shell you can use following to get the return values:
> set out = `java com.test.Test`
> echo $out
The shell script would have to call java com.test.Test. And this will call the main method which inturn is currently calling execute.
From a shell script you would have to start a JVM and a JVM always starts with a Main method.
As for the return code, you can access it using the $? shell variable.
So basically your shell script would be something like this:
#!/bin/bash
java -cp . com.test.Test
echo "The return code of the java application is $?"
Also you need to specify the classpath where all you relevant classes reside. In the above example I am putting in the current dir as the classpath.
The JVM will terminate with a exit code of 0 on completion of all non-daemon threads. If you want to return a specific exit code in case of an error you can use System.exit(<codehere>). Please note that calling System.exit() will cause the JVM to shutdown even if there are other non-daemon threads that are running.
Edit:
Added "-cp ." to the command based on the comments.
Added some exit code details
I have a java program:
public class ProcessMain {
public static final void main(String[] args) throws Exception {
Scanner keyboard = new Scanner(System.in);
boolean exit = false;
do
{ if(keyboard.hasNext()){
String input = keyboard.next();
System.out.println(input);
if( "abort".equals(input)){
ABORT();
exit = true;
}
}else{
System.out.println("Nothing");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}while (!exit);
}
private static void ABORT(){
System.out.println("ABORT!!!!");
}
}
In Linux, a script:
rm testfifo
mkfifo testfifo
cat > testfifo &
echo $!
java -cp "Test.jar" com.example.ProcessMain < testfifo
Terminal A runs the script, "Nothing" can be printed every 5 seconds.
And then Terminal B execute echo "abort" >testfifo, but the program cannot display ABORT, it still displays Nothing every 5 seconds.
Please help!!
If you only need an external trigger to stop current processing. You might create a semaphore file and stop as soon it is created by another process.
See the following snippet.
// it will check for the file in the current directory
File semaphore = new File("abort.semaphore");
semaphore.deleteOnExit();
System.out.println("run until exist: " + semaphore);
while (!semaphore.exists()) {
System.out.println("Nothing");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("ABORT!!!!");
As long the file abort.semaphore does not exist, the program will print to the console and wait five seconds.
edit On Linux you might use a signal handler and send an SIGABRT to the running process.
the following snippet uses an internal proprietary API
import sun.misc.Signal;
import sun.misc.SignalHandler;
public class SigAbrt {
private static volatile boolean abort = false;
public static void main(String[] args) throws Exception {
Signal.handle(new Signal("ABRT"), new SignalHandler () {
public void handle(Signal sig) {
System.out.println("got a SIGABRT");
abort = true;
}
});
for(int i=0; i<100; i++) {
Thread.sleep(1000);
System.out.print('.');
if (abort) {
System.out.println("ABORT");
break;
}
}
}
}
run it
session one
java SigAbrt
session two
// first find the PID of SigAbrt
jps
example output of session two
2323 Jps
4242 SigAbrt
now send a SIGABRT to the SigAbrt process
kill -s SIGABRT 4242
example output of session one
...........got a SIGABRT
.ABORT
Program not printing on console might be because of your testfifo file is empty.
Try this:
printf "Hello\nMy\nFriend\nabort" > testfifo
java -cp "Test.jar" com.example.ProcessMain < testfifo
It will work.
Alright, I have a shutdown hook that makes sure I close my connection nicely whenever I close. What I need to do now is open another program (terminal emulator) then close mine while leaving the terminal emulator open. I am able to open the emulator but the java program doesn't close until the emulator closes. How can I run something and close my program out?
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
if (connection != null) {
try {
connection.close();
System.out.println("Connection Closed");
try {
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "C:\\MVbase\\mvterm.lnk");
Process p = pb.start();
System.exit(0);
} catch (IOException e) {
System.out.println(e);
}
} catch (MVException e) {
System.out.println(e.getMessage());
}
}
}
}, "Shutdown-thread"));
The easiest way to do it is to make a shell script or batch file that runs the program then shuts it down and starts the terminal emulator.
#!/bin/sh
cd C:/location/of/program
javac program.java
java program
kill program
cd C:/location/of/terminalemulator
run terminalemulator
Save this as a batch file and it should do it all from the command line.