Running .bat file in java to create a .csv file - java

I am trying to execute a bat file using java. This bat file contains code that should create a .csv file in the same directory. The .csv file is successfully created when I execute the .bat file by running it on my Windows machine, however when I try to execute it in java using Runtime.getRuntime().exec(), the file does not get created.
String[] command = {"cmd.exe", "/C", "C:/Users/MidiCsv/ex.bat"};
Process p = null;
try {
p = Runtime.getRuntime().exec(command);
} catch (IOException e) {
e.printStackTrace();
}
try {
p.waitFor();
System.out.println("ready");
} catch (InterruptedException e) {
e.printStackTrace();
}
content = Files.readString(Paths.get("C:/Users/MidiCsv/" + midiName + ".csv"), StandardCharsets.US_ASCII);
The value returned by the p.waitFor() method is 2, I assume this means there was an error here since the normal return value is 0. What error could this indicate?

If the working directory is required to be same as your batch file, use this variant of exec method instead:
public Process exec(String[] cmdarray,
String[] envp,
File dir)
throws IOException
Reference: https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#exec(java.lang.String[],%20java.lang.String[],%20java.io.File)
Make dir the directory containing your batch file.

I figured out the error from taking the helpful advice here. I used the exec() variant Febtober mentioned, also previously I was putting the absolute path of the .batch file as the dir paramter, whereas I should have put the directory of the .batch file instead.

Related

How to run a batch file which is present in the working directory of the java file? [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();
}

About citing external files in java application

