How to give response to command line using java - java

I am executing command using java code. but once command start running it asking for some user input. I dont know how to provide input using java code. Please help me.
I am using apache org.apache.commons.exec.CommandLine package to run command.
Output after running command using java code :
[java] The ear file could archive up to: 17 MB in size.
[java] Are you sure you want to build it? [y]Ear building was cancelled by the user
Java Code :
try {
CommandLine cmdLine = new CommandLine(command);
for (int i = 0; i < args.size(); i++) {
cmdLine.addArgument(args.get(i));
}
DefaultExecutor exec = new DefaultExecutor();
exec.setWorkingDirectory(new File(dir));
if (timeout > 0) {
ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout);
exec.setWatchdog(watchdog);
}
exitValue = exec.execute(cmdLine);
return exitValue;
} catch (Exception e) {
log.error(e, e);
}

Better to use Runtime.exec(..) that returns a Process object to you.
Process has getOutputStream() method that connected to the normal input of the sub process. A bit trickier to use and detect when your script is done, but gives you more freedom.

Use system.in in java for accepting input values

Related

how can I execute "java" command by java code?

I'm trying to run a multi-agent system using JADE by code.
Usually, I can run the jade system by command line using the following command:
java jade.Boot -gui
It also works well using Netbeans IDE by changing the project properties and pointing the run configuration to the jade.Boot class.
My problem is: I want to run this system by java code... let's say, when a user clicks a button, and as far as I know, this command specified above should work using the following code:
Process p=null;
try {
p = Runtime.getRuntime().exec("java jade.Boot -gui;");
}
catch (IOException ex) {
Logger.getLogger(SimulationCreator.class.getName()).log(Level.SEVERE, null, ex);
}
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
String s;
try {
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
} catch (IOException ex) {
Logger.getLogger(SimulationCreator.class.getName()).log(Level.SEVERE, null, ex);
}
But I'm getting nothing, neither the JADE system is running nor I'm getting any error.
What am I missing ?
P.S.: I'm working on ubuntu 20.0.
P.S.: running other commands by code like "ps -aux" works very well!
Your problem may be a difference between PATH of the current running VM, compared the shell (bash etc) you use and implicit passing of CLASSPATH. Check the location of java which which java in the shell that works and try using in your exec.
Also you won't see all issues when running as you don't access the error stream at same time as the output stream, changing to ProcessBuilder allows easier debugging as you can redirect the out/err streams to a file. But if JADE runs for a long time or produces a lot of output you should consumer STDOUT+ERR in background threads.
Try this in jshell:
String[] cmd = new String[]{"java", "jade.Boot", "-gui"};
ProcessBuilder pb = new ProcessBuilder(cmd);
File fileOut = new File("stdout.log");
File fileErr = new File("stderr.log");
pb.redirectError(fileErr);
pb.redirectOutput(fileOut);
Process p = pb.start();
int rc = p.waitFor();
String stdout = Files.readString(fileOut.toPath());
String stderr = Files.readString(fileErr.toPath());
System.out.println("Exit : "+rc +' '+(rc == 0 ? "OK":"**** ERROR ****"));
System.out.println("STDOUT : "+stdout);
System.out.println("STDERR : "+stderr);

Java Runtime.exec() to run a java program

