I have an excel sheet where it has a list of jar files to be executed. To kick start the testing, I will run a code to read from the said excel sheet and execute the jar files in the excel sheet. The code to run those jar files is as follow :
final Process p = Runtime.getRuntime().exec("cmd /c start cmd /k java -jar " + start.jar_filepath + " " + start.tc_name + " " + start.test_data + " " + start.test_result + " " + start.test_cycle);
This will actually run all the jar files concurrently.
I actually wanted one jar to be executed at one time, and the next jar to be executed AFTER the current jar has finish execution.
I added the following.
p.waitFor();
However, it still behaves the same, that is, it is executed simultaneously.
Am I using the waitFor() wrongly ? Advice is appreciated.
Update:
The following is the code that iterates the excel sheet
public static void main(final String[] args) throws IOException, Throwable {
final DataFormatter df = new DataFormatter();
final FileInputStream StartInput = new FileInputStream("c:\\TA\\TestConfig_MA.xlsx");
final XSSFWorkbook StartInputWB = new XSSFWorkbook(StartInput);
final XSSFSheet sheet = StartInputWB.getSheet("Config");
System.out.println("Amount of Row in test config : "+ sheet.getLastRowNum());
start.count = 1;
//while (start.count <= sheet.getLastRowNum()) {
for(start.count = 1; start.count <= sheet.getLastRowNum(); start.count++){
System.out.println("Total test case = " + sheet.getLastRowNum());
System.out.println(start.count);
final XSSFRow row = sheet.getRow(start.count);
start.testability = row.getCell(0).toString();
start.jar_filepath = row.getCell(1).toString();
start.tc_name = row.getCell(2).toString();
start.test_data = row.getCell(3).toString();
start.test_result = row.getCell(4).toString();
start.test_cycle = df.formatCellValue(row.getCell(5));
System.out.println("test cycle from start.jar = " + start.test_cycle);
System.out.println("Test Case Name : " + start.tc_name);
if (start.testability.equals("Y") || start.testability.equals("y)")) {
System.out.println("Test Case Name : " + start.tc_name);
System.out.println("Round : " + start.count);
final Process p = Runtime.getRuntime().exec("cmd /c start cmd /k java -jar " + start.jar_filepath + " " + start.tc_name + " " + start.test_data + " " + start.test_result + " " + start.test_cycle);
p.waitFor();
System.out.println("wait for = " +p.waitFor());
else {
System.out.println("Its a no");
}
// ++start.count;
}//for
System.out.println("test is done");
}
}
why you need "cmd /c start cmd /k ..."?
You run cmd which runs start which runs cmd which runs java
In particular, start opens a new window and returns immediately. Therefore p.waitFor(); will wait for start to complete, but not the new window opened by it.
You may want to narrow it to simple
...exec("java -jar " + ...)
or at least
...exec("cmd /c java -jar " + ...)
Related
I am currently heeding advice from this Stack Overflow post:
Call and receive output from Python script in Java? (which links to http://www.devdaily.com/java/edu/pj/pj010016 for getting the output)
So, that's great and all, and I used it for the following code successfully:
String directPath;
if (Files.exists(Paths.get("C:/Users/jiaqin/Documents/NetBeansProjects/NCHandler/nchandlerv2/NCPythonFiles/"))) {
directPath = "C:/Users/jiaqin/Documents/NetBeansProjects/NCHandler/nchandlerv2/NCPythonFiles/";
}
else {
directPath = "/home/lab/testNetconf/NCPythonFiles/net_back_end/";
}
Process p = Runtime.getRuntime().exec("python " + directPath + "get_platform_and_OS.py -ssh_ip " + ui.ssh_ip
+ " -username " + ui.username + " -password " + ui.password);
Scanner threeInfo = new Scanner(p.getInputStream());
String hostName = "";
String IP_Address = ui.ssh_ip;
String OS = "";
String platform = "";
int iter = 0;
while (threeInfo.hasNextLine()) {
switch(iter) {
case 0:
hostName = threeInfo.nextLine();
break;
case 1:
OS = threeInfo.nextLine();
break;
case 2:
platform = threeInfo.nextLine();
break;
default:
break;
}
iter ++;
}
threeInfo.close();
Label hostNameLabel = new Label(hostName);
Label sshLabel = new Label("SSH IP Address: " + IP_Address);
Label OSLabel = new Label(OS);
Label platformLabel = new Label(platform);
Essentially, I run a python script by determining its path first, then I read the output using a Scanner (instead of a BufferedReader like in the post). Based on that case, I have a later method that uses the exact same concept:
public static String verifyShowCommands(String[] showCommands, MainUI ui) {
try {
String errorText = "";
String retErrors = "";
System.out.println("Python exec command is:\n" + "python /home/lab/testNetconf/NCPythonFiles/net_back_end/verify_show_commands.py -ssh_ip " + ui.ssh_ip + " -username "
+ ui.username + " -password " + ui.password + " -show_commands \"" + String.join(", ", showCommands) + "\"");
Process p = Runtime.getRuntime().exec("python /home/lab/testNetconf/NCPythonFiles/net_back_end/verify_show_commands.py -ssh_ip " + ui.ssh_ip + " -username "
+ ui.username + " -password " + ui.password + " -show_commands \"" + String.join(", ", showCommands) + "\"");
BufferedReader obtainedInfo = new BufferedReader(new InputStreamReader(p.getInputStream()));
String read = null;
while ((read = obtainedInfo.readLine()) != null) {
System.out.println("New line found");
retErrors += read;
}
System.out.println("Obtained Info is:" + retErrors + " and that's it");
obtainedInfo.close();
for (int i = 0; i < showCommands.length; i ++) {
if (i < showCommands.length - 1) {
int thisSCStart = retErrors.indexOf(showCommands[i]);
int nextSCStart = retErrors.indexOf(showCommands[i+1]);
String outputSC = retErrors.substring(thisSCStart, nextSCStart);
if (outputSC.contains("'Valid': 'No'")) {
errorText += outputSC + "\n";
}
}
else {
String outputSC = retErrors.substring(retErrors.indexOf(showCommands[i]));
if (outputSC.contains("'Valid': 'No'")) {
errorText += outputSC + "\n";
}
}
}
return errorText;
}
catch (IOException e) {
return null;
}
}
As you can see, I'm once again running a python script and reading the output. The error occurs when I attempt to get the substring of retErrors - because retErrors is an empty string; that's right, for some reason, this time the output is NOT getting read. Note that the above uses BufferedReader; I was originally using Scanner, and when that failed I changed over because I thought maybe for god-knows-what reason, synchronization might affect the situation. Unfortunately, it seemed there was STILL no output to read.
As for how I know, I simply observed in the Netbeans output and searched for the line
System.out.println("Obtained Info is:" + retErrors + " and that's it");
Then, you might ask the obvious question: what if the command is invalid? Well, I printed out the entire exec command at the top as well:
System.out.println("Python exec command is:\n" + "python /home/lab/testNetconf/NCPythonFiles/net_back_end/verify_show_commands.py -ssh_ip " + ui.ssh_ip + " -username "
+ ui.username + " -password " + ui.password + " -show_commands \"" + String.join(", ", showCommands) + "\"");
So, I looked for that line in the Netbeans output, and there it was:
Info: Python exec command is:
python /home/lab/testNetconf/NCPythonFiles/net_back_end/verify_show_commands.py -ssh_ip 9.0.0.12 -username root -password lab -show_commands "show bgp scale"
And then I copy-pasted that exact command into a terminal and ran it, and I got an output (the actual type of the printed result in the output is a dictionary, hence the brackets):
Anyone have some advice? This is extraordinarily frustrating to me because I'm following the exact format of the first case with get_platform_and_os.py but then with verify_show_commands.py, it just doesn't read anything.
As a side note, if this information helps, when I run the command manually in the terminal, it takes roughly 2-3 seconds to complete. However, running it in my project takes much less than a second before it errors out.
So...
Using Quotes within getRuntime().exec
Apparently this is a thing. I just made every word in the command an array element instead, and inside the array, "show bgp scale" was entered without the quotes. After that, it worked.
I have developed a Java application and it's in last stage.
The problem is that I cannot execute the mysqldump with Runtime.getRuntime().exec().
try {
String[] command = new String[] {
"cmd.exe",
"/c",
"mysqldump --host=" + host + " --user=" + dbuser + " --password=" + dbpass + " " + dbname + " > " + filename
};
Process runtimeProcess = Runtime.getRuntime().exec(command);
int ProcessComplete = runtimeProcess.waitFor();
if (ProcessComplete == 0) {
JOptionPane.showMessageDialog(null, "Database backup has been done successfully");
}
else {
JOptionPane.showMessageDialog(null, "Database backup was unsuccessfull");
JOptionPane.showMessageDialog(null, command);
}
}
catch (IOException | InterruptedException exc) {
Logger.getLogger(Backup.class.getName()).log(Level.SEVERE, null, exc);
}
Can anyone help me with this?
I tried your code in Windows and it works fine for me.
Open cmd, type mysqldump and hit enter.
If it is executed successfully, that means your code should work properly if your database configuration is correct.
If you get 'mysqldump' is not recognized as an internal or external command then either you have to set the MySQL path in your environment variable, or specify the full path for mysqldump in your Java code like this:
String[] command = new String[] {
"cmd.exe",
"/c",
"c://mysql/bin/mysqldump --host=" + host + " --user=" + dbuser + " --password=" + dbpass + " " + dbname + " > " + filename
};
I can get a terminal window or command prompt to open on either Mac OS or Windows. I want to send a string to that terminal or cmd window using my java.
String in = " -i " + "\"" + tfIntdta.getText() + "\"";
String rst = " - r " + "\"" + tfRstplt.getText() + "\"";
String out = " -o " + "\"" + tfOutdta.getText() + "\"";
String strip = " -s" + "\"" + tfStpdta.getText() + "\"";
String guistring = "-n gui";
String wd = "\"" + System.getProperty("user.dir");
String osver = System.getProperty("os.name");
String app = "";
if (osver.contains("Mac")){
app = wd + "/relap5.x\"";
} else if (osver.contains("Windows")){
app = "\\relap5.exe";
} else if (osver.contains("linux")) {
app = "/relap5.x";
}
String run = app + in + rst + out;
So the string would look something like this.
"/Users/brianallison/Documents/Java/RELAP5 GUI/issrs/relap5.x" -i "" - r "" -o ""
I want the line above to appear on the terminal or cmd window and execute.
Put your command and parameters in an array:
String[] command = {
"/Users/brianallison/Documents/Java/RELAP5 GUI/issrs/relap5.x",
"-i", "Choose your input file",
"-r", "",
"-o", ""
};
Then execute using Runtime#exec(String[] cmdarray):
Runtime.getRuntime().exec(command);
This answer has been put together after reading your other two questions from today, here and here.
I am using Java to format a poem in LaTeX and then compile it. The LaTeX-ization works perfectly fine, but I somehow can't run the command. Is this a problem with my LaTeX invocation? For some reason, when I use Java to write an equivalent batch file and then run it, Java will do nothing but when I run the batch file from the shell, it works.
/**
*
* #param title the title of the poem
* #param poem a <code>List</code> with one string for each line of the
* poem.
* #throws FileNotFoundException
*/
protected static void writePDF(final String title, List<String> poem) throws FileNotFoundException {
final StringBuilder latex = new StringBuilder(0);
// I know I shouldn't concatenate like this; I'll fix it later.
// eeeewww escapes
latex.append(
"\\documentclass[letterpaper,12pt,article,oneside]{memoir}\n"
+ "\\usepackage[utf8]{inputenc}\n"
+ "\\usepackage{ebgaramond}\n"
+ "\\usepackage{hyperref}\n"
+ "\\usepackage[protrusion,expansion,kerning,tracking,spacing]{microtype}\n"
+ "\\linespread{1.3}\n"
+ "\\nonfrenchspacing\n"
+ "\\microtypecontext{spacing=nonfrench}\n"
+ "\\begin{document}\n"
+ "\\title{" + title + "}\n"
+ "\\author{}\n"
+ "\\date{\\today}\n"
+ "\\maketitle\n"
+ "\\setlength{\\parindent}{0pt}\n"
+ "\\setlength{\\parskip}{\\baselineskip}\n");
// Go Java 8!
poem
.stream()
.map((String s)
// Original poem's in HTML
-> s.replace("<p>", "\n\n").replace("<br>", "\\\\\n"))
.forEach(latex::append);
latex.append("\n\\end{document}");
final String latexstr = latex.toString().replace("...", "\\ldots");
final String filename = title + ".tex";
final File file = new File(filename);
try (final PrintWriter pw = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)))) {
pw.print(latexstr);
}
final String path = file.getAbsolutePath()
.substring(0, file.getAbsolutePath().lastIndexOf("\\")) + "\\";
System.out.println("Path: " + path);
final String LaTeXcmd = "pdflatex \""
+ path
+ title + "\"";
final File script = new File(""
+ rand.nextDouble()
+ "compile"
+ title.replace(" ", "_")
+ ".bat");
//I originally wanted just to write a batch file and run it from Java.
// try (final PrintWriter pw = new PrintWriter(new BufferedOutputStream(new FileOutputStream(script)))) {
// pw.print(""
// //"#echo off\n"
// + "cd " + path + "\n"
// + LaTeXcmd + "\n"
// // + "del \"" + path + title + ".aux\"\n"
// // + "del \"" + path + title + ".log\"\n"
// // + "del \"" + path + title + ".out\"\n"
// // + "del \"" + path + title + ".tex\"\n"
// // + "start /b \"\" cmd /c del \"%~f0\"&exit /b\n"
//
// + "msg * all\n"
// );
// }
try {
System.out.println("latexcmd " + LaTeXcmd);
final File workingdir = new File(path);
System.out.println("workingdir " + workingdir);
// >>>>>>>>>>>>>>>> IS THIS CORRECT? <<<<<<<<<<<<<<<<
Runtime.getRuntime().exec(LaTeXcmd, new String[]{}, workingdir);
// This statement works perfectly fine (Windows).
// Runtime.getRuntime().exec("msg * all");
} catch (IOException ex) {
Logger.getLogger(PoetryBackend.class.getName()).log(Level.SEVERE, null, ex);
}
}
It's not correct. Try
String command = new String[] {"cmd", "/c", LaTeXcmd };
Runtime.getRuntime().exec(command, new String[]{}, workingdir);
since otherwise you're not executing it through command interpreter, which is what you want if you want it to behave like you would run it from cmd prompt.
This applies to running .bat files as well.
Having a tiny issue where not sure how to call a specific function to print its details.
I created a Radio button that checks the Total physical Memory on a PC, also have one for GPU and both work just fine.
Now I am lost on how to call that same function so it prints in the bigger window when I do a system scan of specific system properties.
if (isWindows()) {
jTextArea1.setText(header + "User Name : " + name
+ "\nOperating System :" + jComboBox1.getSelectedItem()
+ "\nSelected Gamer Ability : " + this.jComboBox4.getSelectedItem()
+ "\nSelected Age Group :" + this.jComboBox5.getSelectedItem()
+ "\nSystem Version : " + System.getProperty("os.version")
+ "\nSystem Architecture : " + System.getProperty("os.arch")
PROBLEM PART + "\nSystem Total Ram : " + this.jRadioButton2......
+ "\nScan ID : " + n + "\n \n")
}
private void jRadioButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String filepath = "..\\Checker\\src\\batchchecker\\memory.bat";
try
{
Process p = Runtime.getRuntime().exec(filepath); // filepath
p.waitFor();
InputStream in = p.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int c = -1;
while ((c = in.read()) != -1)
{
baos.write(c);
}
String response = new String(baos.toByteArray());
jRadioButton2.setText(evt.getActionCommand());
JOptionPane.showMessageDialog(null, "" + evt.getActionCommand()
+ response);
}
catch (Exception e)
{
e.printStackTrace(System.err);
}
}
}
As you can see from above code, my radio does what it needs to and tested. I am just not sure how to call the same result into the bigger picture where it actual prints all the details along with the rest. The line of code is + "\nSystem Total Ram : " + this.jRadioButton2......
Seems like you just need to move your implementation to a separate method that can be called from both your actionPerformed() method and your other call. For example:
public String findMemoryDetails() {
// ... put code here
}
Then call it here:
private void jRadioButton1ActionPerformed(java.awt.event.ActionEvent evt) {
String memDetails = findMemoryDetails();
JOptionPane.showMessageDialog(null, "" + evt.getActionCommand() + memDetails);
}
And here:
+ "\nSystem Total Ram : " + findMemoryDetails()