why cant I use log files in java runtime - java

I have (in java),
rt.exec("qq.exe -i ..(some other parameters) > qq.log");//*1
when I run qq.exe -i ..(some other parameters) > qq.log in terminal It works fine and keeps the qq.log file correctly.
However using rt.exec (*1) doesnt work. " > qq.log" part causes problem. When I delete that part rt.exec (*1) works but I cant have qq.log file this time.
What causes this problem and Is there any soln??

rt.exec() can't execute sh/bat code. It's just invoking another program. When you try to redirect the output stream of qq.exe with the > symbol, which is specific to shell, java doesn't understand what to do.
An alternative is when you execute some program with the exec method, get the Process returned by rt.exec().
A Process can give you an OutputStream to the application, an InputStream from the application and even an ErrorStream for a started application.
With the InputStream, you can programmatically read the result of qq.exe and all you have to do is to write this into a file.

Java 7 added ProcesBuilder.Redirect class that allows to redirect input/output/error streams to/from files. It can be used like this:
ProcessBuilder builder = new ProcessBuilder("cat", "/proc/meminfo");
// Append all errors from process to log file:
builder.redirectError(Redirect.appendTo(new File("/tmp/my.log")));
Process process = builder.start();
Using corresponding methods you can redirect input and output. The full example is here: Run external process in Java 7.

Related

Getting too many arguments error while executing tr command from java

file = D:\Unix\tr.exe "Æ" "~" < "C:\SourceFiles\source.csv" > "D:\tgt"
When i execute this command using the below code in java
Process process = Runtime.getRuntime().exec(file);
am getting the following error
D:\Unix\tr.exe: too many arguments
PS : File contains Æ characters am trying to replace all those characters with ~
Any suggestions please ?
You're passing unicode in the CMD, I guess that causes the problem.
Set chcp xxx on the CMD and try.
refer below link for chcp codes
https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/chcp.mspx?mfr=true
You have to program the io redirection yourself. This is usually the bash that takes care of it.
The result of the exec() call is a process. This process can then be used to get the STDIN of the process. Send the data to that process using that stream.
The way you call it, you send another command line option to tr, which is the < and > redirectors and the filenames.
Process process = System.getRuntime().exec(strBatchFileName);
OutputStream stdin = process.getOutputStream();
sendFileToStream(out);
InputStream stdout = process.getInputStream();
loadResultFromStream(stdout);
This is a pseudocode example, where sendFileToStream(...) feeds the input file into the TR process, and the loadResultFromStream(...) will load the result.
You may need to utilize threads to feed and read if the data is larger than the stream's buffer.
The question is kind of a duplicate and you will find a ProcessBuilder example here: Runtime's exec() method is not redirecting the output

Trying to execute a Java jar with Runtime.getRuntime().exec()

In the project I am working on, I need to execute a script that I have in a resources folder -- in the class path. I am simply testing the final script functionality, since I am on Windows, I needed a way to output a file to STDIN so I created a simple cat.jar program to clone unixs cat command.
So when I do "java -jar cat.jar someFile.txt" it will output the file to stdout. I'm sure there are different ways of doing what I did.
Anyways,
I want to run that JAR from my main java program.
I am doing
Runtime.getRuntime().exec("java -jar C:/cat.jar C:/test.txt");
I've tried switching the forward slash to a backward slash and escaping it -- didn't work.
Nothing is getting sent to standard out.
Where as, if I run the cat jar on its own, I get the file directed to standard out.
What am I doing wrong here?
Is this enough information?
Use the Process instance returned by exec()
Process cat = Runtime.getRuntime().exec("java -jar C:/cat.jar C:/test.txt");
BufferedInputStream catOutput= new BufferedInputStream(cat.getInputStream());
int read = 0;
byte[] output = new byte[1024];
while ((read = catOutput.read(output)) != -1) {
System.out.println(output[read]);
}
References:
http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html
By default, the created subprocess does not have its own terminal or console. All its standard I/O (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().
http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html#getInputStream()
getInputStream() returns the input stream connected to the normal output of the subprocess.

How to invoke a CMD file in JAVA correctly on windows?

I have sample java code like below.
String testEfdDirectoryPath="D:\\test";
String efdExecutable = "test.cmd";
File executableFile = new File(testEfdDirectoryPath, efdExecutable);
ProcessBuilder pb=new ProcessBuilder();
$$pb.command("cmd.exe","/C",executableFile.toString());$$
pb.directory(new File(testEfdDirectoryPath));
Process p=pb.start();
int code=p.waitFor();
System.out.print(code);
In test.cmd there is actually a call to another java application. Unless I change the $$ marked line to the following to redirect its output, the another java app cannot be launched.
pb.command("cmd.exe","/C",executableFile.toString(),">output.txt");
Do you guys have any ideas? Thanks in advance. :)
Does your child process produce a lot of output (more than a few kilobytes)? If that is the case, you need to read that output from the process. You should try:
start the process
close the stdin of the process, so pb.getOutputStream().close()
repeatedly read from pb.getInputStream() and the error stream
This may be possible in one thread, or in multiple threads. Anyway, you should just take the explanation above as a list of keywords and try to search for an example code snippet that you can trust, preferrably from an Open Source application that does such a thing successfully.
Maybe http://commons.apache.org/exec/ can help you.
Windows cannot execute scripts directly; when you double click on a .cmd file it actually opens the file in cmd.exe. So try cmd.exe E:\\test\\test.cmd.

