Reputation: 4217
I've spent the past 3 days without much luck on google on how to run a grep process from within Java.
I have the following code to run a grep process, however, I am only getting the first line of the response.
package com.example.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) {
try {
Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/").start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("Exit Code: " + process.exitValue());
} catch (IOException e) {
e.printStackTrace();
}
}
}
I am only getting the following response:
Binary file /home/user/dev/java/Parser/parser/bin/com/example/parser/Main.class matches
Exit Code: 0
When I should be getting the following response:
Binary file /home/user/dev/java/Parser/parser/com/example/parser/Main.class matches
/home/user/dev/java/Parser/parser/src/com/example/parser/Main.java:10: public static void main(String[] args) {
/home/user/dev/java/Parser/parser/src/com/example/parser/Main.java:12: Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start();
Exit Code: 0
I am wondering why I only get output for the first finding? Is grep forking several processes to run the search and I'm only getting a handle on the first one?
I have also tried running the process from a Thread:
package com.example.parser;
public class Main {
public static void main(String[] args) {
try {
Analyzer analyzer = new Analyzer();
analyzer.start();
analyzer.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.example.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Analyzer extends Thread {
public Analyzer() {
}
@Override
public void run() {
try {
Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start();
process.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while((line = br.readLine()) != null) {
System.out.println(line);
}
System.out.println("Exit Code: " + process.exitValue());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
As well as the following:
package com.example.parser;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/Parser/parser").start();
process.waitFor();
Analyzer analyzer_is = new Analyzer(process.getInputStream());
Analyzer analyzer_es = new Analyzer(process.getErrorStream());
analyzer_is.start();
analyzer_es.start();
analyzer_is.join();
analyzer_es.join();
System.out.println("Exit Code: " + process.exitValue());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.example.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Analyzer extends Thread {
InputStream is = null;
public Analyzer(InputStream is) {
this.is = is;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(this.is));
String line = "";
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
As suggested by the following article: http://www.javaworld.com/jw-12-2000/jw-1229-traps.html
Upvotes: 4
Views: 9358
Reputation: 401
Have a look at this project for grep in java https://code.google.com/p/grep4j
Upvotes: 0
Reputation: 4217
I was able to solve the issue by launching a shell with the -c flag. The following code does what I had originally intended:
package com.example.parser;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
try {
List<String> commands = new ArrayList<String>();
commands.add("/bin/sh");
commands.add("-c");
commands.add("grep -rni --include \"*.java\" \"public static void main(\" /home/user/dev/java/Parser/parser");
Process process = new ProcessBuilder(commands).start();
Analyzer analyzer_is = new Analyzer(process.getInputStream());
Analyzer analyzer_es = new Analyzer(process.getErrorStream());
analyzer_is.start();
analyzer_es.start();
process.waitFor();
analyzer_is.join();
analyzer_es.join();
System.out.println("Exit Code: " + process.exitValue());
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.example.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Analyzer extends Thread {
InputStream is = null;
public Analyzer(InputStream is) {
this.is = is;
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(this.is));
String line = "";
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Upvotes: 2
Reputation: 382170
This is probably because you don't wait for the grep to finish.
Use the waitFor method :
Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", "/home/user/dev/java/").start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
process.waitFor();
String line = "";
while((line = br.readLine()) != null) {
System.out.println(line);
}
Note that you may also read the output (mainly to get what happens) while it is being processed using
Process process = new ProcessBuilder("grep", "-rni", "\"public static void main(\"", String line;
while (true) {
line = reader.readLine(); // add IO exception catching
if (line != null) {
System.out.println(line);
} else {
Thread.sleep(DELAY); // DELAY could be 100 (ms) for example
}
}
I suppose you're sure a grep launched by the owner of the java program is more than one line long ?
Upvotes: 1
Reputation: 1073
The other reason could be your process is still running but your Java program just exited.
Use the process.waitFor(); and Read your input stream in a thread.
Start the process. Lunch a thread with the process input stream as the input. Now wait for the process to exit by using process.waitFor();
This might help!
Upvotes: 0