I am using an external library. When a call a method of this library then it outputs some text on console. I want to hide this text from console. How is it possible?
Thanks in Advance
You can redefine system.out (I believe it is System.setOut()) I believe you can set it to NULL (Corrected--you can NOT set it to NULL), but you can set it to ANY output stream.
I did something interesting with this once. I saved "System.out" then redirected it to my own output stream with code in the "print" method--that method is called whenever anyone prints to the stream.
Every time a line of input came in to this class, I'd create a stack trace, grab the trace and dig down to the method that called the System.out.println() method. At this point I could prepend the line and have instant logger functionality--it even shows the line number.
This was probably quite slow but it could be turned on and off very easily.
I could also do all the filtering you'd like without touching the source code. Sometimes I'd filter on a single package, sometimes I'd filter on a class and sometimes it would be strings starting with "BK:" which would only print out my messages.
Overall it was a lot of fun and trivial to remove ALL debug output for production.
(I do not recommend the get stack trace thing for production code, it really should be quite slow even though I didn't notice it)
// class variable
public static final OutputStream out;
{
out=System.getOutputStream();// I may have the actual name wrong, but it's close
System.setOutputStream(new OutputStreamThatDoesNothing());
}
at this point any calls to:
Redirect.out("Hello");
Should act just as calls to System.out did.
Since there is no magic with this, you can also do something like this if you really want to:
OutputStream tmp=System.getOutputStream();
System.setOutpuatStream(nullStream);
callOffensiveLibraryMethod();
System.setOutputStream(tmp);
This would only eliminate output within that call BUT would be Very Bad if your application was multi-threaded.
private PrintStream realSystemOut = System.out;
private static class NullOutputStream extends OutputStream {
#Override
public void write(int b){
return;
}
#Override
public void write(byte[] b){
return;
}
#Override
public void write(byte[] b, int off, int len){
return;
}
public NullOutputStream(){
}
}
void someMethod(){
System.setOut(new PrintStream(new NullOutputStream());
realSystemOut.println("Hello World!"); //prints Hello World!
System.out.println("Hello World!"); //nothing!
System.setOut(realSystemOut);
System.out.println("Hello World!"); //prints Hello World!
}
For those looking for a 2020 version that also does not require external libraries for the null stream:
PrintStream out = System.out;
System.setOut(new PrintStream(OutputStream.nullOutputStream()));
//
//do stuff with library...
//
System.setOut(out);
Available since Java 11.
Set the System.out to a NullOutputStream. apacahe.commons has one available.
If you want to print it out accordingly you could write a fun hack.
private static final PrintStream SYSTEM_OUT = System.out();
public static void debug(String debug){
SYSTEM_OUT.println(debug);
}
Somehwere else in the code
System.setOut(new PrintStream(new NullOutputStream()));
Related
Basically, I wanted console to do 2 things:
I wanted console to color code errors and general info messages (which errors being red and everything else green).
I wanted to save all console messages to a log file.
So, I created a print stream that looked something like this:
public static class GeneralStream extends PrintStream {
public GeneralStream(OutputStream out) {
super(out);
}
#Override
public void println(String string) {
String time = DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now());
String output = "["+time+"] ["+type.n()+"] "+string;
Logs.logToFile(output);
String coloredOutput = ANSI_RESET+ANSI_WHITE+"["+ANSI_CYAN+time+ANSI_WHITE+"] "+
ANSI_WHITE+"["+ANSI_RESET+type.c()+type.n()+ANSI_WHITE+"] "+type.c()+string+ANSI_RESET;
super.println(coloredOutput);
}
}
Great. Then I set this print stream at the start of my program as the default PrintStream using:
// Set console output settings
System.setOut(new Console.GeneralStream(System.out));
System.setErr(new Console.GeneraStream(System.err));
Awesome. Finally, upon doing System.out.println("Hello World"), I get the result I expected. My messages are colored. They are logged to a file. Great! In fact even if I do System.err.println("Error!"), I still get a result as expected. However, "automatic" exceptions do not print through the System.err that I set.
Here is an example:
// Set console output settings
System.setOut(new Console.GeneralStream(System.out));
System.setErr(new Console.ErrorStream(System.err));
System.out.println("Hello world!");
System.err.println("Printing an error!");
// Real exception (NPE)
Integer nullInteger = null;
System.out.println(nullInteger.toString()); // won't print and will produce a NullPointException
Here is the result:
As you can see, my System.out and System.err print fine but as soon as there is a real exception, it prints regularly.
So my question is how can I set a custom PrintStream for errors like this so they are logged to a file (and preferably follow my custom message formating).
If you dig into how the Throwable class prints the stack trace, you'll see it uses the println(Object) method, so you'll need to add this method to your custom ErrorStream class:
#Override
public void println(Object object) {
println(String.valueOf(object));
}
Even then, you may want to change the "uncaught exception handler" to change how it logs exceptions. It seems that the default handler calls first System.err.print to output Exception in thread "{ThreadName}" followed by Throwable.printStackTrace, so you end up with the time stamp and other stuff in the middle of the message. For example:
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
System.err.println("Uncaught exception in thread " + thread.getName());
throwable.printStackTrace(System.err);
});
This question already has answers here:
JUnit test for System.out.println()
(14 answers)
Closed 6 years ago.
I have written a method that is printing output to a console. How should I test it?
public class PrinterForConsole implements Printer<Item>{
public void printResult(List<Item> items) {
for (Item item: items){
System.out.println("Name: " + item.getName());
System.out.println("Number: " + item.getNumber());
}
}
}
currently, my test looks like this
public class TestPrinter{
#Test
public void printResultTest() throws Exception {
(am figuring out what to put here)
}
}
I have read the solution at this post (thanks #Codebender and #KDM for highlighting this) but don't quite understand it. How does the solution there test the print(List items) method? Hence, asking it afresh here.
Since you have put you don't get what the duplicate question says, I will try to explain a little.
When you do, System.setOut(OutputStream), whatever the application writes to the console (using System.out.printX()) statements, instead get written to the outputStream you pass.
So, you can do something like,
public void printTest() throws Exception {
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
System.setOut(new PrintStream(outContent));
// After this all System.out.println() statements will come to outContent stream.
// So, you can normally call,
print(items); // I will assume items is already initialized properly.
//Now you have to validate the output. Let's say items had 1 element.
// With name as FirstElement and number as 1.
String expectedOutput = "Name: FirstElement\nNumber: 1" // Notice the \n for new line.
// Do the actual assertion.
assertEquals(expectedOutput, outContent.toString());
}
The best way to test it is by refactoring it to accept a PrintStream as a parameter and you can pass another PrintStream constructed out of ByteArrayOutputStream and check what is printed into the baos.
Otherwise, you can use System.setOut to set your standard output to another stream. You can verify what is written into it after the method returns.
A simplified version with comments is below:
#Test
public void printTest() throws Exception {
// Create our test list of items
ArrayList<Item> items = new ArrayList<Item>();
items.add(new Item("KDM", 1810));
items.add(new Item("Roy", 2010));
// Keep current System.out with us
PrintStream oldOut = System.out;
// Create a ByteArrayOutputStream so that we can get the output
// from the call to print
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Change System.out to point out to our stream
System.setOut(new PrintStream(baos));
print(items);
// Reset the System.out
System.setOut(oldOut);
// Our baos has the content from the print statement
String output = new String(baos.toByteArray());
// Add some assertions out output
assertTrue(output.contains("Name: KDM"));
assertTrue(output.contains("Name: Roy"));
System.out.println(output);
}
Note that if the print method throws an exception, the System.out is not reset. It is better to use setup and teardown methods to set and reset this.
How about something like this.
#Test
public void printTest() throws Exception {
OutputStream os = new ByteArrayOutputStream();
System.setOut(os);
objectInTest.print(items);
String actualOutput = os.toString("UTF-8");
assertEquals(expectedOutput, actualOutput);
}
This is the Simple Test Code :-
#Test
public void out() {
System.out.print("hello");
assertEquals("helloworld", outContent.toString());
}
#Test
public void err() {
System.err.print("helloworld 1 ");
assertEquals("helloworld 1", errContent.toString());
}
For more :JUnit test for System.out.println()
Eventually, what I came up with is this (after going through all the answers and links to possible duplicates above).
import org.junit.Test;
#Test
public void shouldPrintToConsole() throws Exception {
Item testItem = new Item("Name", "Number");
List<Item> items = Arrays.asList(testItem);
Printer print = new Printer();
printer.printOutput(items);
}
Read up on naming convention (shouldPrintToConsole()) for testing too. Wondering if this is the convention because I see many sites that follow and many that don't.
static void goOut(String in) {
//instance variables
String fileCopy = currentLine + in;
try {
FileWriter writer = new FileWriter(output,true);
writer.write(line1 + System.getProperty("line.separator", "\r\n"));
writer.write(fileCopy + System.getProperty("line.separator", "\r\n"));
} catch(IOException ex) {
ex.printStackTrace();
}
}
Edited code to the correct standard as pointed out by other users.
of course because thats what you r telling it to do. every time is called it writes both x and the number. a quick fix: you can keep a flag if it is the first run set it flag = true. and check within ur method, sth like this:
public class YourClass{
private boolean didRun = false;
static void goOut(String in) {
...... init ur file and writer
if(!didRun)
writer.write(Y);
writer.write(in);
writer.close();
didRun = true;
}
}
I dont know the rest of the code but i think thats what u need
I believe you want to separate the jobs the "goOut" is responsible for.
You should make "goOut" only write the numbers (in your example).
The writing of the y's (in your example) should not be apart of the method and called once, at the start of writing to the file.
Also, #Jon Skeet is right about the multiple FileWriters. Use one, since its the same file.
Agree, sounds like a disaster.
When you use multiple writers to access the file, I would expect to get unpredictable results.
I dont think there is any guarantee that FileWriter1 would complete the task before FileWriter2.
In addition, the method is not synchronized.
I was searching java source code that prints the System.out.println() parameter values on the console. I checked PrintStream, FilterOutputStream and OutputStream classes, none of them have complete implementation of the method nor any reference to native code.
How does the System.out.println value getting printed on the console, which native method is doing the actual job ?
You have to drill down through the decorator-pattern wrappers. At the bottom you'll find FileOutputStream, specifically this method:
private native void writeBytes(byte b[], int off, int len) throws IOException;
Use this code to play with it:
public static void main(String[] args) throws Exception {
nav(nav(System.out));
}
static Object nav(Object o) throws Exception {
final Field[] fs = o.getClass().getSuperclass().getDeclaredFields();
for (Field f : fs) {
f.setAccessible(true);
final Object r = f.get(o);
System.out.println(r);
return r;
}
return null;
}
public static final PrintStream out
The "standard" output stream. This stream is already open and ready to accept output data. Typically this stream corresponds to display output or another output destination specified by the host environment or user.
For simple stand-alone Java applications, a typical way to write a line of output data is:
System.out.println(data)
where:
void println(String x)
Prints a String and then terminates the line.
Alright I am very new to Java and am trying to develop an application to teach myself how to use the language.
I have been copying and pasting the same few lines of code all over, and I know that there is a way to consolidate this into a function, but cannot quite figure it out.
FileOutputStream fout4 = openFileOutput("building1hourly.txt", MODE_WORLD_READABLE);
OutputStreamWriter osw4 = new OutputStreamWriter(fout4);
osw4.write("" +iHourlyAfter);
osw4.flush();
osw4.close();
Now isn't there some type of way I could do something like this
public void writerFunction("What to write to file", "name stream", "name writer", "MODE"){insert above code here}
Yes absolutely:
public void writeToFile(String fileName, String contents, int mode) throws IOException {
FileOutputStream fout = openFileOutput(fileName, mode);
OutputStreamWriter osw = new OutputStreamWriter(fout);
osw.write(contents);
osw.flush();
osw.close();
}
First of all, great job so far. Learning programming is just like learning math (except more fun), you can read about it all you want in a book, but you don't really understand concepts until you DO them. You're going about this the right way.
Now, to answer your question: Yes, you can encapsulate the process of writing to a file in a function. Let's call it writeToFile. You want to "call" this function by sending it arguments. The arguments are the information that the function needs to do its work.
There are two sides to a function: the declaration, and the invocation. Just like in math, you can define a function f(x), where f does something. For example: say I have the function f(x) = 2x - 4. That equation is what we call the function declaration, in that we are defining what f does, and you are defining the parameters that it accepts, namely a single value x. Then you want to apply that function on a certain value x, so you might do something like: f(4). This is the function invocation. You are invoking, or calling the function, and sending 4 as the argument. The code that invokes a function is called the caller.
Let's start with the declaration of the function that you want to build:
public void writeToFile (String data, String fileName)
This function defines two parameters in its signature; it expects a String containing the data you will write to the file, and the fileName to which we will write the data. The void means that this function does not return any data back to the caller.
The complete function, the body of which you provided in your post:
public void writeToFile (String data, String fileName){
FileOutputStream fout4 = openFileOutput(fileName, MODE_WORLD_READABLE);
OutputStreamWriter osw4 = new OutputStreamWriter(fout4);
osw4.write("" +iHourlyAfter);
osw4.flush();
osw4.close();
}
Now you will want to call, or invoke this function from somewhere else in your code. You can do this like so:
writeToFile("stuff I want to write to a file", "myFile.txt");