how to start new independent process from java [duplicate] - java

I'm writing a plugin in order to restart a server application on Linux (though I'm testing on OSX). The way I'm doing this is using a shell script which commands the application to stop, and then oversees the death of the process, safely starting a new one when the time comes.
My script works when I execute it manually from the command line. However, when I execute it from within the application, the shell process is killed along with the application.
I've tried two different methods of running the process from Java:
String scriptArgs[] = {"sh", "restart.sh", "&"};
try {
Runtime.getRuntime().exec(scriptArgs);
} catch (IOException e) {
e.printStackTrace();
}
and
ProcessBuilder processBuilder = new ProcessBuilder("sh", "restart.sh");
try {
processBuilder.directory(new File(System.getProperty("user.dir")));
processBuilder.redirectErrorStream(false);
processBuilder.start();
} catch (IOException e) {
e.printStackTrace();
}
Both of these methods gave the same result: the script was called, it successfully shut down the application, and then it died before it could continue. Is there any method to start a completely independent process from Java?

When you run a process from java you are creating a shell instance which then runs the process. The shell will only exit once this process has finished even if it is being run in the background &
To run a process in headless mode you need to use the nohup command. For details, see here.
A usage could look like this:
ProcessBuilder processBuilder = new ProcessBuilder("nohup", "sh", "restart.sh");
try {
processBuilder.directory(new File(System.getProperty("user.dir")));
processBuilder.redirectErrorStream(false);
processBuilder.start();
} catch (IOException e) {
e.printStackTrace();
}

Related

Linux mail command removes text after space in subject when run from Java

I have to send email from a Linux server through a Java program. When I run the command on SSH Secure Shell, everything is fine. But when I call the same command from Java, the subject after space is removed.
Script is as follows:
mail -s "This is a test subject" "receiver#example.com"
When I execute the above script through Java, the subject is truncated to "This (Double quotes followed by the first word)
Java code for running the above script is:
Runtime.getRuntime().exec(emailCommand);
*Here emailCommand refers to the shell script.
Did a lot of googling but did not find a solution.
After the discussion with I am providing you a solution like below:-
String[] command ={"/path/to/your/shellscript.sh", "shellscriptcommandlineparameter"};
ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectOutput(new File("/tmp/output.txt"));
try {
Process p = pb.start();
p.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}catch (Exception e1) {
e1.printStackTrace();
}
}
Try with this updated java code and you can see the output from your shell script in output.txt file.

Trying to show the execution of bat file in eclipse console [duplicate]

