Hiding System.out.print calls of a class

前端 未结 5 1410
别那么骄傲
别那么骄傲 2021-02-02 13:16

I\'m using a java library (jar file). The author of the file put in a bunch of System.out.print and System.out.printlns. Is there any way to hide these

5条回答
  •  清歌不尽
    2021-02-02 13:46

    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 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.

提交回复
热议问题