Here's the situation. Im creating a UI which will allow make using a genetic programming system (ECJ) easier to use.
Currently you need to run a command prompt within the ECJ folder and use the commands similar to this to execute a parameter file.
java ec.Evolve -file ec\app\tutorial5\tutorial5.params
Where the full path of tutorial5 is
C:\Users\Eric\Documents\COSC\ecj\ec\app\tutorial5\tutorial5.params
and the command prompt must be executed from
C:\Users\Eric\Documents\COSC\ecj
My program makes the user select a .params file (which is located in a ecj subdirectory) and then use the Runtime.exec() to execute
java ec.Evolve -file ec\app\tutorial5\tutorial5.params
What i have so far
// Command to be executed
String cmd = "cd " + ecjDirectory;
String cmd2 = "java ec.Evolve -file " + executeDirectory;
System.out.println(cmd);
try {
Process p = Runtime.getRuntime().exec(
new String[]{"cmd.exe", "/c", cmd, cmd2});
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
statusTF.append(r.readLine());
p.waitFor();
} catch (IOException | InterruptedException ex) {
System.out.println("FAILED: " + ex.getMessage());
statusTF.append("Failed\n");
}
Currently it outputs the change directory command but nothing else.
Can this be done?
First, the 'cd' command can't be executed by Runtime.exec() in the first place (see How to use "cd" command using Java runtime?). You should be able to just set the working directory for the process when you call exec (see below).
Second, running 'cmd.exe /c' to execute your process isn't what you want here. You won't be able to get the results of your process running, because that is returned to the command window -- which eats the error and then closes without passing the error along to you.
Your exec command should look more like this:
Process p = Runtime.getRuntime().exec(
command, null, "C:\Users\Eric\Documents\COSC\ecj");
Where 'command' looks like this:
String command = "java ec.Evolve -file ec\app\tutorial5\tutorial5.params"
Edit: For reading error messages, try this:
String error = "";
try (InputStream is = proc.getErrorStream()) {
error = IOUtils.toString(is, "UTF-8");
}
int exit = proc.waitFor();
if (exit != 0) {
System.out.println(error);
} else {
System.out.println("Success!");
}
You can use Java processbuilder:
processBuilder documentation!
you can define the working directory of the process and all other stuff.
Each call to exec() runs in a new environment, this means that the call to cd will work, but will not exist to the next call to exec().
I prefer to use Apache's Commons Exec, it's provides an excellent facade over Java's Runtime.exec() and gives a nice way to specify the working directory. Another very nice thing is they provide utilities to capture standard out and standard err. These can be difficult to properly capture yourself.
Here's a template I use. Note that this sample expects an exit code of 0, your application may be different.
String sJavaPath = "full\path\to\java\executable";
String sTutorialPath = "C:\Users\Eric\Documents\COSC\ecj\ec\app\tutorial5\tutorial5.params";
String sWorkingDir = "C:\Users\Eric\Documents\COSC\ecj";
try (
OutputStream out = new ByteArrayOutputStream();
OutputStream err = new ByteArrayOutputStream();
)
{
// setup watchdog and stream handler
ExecuteWatchdog watchdog = new ExecuteWatchdog(Config.TEN_SECONDS);
PumpStreamHandler streamHandler = new PumpStreamHandler(out, err);
// build the command line
CommandLine cmdLine = new CommandLine(sJavaPath);
cmdLine.addArgument("ec.Evolve");
cmdLine.addArgument("-file");
cmdLine.addArgument(sTutorialPath);
// create the executor and setup the working directory
Executor exec = new DefaultExecutor();
exec.setExitValue(0); // tells Executor we expect a 0 for success
exec.setWatchdog(watchdog);
exec.setStreamHandler(streamHandler);
exec.setWorkingDirectory(sWorkingDir);
// run it
int iExitValue = exec.execute(cmdLine);
String sOutput = out.toString();
String sErrOutput = err.toString();
if (iExitValue == 0)
{
// successful execution
}
else
{
// exit code was not 0
// report the unexpected results...
}
}
catch (IOException ex)
{
// report the exception...
}

How do i run a Linux terminal cmd from a java program [duplicate]