In my Java application, I want to run a batch file that calls "scons -Q implicit-deps-changed build\file_load_type export\file_load_type"
It seems that I can't even get my batch file to execute. I'm out of ideas.
This is what I have in Java:
Runtime.
getRuntime().
exec("build.bat", null, new File("."));
Previously, I had a Python Sconscript file that I wanted to run but since that didn't work I decided I would call the script via a batch file but that method has not been successful as of yet.
Batch files are not an executable. They need an application to run them (i.e. cmd).
On UNIX, the script file has shebang (#!) at the start of a file to specify the program that executes it. Double-clicking in Windows is performed by Windows Explorer. CreateProcess does not know anything about that.
Runtime.
getRuntime().
exec("cmd /c start \"\" build.bat");
Note: With the start \"\" command, a separate command window will be opened with a blank title and any output from the batch file will be displayed there. It should also work with just `cmd /c build.bat", in which case the output can be read from the sub-process in Java if desired.
Sometimes the thread execution process time is higher than JVM thread waiting process time, it use to happen when the process you're invoking takes some time to be processed, use the waitFor() command as follows:
try{
Process p = Runtime.getRuntime().exec("file location here, don't forget using / instead of \\ to make it interoperable");
p.waitFor();
}catch( IOException ex ){
//Validate the case the file can't be accesed (not enought permissions)
}catch( InterruptedException ex ){
//Validate the case the process is being stopped by some external situation
}
This way the JVM will stop until the process you're invoking is done before it continue with the thread execution stack.
Runtime runtime = Runtime.getRuntime();
try {
Process p1 = runtime.exec("cmd /c start D:\\temp\\a.bat");
InputStream is = p1.getInputStream();
int i = 0;
while( (i = is.read() ) != -1) {
System.out.print((char)i);
}
} catch(IOException ioException) {
System.out.println(ioException.getMessage() );
}
ProcessBuilder is the Java 5/6 way to run external processes.
To run batch files using java if that's you're talking about...
String path="cmd /c start d:\\sample\\sample.bat";
Runtime rn=Runtime.getRuntime();
Process pr=rn.exec(path);`
This should do it.
The executable used to run batch scripts is cmd.exe which uses the /c flag to specify the name of the batch file to run:
Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "build.bat"});
Theoretically you should also be able to run Scons in this manner, though I haven't tested this:
Runtime.getRuntime().exec(new String[]{"scons", "-Q", "implicit-deps-changed", "build\file_load_type", "export\file_load_type"});
EDIT: Amara, you say that this isn't working. The error you listed is the error you'd get when running Java from a Cygwin terminal on a Windows box; is this what you're doing? The problem with that is that Windows and Cygwin have different paths, so the Windows version of Java won't find the scons executable on your Cygwin path. I can explain further if this turns out to be your problem.
Process p = Runtime.getRuntime().exec(
new String[]{"cmd", "/C", "orgreg.bat"},
null,
new File("D://TEST//home//libs//"));
tested with jdk1.5 and jdk1.6
This was working fine for me, hope it helps others too.
to get this i have struggled more days. :(
I had the same issue. However sometimes CMD failed to run my files.
That's why i create a temp.bat on my desktop, next this temp.bat is going to run my file, and next the temp file is going to be deleted.
I know this is a bigger code, however worked for me in 100% when even Runtime.getRuntime().exec() failed.
// creating a string for the Userprofile (either C:\Admin or whatever)
String userprofile = System.getenv("USERPROFILE");
BufferedWriter writer = null;
try {
//create a temporary file
File logFile = new File(userprofile+"\\Desktop\\temp.bat");
writer = new BufferedWriter(new FileWriter(logFile));
// Here comes the lines for the batch file!
// First line is #echo off
// Next line is the directory of our file
// Then we open our file in that directory and exit the cmd
// To seperate each line, please use \r\n
writer.write("cd %ProgramFiles(x86)%\\SOME_FOLDER \r\nstart xyz.bat \r\nexit");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// Close the writer regardless of what happens...
writer.close();
} catch (Exception e) {
}
}
// running our temp.bat file
Runtime rt = Runtime.getRuntime();
try {
Process pr = rt.exec("cmd /c start \"\" \""+userprofile+"\\Desktop\\temp.bat" );
pr.getOutputStream().close();
} catch (IOException ex) {
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
}
// deleting our temp file
File databl = new File(userprofile+"\\Desktop\\temp.bat");
databl.delete();
The following is working fine:
String path="cmd /c start d:\\sample\\sample.bat";
Runtime rn=Runtime.getRuntime();
Process pr=rn.exec(path);
This code will execute two commands.bat that exist in the path C:/folders/folder.
Runtime.getRuntime().exec("cd C:/folders/folder & call commands.bat");
import java.io.IOException;
public class TestBatch {
public static void main(String[] args) {
{
try {
String[] command = {"cmd.exe", "/C", "Start", "C:\\temp\\runtest.bat"};
Process p = Runtime.getRuntime().exec(command);
} catch (IOException ex) {
}
}
}
}
To expand on #Isha's anwser you could just do the following to get the returned output (post-facto not in rea-ltime) of the script that was run:
try {
Process process = Runtime.getRuntime().exec("cmd /c start D:\\temp\\a.bat");
System.out.println(process.getText());
} catch(IOException e) {
e.printStackTrace();
}

Process is not completing even after putting the waitFor function

i am new to this Process Thing in java and i am having a problem with this shell command that i want to run in java.
I have this file with a large set of data in it and i want to convert it using XSL.
The command is working fine if run on cmd.exe but is not working in java code.
I have used the process wait too but still there is no output. Please help.
Thanks
Small fragment of code
String c="java -Xmx1g -jar c:\\temp\\FileConverter.jar xmlTransform title \"Data\" root \"c:\\temp\\\" src \"c:\\temp\\input.xml\" xsl \"converter.xsl\" xsl:MEMBER_CODE \"111\" xsl:MEMBER_NAME \"ABC\" xsl:MEMBER_PASSWORD \"abc\" dst \"c:\\temp\\dummy.xml\" src-error \"c:\\temp\\error\"";
Runtime rt = Runtime.getRuntime();
try {
Process proc = rt.exec(c);
synchronized (proc) {
proc.wait(10000);
}
System.out.println("Done");
}catch (IOException e) {
e.printStackTrace();
}

.jar not executing and showing the System.out.print(); output

My problem is when to call jar file using
Runtime.getRuntime().exec() method, my .jar is not executing and showing its output
Coding is like that
public static void main(String[] args) {
String execJar = "java -jar C:\test.jar";
try {
Process p = Runtime.getRuntime().exec(execJar);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
When I used this "java -jar C:\test.jar" in command prompt, my .jar is not executing thus not showing System.out output.
Does anybody know how I can make this work?
Thanks.
ProcessBuilder pb = new ProcessBuilder("java", "-Xmx1024m", "-Xms1024m",
"-DTOOLS_DIR=C://", "-Daoi=whole",
"-jar", "C://calc.jar");
try {
pb.start();
} catch (IOException ex) {
System.out.print("EEE"+ex);
}
This is easy to follow as it has simple paths so you can try it and let it run easily
When you execute a process from within Java, it will have it's own standard out and standard error streams in that particular process. To access those, you have to get the corresponding streams from the Process object you have created.
p.getOutputStream(); // System.out
p.getErrorStream(); // System.err
Where do you expect the System.out to go ?.
When the process is spawned, the input/output and error streams are opened between the spawning and spawned process. You should consume the input and error (these represent the process output, despite the confusing name), otherwise your spawned process will block, waiting for the streams' contents to be consumed.
See this answer for more info.
ProcessBuilder pb = new ProcessBuilder("java", "-Xmx1024m", "-Xms1024m",
"-DTOOLS_DIR=F://Net Beans Work Space//calc//dist", "-Daoi=whole",
"-jar", "F://Net Beans Work Space//calc//dist//calc.jar");
pb.start();
Use this code it will surely run your jar file what you have to change is the paths in above code please reply it will work for you I will be thankful for you kind reply

How to kill Ant program spawned from within java

Destroying spawned ant process, from windows, does not work. Unix variants this works fine but from windows this does not work. Code snippet is below. While the return code is correct (1) the spawned process continues to execute until done. Only a problem on a windows. Any ideas?
ProcessBuilder build = new ProcessBuilder();
List<String> list = build.command();
list.add("cmd");
list.add("/C");
list.add("ant");
list.add("-f");
list.add("HelloWorld.xml");
try {
Process p = build.start();
Thread.sleep(5000);
p.destroy();
int i = p.waitFor();
System.out.println(i);
} catch (Exception e) {
System.out.println(e);
}
The problem is that Process.destroy doesn't kill the process grandchildren. There is a bug opened for it since 2002.
Anyway, why are you spawning a new prompt with cmd /c start to call Ant? If that is not a requirement just call ant.bat -f HelloWorld.xml.
UPDATE
ant.bat will also spawn children processes. There is a workaround with taskkill that may help.
Problem solved by using a mix of wmic (to grab the windows process list) and taskkill (to force kill the running process).

Categories