I have a JAVA jar program turned into a .exe then an install created with INNO Setup. The program installs and works except at the end I submit a dos command to execute a batch file to copy some files. If I run the installed program by double clicking on the file associated with it. The program runs successfully except the batch file does not run. If I open a command window and execute the same program from the command line, it runs successfully and the batch file runs successfully.
The method that runs the batch file is.
public static int moveAside()
{
System.out.println("----MoveAside: start: " + UserDir + " TCDir: " + TCDir);
try
{
String pathx = "\"" + UserDir + "\"";
String newFileName = FilenameIn.replaceAll("/","\\\\");
String newTCDir = TCDir.replaceAll("/","\\\\");
String squote = "\"";
String path = "cmd \"/c/q\" start \"\" " + pathx + "\\moveAside.bat " + "C:\\IronLayer\\PERPLXDAM\\" + " " + newFileName + " " + newTCDir ;
// ">> moveAside.out";
System.out.println("MA: " + path + "<<<");
Runtime rn = Runtime.getRuntime();
Process pr = rn.exec(path);
} catch (Exception e)
{
System.out.println("----Exception in MoveAside: " + e.getMessage());
return 1;
}
System.out.println("----MoveAside: run successfully");
return 0;
}
A typical call from the System.out.println above is:
"C:\Program Files (x86)\PERPLXDAM"\moveAside.bat C:\IronLayer\PERPLXDAM\ C:\Users\johnf\onedrive\Desktop\robin042920e.DVNC C:\Users\johnf\onedrive\Desktop\
The bat file moveAside.bat is:
::
::---setup remover bat
::
:: %1 - desktop directory name
:: %2 - transcode file name and path
:: %3 - desktop location
::
echo on
for /F "tokens=2" %%i in ('date /t') do set mydate=%%i
set mytime=%time%
echo %mydate%:%mytime% "==" PPLXCTL.cfg %1 "==" %2 =="C:\IronLayer\PERPLXDAM\" == "desktop: " + %3 >>"C:\IronLayer\PERPLXDAM\Hist.log"
set local
set "_tdir = %1"
set "_tfiledir = %2"
echo tfiledir: "%_tfiledir%"
move /Y "%2" "C:\IronLayer\PERPLXDAM\"
move /Y "%3PPLXCTL.cfg" "C:\IronLayer\PERPLXDAM\"
::exit
(the exit is commented out so the command window does not disappear while I am debugging.)
An Icon is associated with the .DVNC file extent and double clicking on one of those files triggers the program. But the batch file does not run executing it that way, the rest of the program runs fine, just not the final bat file.
Again, if I execute the same .exe from the command line the program works and the .bat runs successfully and the files are copied off the desktop.
Here are a few things to check:
It may be that the environment / directory for the EXE is different to when you run as java -jar classname - check that carefully by printing dir paths before use.
Run the command without cmd.exe if possible, and remove the weird escaping you have on the paths. Java has File / Path classes for ALL path manipulation:
String[] path = new String[] {
new File(UserDir, "moveAside.bat").toAbsolutePath()
, "C:\\IronLayer\\PERPLXDAM\\"
, FilenameIn
, TCDir
};
Also check for errors: after start() get the sub-process exit code and check rc == 0
int rc = pr.waitFor();
// exception if rc != 0
Then check STDERR in case the batch file has failed and not returned non-zero code. It is easier to do this if replace use of Runtime.exec with ProcessBuilder and merge STDERR->STDOUT:
ProcessBuilder pb = new ProcessBuilder(path);
pb.redirectErrorStream(true);
// See also: pb.redirectError(new File("stderr.log")));
Process pr = pb.start();
try(OutputStream os = p.getOutputStream()) {
os.transferTo(System.out);
}
int rc = pr.waitFor();
You invoke the Runtime.exec() method. The method returns a Process instance, and in it's documentation you can read
By default, the created process does not have its own terminal or console. All its standard I/O (i.e. stdin, stdout, stderr) operations will be redirected to the parent process, where they can be accessed via the streams obtained using the methods getOutputStream(), getInputStream(), and getErrorStream(). The parent process uses these streams to feed input to and get output from the process. Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the process may cause the process to block, or even deadlock.
So it is likely your process is started by the OS but gets blocked due to I/O restrictions. Get around that by reading the STDOUT and STDERR streams until your process finishes. One good programming model is visible at https://www.baeldung.com/run-shell-command-in-java
I am trying to launch Apache Spark job from java code. Have problems with path to file and " symbols in it. The code
String command = sparkPath
+ "bin/spark-submit --class ClassName \"" + curFilePath
+ "\" " + readFilePath + " " + saveFilePath;
System.out.println("Next command: \n " + command);
// run Unix command
Process proc = Runtime.getRuntime().exec(command);
So as a result I have the error:
Exception in thread "main" java.net.URISyntaxException: Illegal character in path at index 0: "/home/ubuntu/Desktop/teh2/first-example-1.0.jar"
at java.net.URI$Parser.fail(URI.java:2848)
at org.apache.spark.util.Utils$.resolveURI(Utils.scala:1343)
at org.apache.spark.deploy.SparkSubmitArguments.parse$1(SparkSubmitArguments.scala:338)
However if I remove " around curFilePath or copy the command from System.out.println and paste/execute it in the command line it works fine with double quotes.
Please check from which directory it's getting invoked.
You can try below steps
Add SPARK_HOME and SPARK_PATH in $PATH, if you add it, you can execute the scripts in the bin directory without absolute/relative path
Runtime.exec is not recommended. Use ProcessBuilder to execute commands, it'll accept a String array/List, add your command and arguments in the list and use it to execute.
I'm using Runtime.exec() to run a shell script in a Java program.
The script basically compiles a java program and runs it and goes something like:
./run2.sh "/Users/user/Desktop/Test.java" "Test" "/Users/user/Desktop/"
my parameters in general are the absolute path of the java file, class name and directory where the supposedly compiled class file is
my script is simply
javac "$1"
cd "$3"
java "$2"
I've tried running the resulting command in my Terminal and it works fine. however when the java program runs it, I get and error:
javac: invalid flag: "/Users/user/Desktop/Test.java"
What should I do? I've tried every possible script I can find on the internet (*edit: and I can think of, of course)
(*edit: execute statement)
// some code here...
String[] outFile = translate.translate();
try {
String params = "";
for(String sss: outFile) {
String tmp = "\"" + sss + "\"";
params += tmp + " ";
}
String command = "./run2.sh "+params;
System.out.println(command);
Process proc = Runtime.getRuntime().exec(command);
} //respective catch
the first line, String[] outFile = translate.translate() returns an array Strings of my supposedly parameters
Your mistake is including quote characters in the command string that you are passing to exec(). The exec() method does NOT know how to deal with quotes or other "shell language" stuff. You would be better off trying to execute the command something like this:
Runtime.getRuntime().exec(new String[]{command, arg1, arg2, arg3});
where the command and arguments strings DO NOT have quotes around them.
I am trying to launch a .exe file through a Java program. I used the following code:
System.out.println("Opening " + path);
Process exec;
exec = Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL " + path);//path is the path of the exe file which is passed as an argument from another java class
the output is as follows:
Opening C:\Program Files (x86)\C-Free 5\CppIDE.exe
But it is not opening.
Instead when I try
String pat="C:\\Program Files (x86)\\C-Free 5\\CppIDE.exe";
Process exec;
exec = Runtime.getRuntime().exec("rundll32 SHELL32.DLL,ShellExec_RunDLL " + pat);
the program is opened.
I don't know what the problem is.
It's very likely that the space in your path is the problem.
I suggest you pass the arguments as an array instead of passing a single string containing the whole command (alternatively you could quote the spaces correctly, but that's not quite as easy).
Either
use the String[] version of Runtime.exec() or
switch to using ProcessBuilder which has an altogether simpler and more intuitive API.
With ProcessBuilder this could look like this:
ProcessBuilder pb = new ProcessBuilder("rundll32", "SHELL32.DLL,ShellExec_RunDLL", path);
Process p = pb.start();
Also, I see no reason to invoke rundll32 at all in this scenario. This should work just as well:
ProcessBuilder pb = new ProcessBuilder(path);
Process p = pb.start();
You need to construct the path using File.separator. The path separator you are using will, in this case, will be system dependant.
Is it possible to open the command prompt (and I guess any other terminal for other systems), and execute commands in the newly opened window?
Currently what I have is this:
Runtime rt = Runtime.getRuntime();
rt.exec(new String[]{"cmd.exe","/c","start"});
I've tried adding the next command after the "start", I've tried running another rt.exec containing my command, but I can't find a way to make it work.
If it matters, I'm trying to run a command similar to this:
java -flag -flag -cp terminal-based-program.jar
EDIT Unfortunately I have had some strange findings. I've been able to successfully launch the command prompt and pass a command using this:
rt.exec("cmd.exe /c start command");
However, it only seems to work with one command. Because, if I try to use the command separator like this, "cmd.exe /c start command&command2", the second command is passed through the background (the way it would if I just used rt.exec("command2");). Now the problem here is, I realized that I need to change the directory the command prompt is running in, because if I just use the full path to the jar file, the jar file incorrectly reads the data from the command prompt's active directory, not the jar's directory which contains its resources.
I know that people recommend staying away from rt.exec(String), but this works, and I don't know how to change it into the array version.
rt.exec("cmd.exe /c cd \""+new_dir+"\" & start cmd.exe /k \"java -flag -flag -cp terminal-based-program.jar\"");
If you are running two commands at once just to change the directory the command prompt runs in, there is an overload for the Runtime.exec method that lets you specify the current working directory. Like,
Runtime rt = Runtime.getRuntime();
rt.exec("cmd.exe /c start command", null, new File(newDir));
This will open command prompt in the directory at newDir. I think your solution works as well, but this keeps your command string or array a little cleaner.
There is an overload for having the command as a string and having the command as a String array.
You may find it even easier, though, to use the ProcessBuilder, which has a directory method to set your current working directory.
Hope this helps.
public static void main(String[] args) {
try {
String ss = null;
Process p = Runtime.getRuntime().exec("cmd.exe /c start dir ");
BufferedWriter writeer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
writeer.write("dir");
writeer.flush();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
System.out.println("Here is the standard output of the command:\n");
while ((ss = stdInput.readLine()) != null) {
System.out.println(ss);
}
System.out.println("Here is the standard error of the command (if any):\n");
while ((ss = stdError.readLine()) != null) {
System.out.println(ss);
}
} catch (IOException e) {
System.out.println("FROM CATCH" + e.toString());
}
}
The following works for me on Snow Leopard:
Runtime rt = Runtime.getRuntime();
String[] testArgs = {"touch", "TEST"};
rt.exec(testArgs);
Thing is, if you want to read the output of that command, you need to read the input stream of the process. For instance,
Process pr = rt.exec(arguments);
BufferedReader r = new BufferedReader(new InputStreamReader(pr.getInputStream()));
Allows you to read the line-by-line output of the command pretty easily.
The problem might also be that MS-DOS does not interpret your order of arguments to mean "start a new command prompt". Your array should probably be:
{"start", "cmd.exe", "\c"}
To open commands in the new command prompt, you'd have to use the Process reference. But I'm not sure why you'd want to do that when you can just use exec, as the person before me commented.
You just need to append your command after start in the string that you are passing.
String command = "cmd.exe /c start "+"*your command*";
Process child = Runtime.getRuntime().exec(command);
String[] command = {"cmd.exe" , "/c", "start" , "cmd.exe" , "/k" , "\" dir && ipconfig
\"" };
ProcessBuilder probuilder = new ProcessBuilder( command );
probuilder.directory(new File("D:\\Folder1"));
Process process = probuilder.start();
You can use any on process for dynamic path on command prompt
Process p = Runtime.getRuntime().exec("cmd.exe /c start dir ");
Process p = Runtime.getRuntime().exec("cmd.exe /c start cd \"E:\\rakhee\\Obligation Extractions\" && dir");
Process p = Runtime.getRuntime().exec("cmd.exe /c start cd \"E:\\oxyzen-workspace\\BrightleafDesktop\\Obligation Extractions\" && dir");
Please, place your command in a parameter like the mentioned below.
Runtime.getRuntime().exec("cmd.exe /c start cmd /k \" parameter \"");
You have to set all \" (quotes) carefully. The parameter \k is used to leave the command prompt open after the execution.
1) to combine 2 commands use (for example pause and ipconfig)
Runtime.getRuntime()
.exec("cmd /c start cmd.exe /k \"pause && ipconfig\"", null, selectedFile.getParentFile());
2) to show the content of a file use (MORE is a command line viewer on Windows)
File selectedFile = new File(pathToFile):
Runtime.getRuntime()
.exec("cmd /c start cmd.exe /k \"MORE \"" + selectedFile.getName() + "\"\"", null, selectedFile.getParentFile());
One nesting quote \" is for the command and the file name, the second quote \" is for the filename itself, for spaces etc. in the name particularly.