This question already has answers here:
How to run Linux commands in Java?
(9 answers)
Closed 3 years ago.
I am trying to call my rrdtool cmd from a java class, not sure how to go about it.
I have tested my RRDTool cmd from my terminal and it is successful, see below.
rrdtool update mydb.rrd 1385056701:6:5
How do i execute this cmd from a java class?
You can use the below command format to run your Linux command.
Runtime r = Runtime.getRuntime();
Process p = r.exec(yourcmd);
Please go through Running unix command from Java and Unable to run Unix command in Java-Stackoverflow
Hope you get your answers here.
try this
public class ShellTest {
public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {
// Get runtime
java.lang.Runtime rt = java.lang.Runtime.getRuntime();
// Start a new process: UNIX command ls
java.lang.Process p = rt.exec("ls");
// Show exit code of process
System.out.println("Process exited with code = " + rt.exitValue());
}
}
also check here for more details
Try like this(As answered by paxdiablo):
public static void main(String args[]) {
String s;
Process p;
try {
p = Runtime.getRuntime().exec("ls -aF");
BufferedReader br = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((s = br.readLine()) != null)
System.out.println("line: " + s);
p.waitFor();
System.out.println ("exit: " + p.exitValue());
p.destroy();
} catch (Exception e) {}
}
Also check java.lang.Runtime.exec for details.
Executes the specified string command in a separate process.
This is a convenience method. An invocation of the form exec(command)
behaves in exactly the same way as the invocation exec(command, null,
null).
You can use Runtime#exec for this purpose. If you want a Java-like control over the started process, there is a great library called zt-exec that makes handeling processes much easier. The ProcessBuilder is also offering a minor API improvement over Runtime#exec that ships with the Java standard library.
Something you have to take care of is that Java processes come with very little buffer for the in- and output streams what blocks processes once these buffers run full. This happens silently. zt-exec can help you with that.
You can have a look at :
https://github.com/OpenNMS/opennms/blob/master/opennms-rrd/opennms-rrd-rrdtool/opennms-rrdtool-api/src/main/java/org/opennms/netmgt/rrd/rrdtool/JniRrdStrategy.java
for a real life use of rrdtool in java.
Or at
https://code.google.com/p/rrd4j/
For a native version of rrdtool in java.
I runned my rrdtool command in java program as follow:
Process p = null;
try {
ProcessBuilder pb = new ProcessBuilder("/usr/bin/rrdtool","lastupdate", rrdPath);
pb.redirectErrorStream(true);
p = pb.start();
int exitVal = p.waitFor();
if (exitVal == 0)
System.out.println("exitVal of rrdLastUpdate is Successful");
else
System.out.println("exitVal of rrdLastUpdate is Abnormal");
} catch (Exception e) {
System.out.println("Problem in executing rrdlastupdate()");
e.printStackTrace();
}//end of try-catch
I hope this be useful for U :) I worked with some other rrdtool commands in java. if you need more help, I will be happy to help.

Java program that calls external program behaving asynchronously?

All,
I originally had a shell script that called SQLLoader (Oracles data upload tool).
The problem was that SQLLoader takes a plain text password as input so I decided to build a Java application to call SQLLoader internally passing a decrypted password into the command string.
e.g.
sqlldr user/pass#DBServer control=../sqlloader.ctl log=sqlloader.log data=mydata.csv
So with my java wrapper it became this in my shell script
java -jar sqlloader.jar sqlloader.ctl mydata.csv
However a new problem developed when SQLLoader complained there was no file to load. After some head scratching it was discovered that a subsequent command in my shell script seemed to be executing while my java application was still running. Therefore it was behaving asynchronously.
The next command was moving the input file sqlloader was using before it could get a chance to use it. So I put a sleep command in of 20 seconds to give my java application time to run.
java -jar sqlloader.jar sqlloader.ctl mydata.csv
echo $?
sleep 20
if [ $? -ne 0 ]
then
echo "SQLLoader failed during execution, please check the log : "
mv mydata.csv
else
echo "SQLLoader successfully processed file : "
mv mydata.csv
fi
Does anyone know why unix is behaving this way, does Java execute my SQLLoader as a different user/ thread?
This is my java code:
Runtime Rt;
Process Prc;
Prc = Rt.exec("sqlldr user/decryptedpass#DBServer control=../sqlloader.ctl log=sqlloader.log data=mydata.csv);
system.exit(0);
I checked the Runtime Class for anything about it being Asynchronous but couldnt find anything
http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html
Any theories or suggestions?
Thanks
Yes. If you look at Runtime.exec again it does specify that it will launch a new process in the specified environment (e.g. independently of the current "environment" or as you put it asynchronously). You should use ProcessBuilder to create a Process and then waitFor that Process to finish before calling System.exit - which certainly isn't mandatory. Something like this
public static void main(String[] args) {
// String command = "/usr/bin/sleep 5";
List<String> command = new ArrayList<String>();
command.add("c:/cygwin/bin/sleep");
command.add("5");
ProcessBuilder pb = new ProcessBuilder(command);
BufferedReader is = null;
try {
System.out.println("Starting command " + command);
Process p = pb.start();
int ret = p.waitFor();
is = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = is.readLine()) != null) {
System.out.println(line);
}
if (ret == 0) {
System.out.println("Command has completed.");
System.exit(ret);
} else {
System.out.println("Command completed with return code " + ret);
System.exit(ret);
}
} catch (Exception e) {
System.out.println("Caught Exception " + e.getMessage()
+ " running command " + command);
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
}
System.out.println("COMMAND FAILED");
System.exit(1);
}
You need to wait for process completion, you should also read all output (stdout and stderr) from the process you are starting.
If you call exit() after exec(), Java will do just that - exit immediatedly.
Here is an article that explains Runtime.exec pitfalls: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4 (also consider the other pages).

