Best way to run a batch (shell / CMD) command in Java / Eclipse? - java

I have created the following code below in Eclipse / java which executes a batch file, which in turn should also execute once all my TestNG tests have executed but sometimes the bat file will execute and sometimes it dosnt do anything at all, any ideas?
#AfterSuite(alwaysRun = true)
public void executeBatFile() {
try {
List cmdAndArgs = Arrays.asList("cmd", "/c", "copyPasteImgs.bat");
File dir = new File(Paths.get(System.getProperty("user.dir") + "/..").toRealPath() + "\\");
ProcessBuilder pb = new ProcessBuilder(cmdAndArgs);
pb.directory(dir);
Process p = pb.start();
} catch (IOException e) {
e.printStackTrace();
}
}
The batch files moves files from a local folder to a remote folder (When the batch file hasnt worked via eclipse or invoked via jenkins I have manually executed the batch file and it did its jobs, very weird...)
thanks for your help

Apache Commons CLI provides functionalities to handle using command line from java. You can also use the exit value to have an idea about what is going on with your command. For example:
String command = "dir";
CommandLine oCmdLine = CommandLine.parse(command);
DefaultExecutor oDefaultExecutor = new DefaultExecutor();
oDefaultExecutor.setExitValue(0);
try {
int iExitValue = oDefaultExecutor.execute(oCmdLine);
} catch (ExecuteException e) {
System.err.println("Execution failed.");
e.printStackTrace();
} catch (IOException e) {
System.err.println("permission denied.");
e.printStackTrace();
}

Related

Command prompt is not closing after completing even after writing exit

I have following java code
public static void main(String a[]) {
String location = "C:\\Users\\test\\output\\testProject";
File dir = new File("C:\\Users\\test\\cmds");
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", "Start /wait","packageProject.bat",location);
pb.directory(dir);
Process p = null;
try {
p = pb.start();
p.waitFor();
}
catch (IOException e) {
e.printStackTrace();
}
catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("Folder created");
}
Batch file is
cd "C:\Users\test\output\test-master"
mvn clean install -DskipTests
exit
It is packaging file but not command prompt is not closing once process is complete.
Please suggest.
You should remove wrapper CMD.EXE and start, just call the batch file directly as:
String bat = new File(dir, "packageProject.bat").getAbsolutePath();
ProcessBuilder pb = new ProcessBuilder(bat , location);
pb.directory(dir);
Process p = pb.start();
p.waitFor();
If this process generates a lot of output you may run into a second problem if you don't consume error and output streams. You can do this in background threads, or simply send stdout/err to files by adding these calls before pb.start():
pb.redirectOutput(new File(location, "std.out"));
pb.redirectError(new File(location, "std.err"));

How I can install application like .exe or dll file by java code