shell script to redirect the output

I am looking for a help regarding a shell script to redirect the output of a command to a file. I have a C program that reads the input from a serial port and display. I want this data to be redirected to a file. I am executing this from a java program by calling
Runtime r = Runtime.getRuntime();
Process procObj = r.exec("sh " + scriptfile);
I have tried writing the script file as
./program >> file.txt
The file.txt is not getting updated. Here, the program doesn't end until the connection to the port is lost, in a sense it is infinitely running. So my program keeps looking for data on the port and display as and when it is there.
I just need to redirect the same output to a file that I would use as a log.
I looked at How to make shell output redirect (>) write while script is still running? but not helpful.
Kindly help..
How much output does program generate? Using standard IO redirection will add a 4KB buffer between stdout and file. This means your program must output more than 4KB of data before the OS starts to write to the file.
To fix this, add stdout.flush() to your program when a "work unit" is complete (maybe a line but might be more than one line).
Can you try ./program >> file.txt 2>>file.txt, or ./program 2>&1 >>file.txt?
just try this
List<String> cmd = new ArrayList<String>();
cmd.add("sh");
cmd.add("-c");
cmd.add("program 1> file.txt 2>&1");
ProcessBuilder pb = new ProcessBuilder(cmd);
Process p = pb.start();
If you use standard C calls for output (printf, puts etc.), your output may get buffered. On C89 and onwards, it depends on the buffering mode (unbuffered, fully buffered, line buffered) and on the size of the buffer, whether your output is buffered at all and when the buffer is flushed (see http://www.gnu.org/software/libc/manual/html_node/Buffering-Concepts.html and man setvbuf).
By default, output to a file is fully buffered on Linux. If you want the output to appear immediately in the output file, you may:
use fflush() after each output operation
use the system call write() (man 2 write)
switch off buffering: setvbuf(stdout, NULL, _IONBF, 0); (https://stackoverflow.com/a/7876756/601203)
This behaviour is not related on the fact the you start your C program in a Java program via a shell script. This behaviour depends on the standard C library that you have linked into your program.

take time to execute .bat file through java?

i have written a code to run .dat file using Java. but when is run that application then it take time to execute means it give half result and then after some time after gives complete result.
here is my code:
String file = config.getOutPath() + "run_doxygen.bat";
BufferedWriter out = new BufferedWriter(
new FileWriter(file));
String cmd = "doxygen " + config.getOutPath() + "Doxyfile";
runtime.exec(cmd);
System.out.println("cmd_doxy:"+cmd);
out.write(cmd);
out.newLine();
out.close();
the doxygen generate xml file. let suppose it generate 10 xml file . when i launch that *.bat file it generate 5 file and to generate rest 5 file it take time.
and *.bat file contain : doxygen "path"
path is location of config file. it work fine when i run it with cmd or double click.
anybody have any idea
.
thanks
May be you should flush the writer.
out.newLine();
out.flush();
out.close();
It is not entirely clear what you intend your program to do, but what it is actually is doing is as follows:
It opens the ".bat" file for writing.
It launches a "doxygen" command as a separate external process.
It writes the command to standard output, and then the file.
If you are saying that it takes some time for the output to be written to the file, well that is not entirely unexpected. The operating system may decide to give the newly launched doxygen application a big chunk of CPU time to get started. If it doesn't block, your Java application may not get a time-slice for a few seconds. And after that, the OS may switch between the two applications until one or the other finishes.
But why does it matter? Does your Java application expect / require doxygen to finish before it does?
If so, then the solution is to do something like this:
Process proc = runtime.exec(cmd);
// do more stuff.
int rc = proc.waitFor();
// Whoopee! the process has finished (or died) check the rc to see which.
if you are not consuming the streams generated by the external command, it can cause the program to hang. See this article which pretty much covers all the gotchas of using Runtime.exec.

Categories