Running a .bat/ .cmd file from Java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I wanted to run a .cmd file from Java. I have something which works for me. Can someone help me understand possible failures of my program.
import java.io.IOException;
/*
How to run a batch .bat or .cmd file from Java?
1. I don't want the command window to open up. It should be in background.
2. Gracefully destroy any new process created.
3. Need to confirm the quality of the program with experts.
*/
public class RunBat {
public static void main(String args[]) {
Runtime run = Runtime.getRuntime();
//The best possible I found is to construct a command which you want to execute
//as a string and use that in exec. If the batch file takes command line arguments
//the command can be constructed a array of strings and pass the array as input to
//the exec method. The command can also be passed externally as input to the method.
Process p = null;
String cmd = "D:\\Database\\TableToCSV.cmd";
try {
p = run.exec(cmd);
p.getErrorStream();
System.out.println("RUN.COMPLETED.SUCCESSFULLY");
}
catch (IOException e) {
e.printStackTrace();
System.out.println("ERROR.RUNNING.CMD");
p.destroy();
}
}
}
Is my solution reliable? How can I make sure that once the .cmd is execute there is no processes hanging around.
Thanks.
I don't know what you are doing with p.getErrorStream(), You are not accesing it.
Way to determine result i.e. exit code of command executed is by adding following lines after
p = run.exec(cmd);
p.waitFor();
System.out.println(p.exitValue());
And put p.destroy() in finally block.
Hope this helps.
Execute your command as:
cmd.exe /C d:\database\tabletoCSV.cmd
See cmd.exe /? for more information:
> cmd /?
Starts a new instance of the Windows command interpreter
CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
[[/S] [/C | /K] string]
/C Carries out the command specified by string and then terminates
/K Carries out the command specified by string but remains
[...]
Like Carl just mentioned
You are not capturing any output error / success output.
Your are not making the process thread wait for exitValue.
Have you given a look at ProcessBuilder class?
Anyway , you can have a look at following code
Process proc = null;
Runtime rt = Runtime.getRuntime();
try {
proc = rt.exec(cmd);
InputStream outCmdStream = proc.getInputStream();
InputStreamReader outCmdReader = new InputStreamReader(outCmdStream);
BufferedReader outCmdBufReader = new BufferedReader(outCmdReader);
String outLine;
while ((outLine = outCmdBufReader.readLine()) != null) {
System.out.println(outLine);
}
InputStream errStream = proc.getErrorStream();
InputStreamReader errReader = new InputStreamReader(errStream);
BufferedReader errBufReader = new BufferedReader(errReader);
String errLine;
while ((errLine = errBufReader.readLine()) != null) {
System.out.println(errLine);
}
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
} catch (IOException e) {
e.printStackTrace();
System.out.println("ERROR.RUNNING.CMD");
proc.destroy();
}
}
Hope this helps
There's another thing wrong with this code that other answers don't indicate: If the process you start generates (console) output and you don't connect up its output stream, it will stall and fail for no apparent reason. For some programs and environments I've found it necessary to connect up separate threads to keep both the output and error streams drained. And to capture their output so you're not flying blind.
If you have a modern Java (post 1.5), you could also be looking at the ProcessBuilder class as a means to start up external programs.

Categories