I am writing a java application, in which I am automatically importing external csv files in background to do the computation. But the problem is that I am using "absolute" file path in my java program, the generated jar file will not work in another computer. Is there anyway in java to use a kind of "working directory path" so that I can still run the jar file in another computer as long as I put the csv files I'd like to import in the same folder with the jar file?
Thanks!
You can read a file using its name like
try (BufferedReader br = new BufferedReader(new FileReader("text.txt"))) {
String line;
while ((line=br.readLine())!=null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
Here text.txt should be in the same working directory where the jar was executed.
You can also read the directory name from the command line, using the command line arguments like
public static void main(String[] args) {
//check if there were any command line arguments
if (args.length > 0) {
// args[0] is the first command line argument unlike C where args[0] would give u the executable's name
} else {
System.err.println("Usage: java -jar <jar_name> [directory_names..]");
}
}
You can also have a configuration file such as a properties file to read the directory names.
new File(".") give you the relative path
you can write relative path like that :
File file = new File(".\\CSVs\\myfile.csv");
System.getProperty("user.dir") will return you the working directory.
System.getProperty("user.dir")+"\\myfile.txt"
More informations here :system properties, oracle docs

Calling shell script from Java by giving a relative path of script location

I am working on a project wherein I have to call my shell script stored at the location where my java files reside.I am currently calling the shell script by giving a hard-coded (absolute) path.I want to make my script run by giving a relative path.Currently I am running my script via this code in Java:
try {
ProcessBuilder pb2 = new ProcessBuilder("/bin/bash", "/Users/umang/Documents/script.sh", arg);
Process scriptexec = pb2.start();
scriptexec.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
Here the arg is the location of the file on which the script runs.The current Implementation works well but the Issue is I have to store my script at some location on the server.Its a webapp which is deployed on apache-tomcat server by making a war file. It would be good to have a relative path and store the script inside the war file when it is being generated.
Attempt #1:
final File executorDirectory = new File("A/B/C/D/E/F/G/H/");
try {
ProcessBuilder pb2 = new ProcessBuilder("/bin/bash","combiner.sh",arg);
pb2.directory(executorDirectory);
Process scriptexec = pb2.start();
scriptexec.waitFor();
System.out.println("Script executed successfully");
} catch (Exception e) {
e.printStackTrace();
}
A/B/C/D/E/F/G/H/ location where my script resides from the top of the application
Error: File not found error -2 JavaIOException()
Attempt #2
URL loc=ClassLoader.getSystemResource("script.sh");
try {
ProcessBuilder pb2 = new ProcessBuilder("/bin/bash", "/Users/umang/Documents/script.sh", arg);
Process scriptexec = pb2.start();
scriptexec.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
Error: loc does not get me the path for the script location.In the debugger tool I figured out it gets null.
Since the ClassLoader.getSystemResource returns a URL and ProcessBuilder only accepts String I cannot directly append them.
If this is deployed in tomcat try to put your script in the WEB-INF of your war. Now assuming you start the process from a servlet you could use
ServletContext ctx = getContext();
String pathForProcessBuilder = ctx.getRealPath("/WEB-INF/script.sh");
If you don't want to use the ServletContext, try using
getClass().getClassLoader().getResource("/WEB-INF/script.sh")
instead of using ClassLoader (in order to make sure you use the "correct" classloader, i.e. the one which loaded your class)

Runtime.exec doesn't do anything... (no errors)

I am trying to use java to run a batch file at an absolute location. The batch file will compile a couple of java files.
Here is the code which I have been trying:
String s=file.getAbsolutePath() + "\\compile.bat";
Runtime rut = Runtime.getRuntime();
try {
rut.exec(new String[] {file.getAbsolutePath() + "\\compile.bat"});
}catch(IOException e1) {
e1.printStackTrace();
}
System.out.println(s);
Now, when this code gets executed, I get no console errors, but the batch file is not run. When I run the batch file through Windows Explorer, however, the batch file works, compiles the files and closes when done.
How do you know that there were no console errors?
Try this:
String s=file.getAbsolutePath() + "\\compile.bat";
Runtime rut = Runtime.getRuntime();
try {
Process process = rut.exec(new String[] {file.getAbsolutePath() + "\\compile.bat"});
// prints out any message that are usually displayed in the console
Scanner scanner = new Scanner(process.getInputStream());
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
}catch(IOException e1) {
e1.printStackTrace();
}
System.out.println(s);
Check the return value of the subprocess using exitValue().
Also read the error stream getErrorStream() if the exist value is non zero.
Note that when using your invocation of Runtime.exec, the working directory of the command being executed will be the current working directory of the java process. Does your batch file need to run in a specific directory?
If you need to set a specific working directory for the sub-process, you'll need to use another version of Runtime.exec.

how to run a batch file from java?

I am trying run a batch file from my java codes, but unfortunately I could not
run it properly. Actually the batch file is running but only the first line of the batch file
is running, so please give solution to it, here are the codes and the batch file.
class bata
{
public static void main(String [] args)
{
try
{
Runtime.getRuntime().exec("start_james.bat");
}
catch(Exception e) {}
}
}
and the batch file is
cd\
c:
cd C:\Tomcat 5.5\webapps\mail_testing\james-2.3.2\bin
run.bat
start
What do you expect cd: to do? That doesn't look right to me...
If your batch file is only going to run another batch file, why not run that target batch file to start with? If you're worried about the initial working directory, use the overload which takes a File argument to say which directory to use. For example:
File dir = new File("C:\\Tomcat 5.5\\webapps\\mail_testing\\james-2.3.2\\bin");
Runtime.getRuntime().exec("start_james.bat", null, dir);
If all the other answers (with valid batch file) didn't work try executing cmd.exe directly like this:
File dir = new File("D:\\tools\\bin");
Runtime.getRuntime().exec("c:\\windows\\system32\\cmd.exe /c start_james.bat", null, dir);
You might also use the %SystemRoot% environment variable to get the absolute path to cmd.exe.
Isn't there something in java, whereby you can invoke the batch file directly with full path?
I mean, why do you need to change directories?
Also, what is the use of cd:? It is not a valid command in DOS, unless you are using *nix.
I think he wants to change to a directory and then run the batch file. Can you try this ?
cd /d C:\Tomcat 5.5\webapps\mail_testing\james-2.3.2\bin
run.bat
start
Was "cd:" supposed to be a label you can jump to using the GOTO command? However labels are declared using ":labelname". This should be the reason why your batch execution stops after the first line.
This works like a charm:
Runtime run = Runtime.getRuntime();
try
{
System.out.println("Start Running the batch file");
Process p = run.exec(new String[]{"cmd.exe","/c", "start", "C:/Users/sony/Documents/NetBeansProjects/CodeReview/src/codereview/install.bat",i,j,m,l});
System.out.println("Completed");
}
catch (Exception e)
{
}
here i,j,k,l are parameter passing to batch file

Categories

Resources