I want to compile a .tex file from a Java program. I wrote the following code, and it successfully executes, but when I try to open the .pdf file generated, the OS pops a message saying that the file is completely empty (link to image).
By the way, when I run the command pdflatex tarea0.tex directly from terminal, it generates the non-empty .pdf file I want to get from the Java program.
import java.io.File;
import java.io.IOException;
class HelloWorld {
public static void main(String[] args) {
try {
ProcessBuilder pb = new ProcessBuilder("pdflatex", "tarea0.tex");
pb.directory(new File("/Users/carlosreategui/coding/java_testing/latex"));
Process p = pb.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here is the link to all the files
You need to wait for the process to conclude. I'm guessing that exiting the JVM before waiting for the process to conclude causes pdflatex to receive a signal causing it to terminate abruptly.
So adding a line:
p.waitFor();
after the p.start() should have the desired effect.
Related
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();
}
My application should launch an external program to start recording the desktop.
I am using a simple program: recordmydesktop.
Launching the program works fine using ProcessBuilder.
My main issue is that I have to stop the recording. But I don't have access to the program anymore.
My first idea was to launch a terminal from java: bash did not stay open but xterm worked. First of all I would like to know why bash shell stay opened?
Then, I would like to find: How can I not use the xterm and still being able to stop the recording process? For example: send stop signal (Ctrl C) to the process.
Here is some sample code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class hh {
public static void main(String[] args) {
try {
Process process = new ProcessBuilder(new String[]{"/usr/bin/xterm" ,"recordmydesktop"}).start();
InputStream processIS = process.getInputStream();
InputStreamReader processISR = new InputStreamReader(processIS);
BufferedReader processBR = new BufferedReader(processISR);
String line;
System.out.println("Output of the record process is: ");
while ((line=processBR.readLine())!=null){
System.out.print(line);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
Also, in this code, I am not able to get any line back. So my program does not know if the recordmydesktop is ok.
Ps: If you launch:
Process process = new ProcessBuilder(new String[]{"/usr/bin/xterm" ,"xterm"}).start();
Many xterm open instead of two. I create a loop that should not happen. This is not linked to my problem but if someone know the reason I am curious to know why.
Thanks for your help !
You can send a command to the process via the Output stream.
Process process ;
String command = "some command" ;
process.getOutputStream().writeBytes( command.getBytes() ) ;
my problem would take 2 questions, but I'll keep it short. So I need to launch a bat file. Right now I do it like this:
public static void check() throws InterruptedException{
try {
Runtime.getRuntime().exec("cmd /c start build.bat");
Thread.sleep(3000);
} catch (IOException e) {
e.printStackTrace();
}
}
The bat file launches the java compiler to compile another java file and direct the error messages into a txt file. This is what the bat file looks like:
#echo off
javac -Xstdout error.txt MainApp.java
exit
Now the problem is, that I have to include a 3 second sleep, in order to be sure, that the error.txt has been created and filled with errors. This is very unsatisfying. I'd either need a return value from the bat file, so I the rest of the program waits, until it's done or a way to launch the java compiler out of the program and direct the error messages into a txt file.
Thanks everybody.
You can use Process#waitFor:
Causes the current thread to wait, if necessary, until the process
represented by this Process object has terminated
Process p = Runtime.getRuntime().exec("cmd /c start build.bat");
p.waitFor();
I tried out a simple program to execute Linux command at run time. But the following program gets compiled and runs without any error, but the text file is not getting created as intended.Is there anything wrong in this program?
import java.io.*;
class ExecuteJava
{
public static void main(String args[])
{
String historycmd = "cat ~/.bash_history >> Documents/history.txt";
try
{
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec(historycmd);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
Try accessing some of the functions Process provides. I'd start with exitValue. Typically a -1 indicates something went wrong while a 0 means nothing especially bad happened.
Also try InputStream and Error Stream, and read them fully. See if either has useful feedback for you.
Other than that, try what andy256 suggests in comments. Ensure the Documents directory exists in the executing directory of the program.
The append operator >> is meant to be interpreted as part of the command shell. Use
String[] historycmd =
{ "bash", "-c", "cat ~/.bash_history >> Documents/history.txt"};
My problem is when to call jar file using
Runtime.getRuntime().exec() method, my .jar is not executing and showing its output
Coding is like that
public static void main(String[] args) {
String execJar = "java -jar C:\test.jar";
try {
Process p = Runtime.getRuntime().exec(execJar);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
When I used this "java -jar C:\test.jar" in command prompt, my .jar is not executing thus not showing System.out output.
Does anybody know how I can make this work?
Thanks.
ProcessBuilder pb = new ProcessBuilder("java", "-Xmx1024m", "-Xms1024m",
"-DTOOLS_DIR=C://", "-Daoi=whole",
"-jar", "C://calc.jar");
try {
pb.start();
} catch (IOException ex) {
System.out.print("EEE"+ex);
}
This is easy to follow as it has simple paths so you can try it and let it run easily
When you execute a process from within Java, it will have it's own standard out and standard error streams in that particular process. To access those, you have to get the corresponding streams from the Process object you have created.
p.getOutputStream(); // System.out
p.getErrorStream(); // System.err
Where do you expect the System.out to go ?.
When the process is spawned, the input/output and error streams are opened between the spawning and spawned process. You should consume the input and error (these represent the process output, despite the confusing name), otherwise your spawned process will block, waiting for the streams' contents to be consumed.
See this answer for more info.
ProcessBuilder pb = new ProcessBuilder("java", "-Xmx1024m", "-Xms1024m",
"-DTOOLS_DIR=F://Net Beans Work Space//calc//dist", "-Daoi=whole",
"-jar", "F://Net Beans Work Space//calc//dist//calc.jar");
pb.start();
Use this code it will surely run your jar file what you have to change is the paths in above code please reply it will work for you I will be thankful for you kind reply