3

I am running a java program which throws an exception. I am piping the run's output to a grep command where I am checking for a pattern which does not exist, however grep keeps returning a match.

0,2,468.000000
1,2,305.000000
2,5,2702.000000
3,3,1672.000000
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at TestConverter.processPayments(TestConverter.java:113)
    at TestConverter.processFile(TestConverter.java:131)
    at TestConverter.main(TestConverter.java:142)

I am running the following command:

java -classpath TestConverter.jar TestConverter test_xml.xml | grep "stringthatdoesnotmatch*"

I get the following output:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at TestConverter.processPayments(TestConverter.java:113)
    at TestConverter.processFile(TestConverter.java:131)
    at TestConverter.main(TestConverter.java:142)

I am not sure why this is happening. Furthermore, my end goal is to check if the output contains the following pattern:

*java.lang.IndexOutOfBoundsException*ArrayList.java:653*TestConverter.java:142*
sophist_pt
  • 329
  • 1
  • 8
  • 19
  • 1
    Are you sure the exception output isn't going to stderr instead of stdout? – Stephen Newell Apr 08 '18 at 04:25
  • 1
    Try piping STDERR to grep, too: `java -classpath TestConverter.jar TestConverter test_xml.xml |& grep "stringthatdoesnotmatch*"` – zwer Apr 08 '18 at 04:28
  • @StephenNewell Not sure where it is going. But I feel like it may be going to stderr. How can I grep stderr? – sophist_pt Apr 08 '18 at 04:29
  • @zwer I tried that and got a ```-bash: syntax error near unexpected token `&'``` – sophist_pt Apr 08 '18 at 04:30
  • @sophist_pt - That's weird, bash should recognize the `|&` shorthand. Either way, try: `java -classpath TestConverter.jar TestConverter test_xml.xml 2>&1 | grep "stringthatdoesnotmatch*"` – zwer Apr 08 '18 at 04:32
  • @zwer That seems to be working, however I am now trying to make sure that grep checks for a match that guarantees it contains ```*java.lang.IndexOutOfBoundsException*ArrayList.java:653*TestConverter.java:142*``` Do you know how I can achieve this? – sophist_pt Apr 08 '18 at 04:38
  • @sophist_pt - `grep` works on line-by-line basis by default. There are several approaches that you can use for multiline matches, check answers to [this question](https://stackoverflow.com/q/152708) – zwer Apr 08 '18 at 04:45
  • @zwer Thanks for the help. I piped the output to xargs and did the grep and it seems to be working. – sophist_pt Apr 08 '18 at 04:58

1 Answers1

2

You're actually not getting a match. What you have to understand is the difference between standard output and standard error.

The Java program is writing its normal output to the former and exceptions to the latter, but both those streams are initially attached to your terminal device.

So, when you add a pipeline:

program | grep xyzzy

the | character will divert the standard output of program to the standard input of grep. That will then filter out any lines not containing xyzzy, and pass the rest to its standard output, the terminal in this case.

The standard error of program is still connected directly to the terminal so will appear there regardless of what grep does.

If you want the grep program to capture both output and error of `program, combine them first:

program 2>&1 | grep xyzzy

That 2>&1 means take what was destined for stream 2 (standard error) and instead send it to stream 1 (standard output). Then the | can take all of the output/error coming from program.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953