I\'m using a java library (jar file). The author of the file put in a bunch of System.out.print
and System.out.println
s. Is there any way to hide these
Solution of your question is here.. in method SysOutController.ignoreSysout();
Change original PrintStream with a Dummy one which does nothing on it's write()
method.
Don't forget to replace original PrintStream when you finished.
System.out.println("NOW YOU CAN SEE ME");
PrintStream originalStream = System.out;
PrintStream dummyStream = new PrintStream(new OutputStream(){
public void write(int b) {
// NO-OP
}
});
System.setOut(dummyStream);
System.out.println("NOW YOU CAN NOT");
System.setOut(originalStream);
System.out.println("NOW YOU CAN SEE ME AGAIN");
System.setOut();
is probably what you're looking for
System.setOut(new PrintStream(new OutputStream() {
public void write(int b) {
// NO-OP
}
}));
Source
There are two ways I can think of doing this other than what has been previously posted:
1. Use a Java decompiler and remove each System.out
call and recompile the jar. I would reccommend this one if you choose this route.
2. You can use the stack trace to find the calling type. (From How do I find the caller of a method using stacktrace or reflection?)
List<String> classNames = ...
final PrintStream originalOut = System.out;
PrintStream filterStream = new PrintStream(new OutputStream() {
public void write(int b) {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
if(!classNames.contains(stackTraceElements[someNumber].getClassName()){
originalOut.write(b);
}
}
});
System.setOut(filterStream);
Where classNames
is the fully qualified name of every class in the jar file and someNumber
is the correct place in the stack you need to be looking at (probably 1 or 2).
/e1
After some testing I believe the number you will need for someNumber
is either 10 or 11. This is because System.out.print
does not directly call the write
method.
Example stack trace for writing h
:
(Stack traces are in index, getClassName
, getFileName
, getMethodName
order).
0 java.lang.Thread null getStackTrace
1 reflection.StackTrace$1 StackTrace.java write
2 java.io.OutputStream null write
3 java.io.PrintStream null write
4 sun.nio.cs.StreamEncoder null writeBytes
5 sun.nio.cs.StreamEncoder null implFlushBuffer
6 sun.nio.cs.StreamEncoder null flushBuffer
7 java.io.OutputStreamWriter null flushBuffer
8 java.io.PrintStream null write
9 java.io.PrintStream null print
10 java.io.PrintStream null println
11 reflection.StackTrace StackTrace.java main
Example stack trace for writing \n
:
0 java.lang.Thread null getStackTrace
1 reflection.StackTrace$1 StackTrace.java write
2 java.io.OutputStream null write
3 java.io.PrintStream null write
4 sun.nio.cs.StreamEncoder null writeBytes
5 sun.nio.cs.StreamEncoder null implFlushBuffer
6 sun.nio.cs.StreamEncoder null flushBuffer
7 java.io.OutputStreamWriter null flushBuffer
8 java.io.PrintStream null newLine
9 java.io.PrintStream null println
10 reflection.StackTrace StackTrace.java main
reflection.StackTrace
is the main class I'm using to do the test. reflection.StackTrace$1
is my filterStream
and I'm calling System.out.println
from the main
method in reflection.StackTrace
.
/e2
This 11 or 10 discrepancy appears to be because println
calls print
and newLine
. print
goes on to call write
while newLine
directly writes the new line character to the stream. But this shouldn't matter since the jar will not contain java.io.PrintStream
.
If you have a bigger programm consider something like
public abstract class Output {
private static final PrintStream out = System.out;
private static final PrintStream dummy = new PrintStream(new OutputStream() {@Override public void write(int b){} });
private static boolean globalOutputOn = true;
public static void toggleOutput() {
System.setOut((globalOutputOn=!globalOutputOn)?dummy:out);
}
public static void toggleOutput(boolean on) {
globalOutputOn = on;
System.setOut(on?out:dummy);
}
}
This gurantees that you can toggle output on and off in different classes, while beeing guranteed to be able to turn the output on later.
You for example use it by calling
toggleOutput(false)
at the start of each method and
toggleOutput(true)
at the end of each method.