ossys
ossys

Reputation: 4217

Running grep From Java Program

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

Answers (4)

marcocast
marcocast

Reputation: 401

Have a look at this project for grep in java https://code.google.com/p/grep4j

Upvotes: 0

ossys
ossys

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

Denys S&#233;guret
Denys S&#233;guret

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

muruga
muruga

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

Related Questions