How to install silently application in windows by java code. I have downloaded the file from server but need to install also on a single click.
How can I achieve this.?
If I understood it correct you want to install a third application from your java application. All you can do is below (this is for exe.. not sure about dll, I do not think you can run them). That should run the installable exe. But it will install or not that depends upon how that software works.. an give it a try.. But this is not recommended
public static void main(String args[]) {
try {
Process proc = Runtime.getRuntime().exec("your installable exe");
proc.waitFor(); //Wait for it to finish
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Try the following code:
String command = "C:\\setup.exe";
Runtime.getRuntime().exec("cmd /c "+command);
read more.
To run batch file try:
Add this to your batch file:
#echo off
C:\Windows\notepad.exe yourpath\omt.txt
In your java program:
String filePath = "C:/yourbatpath.bat";
try {
Process p = Runtime.getRuntime().exec(filePath);
} catch (Exception e) {
e.printStackTrace();
}
read this to get in depth idea.

Using ProcessBuilder to make a jar file isn't completing

I am trying to compile a jar file from within a Java program. When I run the code it starts to build the jar file and saves about 24k of it then the execution just seems to stop and wait (I am using Process.waitFor() and the program isn't finishing its execution). When I force the program to stop the size of the jar file jumps to about 45k. The jar should be about 1300k.
I tried creating a batch file and then calling the batch file with my ProcessBuilder but the same issue occurs. The batch file when run by itself works perfectly.
This is the code I have so far:
public static void buildJar() {
List<String> jarCmdArgs = new ArrayList<>();
jarCmdArgs.add("jar");
jarCmdArgs.add("cvfM");
jarCmdArgs.add(ROOT_DIRECTORY + File.separator + "my_jar.jar");
jarCmdArgs.add(".");
// jarCmdArgs.add("cmd.exe");
// jarCmdArgs.add("/C");
// jarCmdArgs.add(ROOT_DIRECTORY + File.separator + "make_jar.bat");
ProcessBuilder pb = new ProcessBuilder(jarCmdArgs);
pb.directory(new File(SRC_DIR_PATH));
try {
Process p = pb.start();
p.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
This is the contents of the batch file:
//cd to my working dir with all the files to put into the jar
jar cvfM my_jar.jar .

trying to execute mysqldump from java app, multiple problems

I am writing a java app that needs to perform mysql dump, and I am using the runtime.exec, based in the when runtime.exec won't article. The code is below:
public int exectuteCommand(){
Runtime rt = Runtime.getRuntime();
logger.debug("exexuting cmd: " + showCommand());
int exit = -1;
try {
Process proc = rt.exec(cmd);
ExtProcessStreamHandler errorHandler = new ExtProcessStreamHandler(proc.getErrorStream(), "ERROR");
ExtProcessStreamHandler outHandler = new ExtProcessStreamHandler(proc.getInputStream(), "OUTPUT");
// kick it off
errorHandler.start();
outHandler.start();
exit = proc.waitFor();
} catch (IOException e) {
logger.error("ERROR!! ~~ executing command " + showCommand(), e);
e.printStackTrace();
} catch (InterruptedException e) {
logger.error("ERROR!! ~~ unexpected return for " + showCommand() + " , returned " + exit, e);
e.printStackTrace();
}
return exit;
}
1) The command that the process returns works in the shell (I'm running this on a mac). The first error I had was an inability to find the mysqldump command. That results in this error:
java.io.IOException: Cannot run program "mysqldump": error=2, No such file or directory
I resolved that by adding the complete path of the file to the command. The $PATH var shows
/usr/local/mysql/bin/mysqldump
as the complete path. How can I make sure my java app has that info?
2) when adding the complete path to the command, I get this error msg:
INFO [Thread-1] (ExtProcessStreamHandler.java:28) - external process ERROR : mysqldump: Couldn't find table: ">"
Here is the code that builds the command array:
return new String[] {MYSQLDUMP_CMD, "-u", USER_DEFAULT, "-p"+ PW_DEFAULT, TEST_DB_NAME,
">", DUMP_LOC};
again, when I copy the command passed to the java app into the shell on my mac, it works. Not sure what I'm doing wrong.
thanks in advance!
It thinks ">" is an argument intended for mysqldump. You are invoking an executable, not evaluating a shell expression. If you want to pipe your output, do it with the outHandler and errorHandler in your code.
An alternative is to invoke a shell and pass the expression you want to evaluate as an argument:
expr = new StringBuilder()
.append(MYSQLDUMP_CMD).append(' ')
.append("-u").append(USER_DEFAULT).append(' ')
.append("-p").append(PW_DEFAULT).append(' ')
.append(TEST_DB_NAME).append(' ')
.append(">").append(' ')
.append(DUMP_LOC)
.toString();
return new String[] {"/bin/bash", "-c", expr};
If your code to build the command array doesn't wrap spaced arguments in single quotes (or if the JDK doesn't do this for you), then modify the StringBuilder statement to create the wrapped quotes for you.
Below Code is worked for me
public static void backup() {
String currentDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd"));
String backupPath = String.format("%s/%s.%s", Helper.BACKUP_PATH, currentDate, "sql");
File backupFile = new File(backupPath);
if (!backupFile.exists()) {
try {
backupFile.createNewFile();
String mysqlCom=String.format("mysqldump -u%s -p%s %s",USER_NAME,PASSWORD,DB);
String[] command = new String[] { "/bin/bash", "-c",mysqlCom};
ProcessBuilder processBuilder = new ProcessBuilder(Arrays.asList(command));
processBuilder.redirectError(Redirect.INHERIT);
processBuilder.redirectOutput(Redirect.to(backupFile));
Process process = processBuilder.start();
process.waitFor();
LOGGER.info("Backup done");
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
LOGGER.info("Database already backuped today");
}
}

.jar doesn't run external program

So i have a java project made in eclipse with sphinx voice recognition. If i say a certain word then it runs a .bat file.
if (resultText.equals("word")) {
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("C:/c.bat");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In Eclipse it works fine, but after i export the .jar and run it, if i say that specific word, it doesn`t run that .bat. So any ideas why this only runs my .bat file from eclipse and not from command line? Thanks
I am not sure about this but atleast try this solution once.
Try giving the .bat file path as C:\\c.bat and then try again.
Try adding something like:
File f = new File("c:/c.bat");
if(f.exists()) {
// execute the file
Process process = runtime.exec(f.getAbsolutePath());
process.waitFor();
InputStream stdout = process.getInputStream();
InputStream stderr = process.getErrorStream();
// check the streams for errors
} else {
// log error
}
hth

Categories

Resources