In a plain Java application, this code:
System.out.println(System.getProperty("java.version"));
System.out.println(System.getProperty("java.vendor"));
System.out.printf("XXXX %s YYY\n","Something");
System.out.printf("XXXX %s YYY\n","");
System.out.printf("XXXX %d YYY\n",123);
System.out.printf("XXXX %3.3f YYY \n",123.456);
Gives this, as expected:
1.8.0_131
Oracle Corporation
XXXX Something YYY
XXXX YYY
XXXX 123 YYY
XXXX 123.456 YYY
The very same code, as part of a server app, produces this:
1.8.0_131
Oracle Corporation
XXXX
Something
YYY
XXXX
YYY
XXXX
123
YYY
XXXX
123.456
YYY
In addition, if I remove the XXX/YYY decorations, the output is normal, (except that the line for the null string is not printed at all).
The systems is Ubuntu 16.04, and the server is an IBM WAS Liberty 16.0.0.4, which is really using the OpenJDK runtime above (/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java). Now, grep'ing the Liberty jars I see a org.owasp.esapi.waf.internal.InterceptingPrintWriter.class
, could that be a culprit?
I may be missing something completely obvious or something is done to the PrintStream but I can't see any settings for this.
And yes, I'm going to change the code to use a proper logging framework, so the question is quite academic anyway. Still I'm curious...
With a colleague's help we tested on Windows (with Java 1.8.0_121):
- With a Liberty server: same problem
- With a Tomcat V7 server: no problem
So the problem would be in the server runtime.
Well, dumping the class hierarchy of System.out:
in a regular app:
java.io.PrintStream java.io.FilterOutputStream java.io.OutputStream java.lang.Object
in the Liberty server:
com.ibm.ws.logging.internal.impl.BaseTraceService.TeePrintStream java.io.PrintStream java.io.FilterOutputStream java.io.OutputStream java.lang.Object
So, I think I have the beginning of an explanation.