We are the using the following code to generate PDFs using wkhtmltopdf
public class SystemUtils{
public String executeCommand(String... command) {
Process process = null;
try {
// Using redirectErrorStream as true. Otherwise we have to read both process.getInputStream() and
// process.getErrorStream() in order to not exhaust the stream buffer.
process = new ProcessBuilder(command).redirectErrorStream(true).start();
process.waitFor();
StringBuilder outputBuilder = new StringBuilder();
try(BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = stdError.readLine()) != null) {
outputBuilder.append(line).append(StringConstants.CARRIAGE_RETURN);
}
}
return outputBuilder.toString();
} catch (IOException | InterruptedException e) {
String exceptionMsg = "Error while executing command '"+command+"' : ";
LOGGER.error(exceptionMsg, e);
throw new AppException(exceptionMsg, e);
} finally {
if(process != null){
process.destroy();
}
}
}
public static void main(String[] args){
SystemUtils systemUtils = new SystemUtils();
String[] array = {"wkhtmltopdf", "/home/pgullapalli/Desktop/testsimilar1.html", "/home/pgullapalli/Desktop/test.pdf"};
systemUtils.executeCommand(array);
}
}
This works absolutely fine for smaller size files. But when we try to process a larger file, it is indefinitely waiting without any response. I am not sure what is going wrong? Can someone please suggest?
I moved process.waitFor() before the return statement and it started working. This probably could be happening as the output buffer has filled and we are not reading from it. After moving the process.waitFor after the stream reading, things are working fine.
Related
I'm accessing to running exe using below method. But I want to get the count of running exe files. Basically I want to get the count of exe process currently runs. Other than assigning all the process name to a list is there a simple way to obtain the count.
public boolean isProcessRunning(String serviceName) {
try {
Process pro = Runtime.getRuntime().exec(TASKLIST);
BufferedReader reader = new BufferedReader(new InputStreamReader(pro.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
// System.out.println(line);
if (line.startsWith(serviceName)) {
return true;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
I have the following method, which executes a command as a process and returns the ouput:
public String execute(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
} catch (Exception e) {
logger.error(e.getMessage());
}
return output.toString();
}
This code is great whenever the command returns, however for continuing running processes such as top this may never return. The code does not need to keep running continuously. It only needs to capture a snapshot, or it could time out after some time, such as 3 seconds. How can I accomplish that?
Process has a method waitFor. It can be used to force a timeout. For example:
if ((p = Runtime.getRuntime().exec(execPath)) != null) && !p.waitFor(TIMEOUT_CONSTANT, TimeUnit.SECONDS)) {
p.destroyForcibly();
}
I'm executing a system command on server which gives continuous output till it gets completed. Since it takes a long time to get completed, I want to sent the output from this system command to client in continuous fashion. Any suggestions on how should I do it.
Here is my snippet of code which executes the system command and has the input stream to read from.
I'm invoking this code form my servlet doPost.
Process process = pb.start();
final InputStream is = process.getInputStream();
final StringBuffer strBuff = new StringBuffer();
Thread inputStreamThread = new Thread(){
public void run() {
String line;
BufferedReader br = new BufferedReader(new InputStreamReader(is));
try {
while((line = br.readLine()) != null) {
strBuff.append(line + "\n");
}
} catch (IOException e) {
logger.error("IO Exception occured in inputStreamThread=> "+e);
}
}
};
inputStreamThread.start();
inputStreamThread.join();
int exitVal = process.waitFor();
I got a very strange problem. I am trying to read the result of a command I am executing. The code never reaches the println-Statement. It is just "hanging up" the program, if the end of the output is reached. No failure and no exception.
My project is a mix of Scala and Java. So it doesn't matter in which language the solution is. I tried in both. The encoding of my project is Cp1252.
Here is my code
var fileScript = Runtime.getRuntime().exec(PathOfScript)
var isr:InputStreamReader = new InputStreamReader(fileScript.getInputStream())
var in = new BufferedReader(isr)
var line:String = ""
try {
while ({line = in.readLine(); line!= null}) {
println("line: "+line)
}
println("OUTSIDE !!!");
in.close();
}
That's strange... my Java version works just fine:
InputStreamReader isr = new InputStreamReader(new FileInputStream("c:\\anyfile"));
BufferedReader in = new BufferedReader(isr);
String line = "";
try {
while ((line = in.readLine()) != null) {
System.out.println("line: "+line);
}
System.out.println("OUTSIDE !!!");
in.close();
} catch (Exception ex) {
ex.printStackTrace();
}
I think that the problem is in fileScript: if it gives a stream and doesn't close it, you'll never get a null in the while loop. Check that part. Try with a regular file (like I did in my example). If it works, the problem is surely in the fileScript object.
I call a class which is located somewhere in a jar file (using java -classpath path/file.jar classname) within my java code.
My problem is when the command genKOSCommand is invalid the call to input.readLine() will block the program. So I added input.ready() to hope avoiding blocking. When I debug the program it's ok. Seem to work. But when don't run it in debug the buffer is never ready.
// Execute a command with an argument that contains a space
String[] genKOSCommand = new String[] {
"java",
"-classpath",
Config.XDSI_TEST_KIT_HOME + "/xdsitest/lib/xdsitest.jar;"
+ Config.XDSI_TEST_KIT_HOME + "/xdsitest/classes",
"ca.etsmtl.ihe.xdsitest.docsource.SimplePublisher", "-k",
"C:/Softmedical/Viewer_Test/xdsi-testkit-2.0.4/xdsihome/usr/data/image14.dcm" };
Process child = Runtime.getRuntime().exec(genKOSCommand);
BufferedReader input = new BufferedReader(new InputStreamReader(
child.getInputStream()), 13107200);
String line = null;
if (input.ready()) {
while ((line = input.readLine()) != null) {
System.out.println(line);
}
try {
child.waitFor();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Any advice on how to detect problems with the executed command?
Thank you.
You need to wait in a loop for the BufferedReader to be ready.
while (input.ready() == false) { /* intentional empty space here */ }
while ((line = input.readLine()) != null) {
System.out.println(line);
}
/* rest of code follows */