PrintWriter and PrintStream never throw IOExceptions - java

Some days ago I realized that PrintWriter (as well as PrintStream) never throw an IOException when writing, flushing or closing.
Instead it sets an internal flag (trouble=true) when an error occurs.
It's not possible to get the exact exception, but only if there was some exception (checkError()).
My question is: why would one want to have such behavior? Isn't that bad API design?

I think that since System.out and System.err are instances of PrintStream, some more relaxed error handling was provided. This was probably, as other posters have mentioned, to smooth the way for those transitioning from C/C++ circa 1995. When the Reader/Writer API was added, PrintWriter was created to parallel the existing PrintStream.
One application where this behavior is extremely desirable is logging. Logging is ancillary to a larger application. Typically, if logging fails, one doesn't want that the entire application to fail. Thus, it makes sense for System.err, at least, to ignore exceptions.

I wonder if its because IOExceptions are checked, this would require you placing a try catch block around every System.out. call.
update: Or a throws in your method signature.
That would get annoying very quickly.

I don't really know the story, but I think it was to make Java easier for newer programmers who the designers wanted to be able to use simple stdio printing methods without the need to know what exceptions are. So in that regard it is good design (I agree with you somewhat though).

Sun / Oracle should have added two write-like functions, one that throws an IOException and another that doesn't throw anything.

It's possible that the design was done by someone coming from a C background where stdio errors are handled in a similar fashion. Since I'm used to that paradigm, I wouldn't call it bad, but I'd agree that it is inconsistent.
I also agree with the comment about trying to make PrintWriter easier to use. The IO classes in Java are confusing (at least for everyone I know) and perhaps someone was just trying to make life a little bit easier.

It is not a design error. It is a proper design meant to be used in a situation when you write an output and you want errors to be ignored.
As a typical use case, the System.out and System.err were already mentioned, but the reason is not relaxed handling for convenience or smooth C/C++ transitions . It is a desired handling of a situation like this:
you start an application in a console
it produces output to the std out/err
you close the console, but you want the application to continue in the background
In this situation, depending on the system implementation, it could happen that System.out or System.err would fail after the console is closed, but you don't want that to crash your application. The application is wanted to continue to run in the background and the output is meant to be scraped. That's what PrintWriter does.
If you care about errors during the output, use FileWriter or OutputStreamWriter.
If you need some of the methods available in PrintWriter and not available in FileWriter, create your own TextWriter extending FileWriter or OutputStreamWriter.

Related

Capture all thrown exceptions in java?

I doubt such a thing is possible, but without attaching a debugger to a java application, is it possible to have some collection populated with information about every exception that is generated in a java application, regardless of if it is caught or not? I know that in .NET, messages get generated by the application about exceptions which at that point are called "First Chance Exceptions", which may or may not subsequently be handled by the application. I'm wondering if there might be a similar mechanism in java I can exploit to view information about all the exceptions generated at runtime.
Just to clarify. This has nothing to do with the context in which an exception occurs. This question is not about what I do in a catch block, or unhandled exceptions. Its about knowing if the JVM provides a mechanism to see every exception generated at runtime, regardless of what generated it, or the context.
Why not, it's of course possible! But firstly.. Logging all exceptions encountered by the JVM is a waste of life. It's meaningless in every sense, there could be several excetion's thrown without any significance.
But if indeed if you have no choice, you could tweak your Java to do that.
Breaking every rule of good programming, what we live for, I give you this idea:
Copy the source code of java.lang.Exception from JDK sources to your project.
Create a method in your Exception.java like below:
private void logException() {
// Your logging routine here.
}
Edit java.lang.Exception to call this method logException() at the end of every constructor.
Add the new java.lang.Exception to bootstrap classpath.
Set your logging levels etc and run.
Put your heads up, present this to your weird client, use your diplomatic skills and scare them in few words 'we can do it.. but its your own risk'. Likely you will convince him not to use this.

Commenting out System.out.println

Do System.out.println(...) calls pose any effect if left in BlackBerry code or any other programming language?
When removed, the compilation time may be reduced, but is there any particular other reason to remove them?
There are a couple of things you need to know before using System.out.println() on Blackberry:
Once you print out something to the standard output any person that has your application installed on the device will be able to see them. All they need to do is to attach the device to the simulator and run in debug mode. So make sure you do not print out anything sensitive such as passwords, class names etc. in the released application.
The performance overhead that the System.out.println() itself makes is minimal, especially when the output stream is not attached to anything (i.e. Device is not connected and not in debug mode).
I myself rather use Blackberry preprocessor to be able to disable all logs before making a release. For this reason I define a logging directive LOGGING and then in my code:
//#ifdef LOGGING
System.out.println("LOGGING is enabled");
//#endif
For more on how to use preprocessors in Blackberry Eclipse plugin see this.
I prefer to use a flag to disable sysouts. Sysouts are really slow if you use them a lot, eg. in loops.
If you don't intend to use the output for anything like debugging ect. then it's best to take it out. Your program will only run as fast as the line can be output so in theory the less system.out line you have the faster the process will be.
Hope this helps.
Runtime might be also reduced, as the statements are actually executed - even if the user doesn't see the output on the screen. If you're using a lot of these (e.g. in tight loops) or you're passing to them Objects with expensive toString() methods, the useless output may be slowing you down.
Also, if you're passing String as an argument, those will take some space in bytecode and in memory. You on your souped-up machine with 173 PB of RAM may not care, but there are resource-constrained systems (such as mobile devices).
You should be able to use Ant to preprocess these lines out of your source code. (Make sure that none of them have side-effects!)
I don't know specifically about Blackberry, but if your program is writing to an unknown device (i.e. you are not sure where standard out is going), there may be a potential for your app to occasionally/sporadically/inexplicably block momentarily in the attempt to write.
Create your own method, i.e. :
public static void consoleMessage(String msg){
if(DEBUG_FLAG){
System.out.println(msg);
}
}
Then use only this throughout your code. It will save you the time for changing all the lines.
Use something like Log4J instead of system out print statements, it gives you much more flexibility
Keeping System.out statements isn't that bad a thing to do usually. Users might be able to see them so it doesnt always look good in a production environment. A better idea is to use a logging framework such as java.util.logging or log4j. These can be configured to dump output to the console, to a file, a DB, a webservice ...
Keep in mind that just becuase you can't see the output it doesn't mean that no work is being done at runtime. The JVM still has to create a String to pass to system.out (or a log statement) which can take a fair bit of memory/CPU for large/complex objects like collections.
Sysout statements access a synchronized, shared resource, which causes synchronization between threads using it. That can prevent memory consistency bugs in multithreaded programs if there is no other code which enforces synchronization. When the sysout statements are removed, any existing memory consistency bugs in the code may surface for the first time.
For an example of this effect, see: Loop doesn't see changed value without a print statement.
It's not an object and it doesn't have any memory attached to it so there shouldn't be any effect besides the time to run it and compile it. And of course readability maybe lol

Programmatically determining the cause of IOException?

Is there any way to programmatically differentiate between what caused an IOException? For example Java will throw an IOException, if there was an error during writing. How can I tell, if it's something like access violation, if the Disk is out of free space, if someone disconnected the the network drive, or other things?
I can't really parse the Message since, there does not seem to be any standardized message format, Sun (or Oracle now I guess) doesn't seem to have any sort of standardized format.
(I need to use Java to fix a very broken system at work.)
Unfortunately Java has no equivalent of .NET's System.Runtime.InteropServices.Marshal.GetHRForException(). You tell what kind of I/O error it was only if the exception is an instance of a subclass, e.g. FileNotFoundException.
Getting a hold of the exception's exact class will give you one of a handful of possible subclasses of IOException, and these are quite standardized. You can either test classes with instanceof or (a brutish approach) compare strings returned from getClass().getName().
There are some workarounds for the other stuff; you can do a File.canWrite() on a file you're about to open for writing (well, your program should have done that anyway, if the name and/or directory can vary), and if there's a chance you ran out of file space, you could try writing a small file to a known good location and seeing if that explodes on you. Not very elegant, I know: Java is not really known as a systems programming language.
On the other hand, very often knowing a detailed cause for an exception doesn't help much: With or without the knowledge, your user may simply not be able to get the program to do what's needed.

Is using checked exceptions in external APIs a good idea?

Seeing a checked expection in API is not rare, one of the most well known examples is IOException in Closeable.close(). And often dealing with this exception really annoys me. Even more annoying example was in one of our projects. It consists from several components and each component declares specific checked exception. The problem (in my opinion) is that at design time it was not exactly known what certain exceptions would be. Thus, for instance, component Configurator declared ConfiguratorExeption. When I asked why not just use unchecked exceptions, I was told that we want our app to be robust and not to blow in runtime. But it seams to be a weak argument because:
Most of those exceptions effectively make app unusable. Yes, it doesn't blow up, but it cannot make anything exepting flooding log with messages.
Those exceptions are not specific and virtually mean that 'something bad happened'. How client is supposed to recover?
In fact all recovering consists from logging exception and then swallowing it. This is performed in large try-catch statement.
I think, that this is a recurring pattern. But still checked exceptions are widely used in APIs. What is the reason for this? Are there certain types of APIs that are more appropriate for checked exceptions?
There have been a lot of controversy around this issue.
Take a look at this classic article about that subject http://www.mindview.net/Etc/Discussions/CheckedExceptions
I personally tend to favor the use of Runtime exceptions myself and have started to consider the use of checked exceptions a bad idea in your API.
In fact some very popular Java API's have started to do the same, for instance, Hibernate dropped its use of checked exceptions for Runtime from version 3, the Spring Framework also favor the use of Runtime over checked exceptions.
One of the problems with large libraries is that they do not document all the exceptions that may be thrown, so your code may bomb at any time if an undocumented RuntimeException just happens to be thrown from deep down code you do not "own".
By explicitly declaring all those, at least the developer using said library have the compiler help dealing with them correctly.
There is nothing like doing forensic analysis at 3 in the morning to discover that some situation triggered such an undeclared exception.
Checked Exceptions should only be thrown for things that are 1) Exceptional they are an exception to the rule of success, most poor exception throwing is the terrible habit of defensive coding and 2) Actionable by the client. If something happens that the client of the API can't possibly affect in any way make it a RuntimeException.
There's different views on the matter, but I tend to view things as follows:
a checked exception represents an event which one could reasonably expect to occur under some predictable, exceptional circumstances that are still "within the normal operating conditions of a program/typical caller", and which can typically be dealt with not too far up the call stack;
an unchecked exception represents a condition that we "wouldn't really expect to occur" within the normal running environment of a program, and which can be dealt with fairly high up the call stack (or indeed possibly cause us to shut down the application in the case of a simpler app);
en error represents a condition which, if it occurs, we would generally expect to result in us shutting down the application.
For example, it's quite within the realms of a typical environment that under some exceptional-- but fairly predictable-- conditions, closing a file could cause an I/O error (flushing a buffer to a file on closing when the disk is full). So the decision to let Closable throw a checked IOException is probably reasonable.
On the other hand, there are some examples within the standard Java APIs where the decision is less defensible. I would say that the XML APIs are typically overfussy when it comes to checked exceptions (why is not finding an XML parser something you really expect to happen and deal with in a typical application...?), as is the reflection API (you generally really expect class definitions to be found and not to be able to plough on regardless if they're not...). But many decisions are arguable.
In general, I would agree that exceptions of the "configuration exception" type should probably be unchecked.
Remember if you are calling a method which declares a checked exception but you "really really don't expect it to be thrown and really wouldn't know what to do if it were thrown", then you can programmatically "shrug your shoulders" and re-cast it to a RuntimeException or Error...
You can, in fact, use Exception tunneling so that a generic exception (such as your ConfiguratorException) can give more detail about what went wrong (such as a FileNotFound).
In general I would caution against this however, as this is likely to be a leaky abstraction (no one should care whether your configurator is trying to pull its data from the filesystem, database, across a network or whatever)
If you are using checked exceptions then at least you'll know where and why your abstractions are leaky. IMHO, this is a good thing.

Why are Exceptions not Checked in .NET?

I know Googling I can find an appropriate answer, but I prefer listening to your personal (and maybe technical) opinions.
What is the main reason of the difference between Java and C# in throwing exceptions?
In Java the signature of a method that throws an exception has to use the "throws" keyword, while in C# you don't know in compilation time if an exception could be thrown.
In the article The Trouble with Checked Exceptions and in Anders Hejlsberg's (designer of the C# language) own voice, there are three main reasons for C# not supporting checked exceptions as they are found and verified in Java:
Neutral on Checked Exceptions
“C# is basically silent on the checked
exceptions issue. Once a better
solution is known—and trust me we
continue to think about it—we can go
back and actually put something in
place.”
Versioning with Checked Exceptions
“Adding a new exception to a throws
clause in a new version breaks client
code. It's like adding a method to an
interface. After you publish an
interface, it is for all practical
purposes immutable, …”
“It is funny how people think that the
important thing about exceptions is
handling them. That is not the
important thing about exceptions. In a
well-written application there's a
ratio of ten to one, in my opinion, of
try finally to try catch. Or in C#,
using statements, which are
like try finally.”
Scalability of Checked Exceptions
“In the small, checked exceptions are
very enticing…The trouble
begins when you start building big
systems where you're talking to four
or five different subsystems. Each
subsystem throws four to ten
exceptions. Now, each time you walk up
the ladder of aggregation, you have
this exponential hierarchy below you
of exceptions you have to deal with.
You end up having to declare 40
exceptions that you might throw.…
It just balloons out of control.”
In his article, “Why doesn't C# have exception specifications?”, Anson Horton (Visual C# Program Manager) also lists the following reasons (see the article for details on each point):
Versioning
Productivity and code quality
Impracticality of having class author differentiate between
checked and unchecked exceptions
Difficulty of determining the correct exceptions for interfaces.
It is interesting to note that C# does, nonetheless, support documentation of exceptions thrown by a given method via the <exception> tag and the compiler even takes the trouble to verify that the referenced exception type does indeed exist. There is, however, no check made at the call sites or usage of the method.
You may also want to look into the Exception Hunter, which is a commerical tool by Red Gate Software, that uses static analysis to determine and report exceptions thrown by a method and which may potentially go uncaught:
Exception Hunter is a new analysis
tool that finds and reports the set of
possible exceptions your functions
might throw – before you even ship.
With it, you can locate unhandled
exceptions easily and quickly, down to
the line of code that is throwing the
exceptions. Once you have the results,
you can decide which exceptions need
to be handled (with some exception
handling code) before you release your
application into the wild.
Finally, Bruce Eckel, author of Thinking in Java, has an article called, “Does Java need Checked Exceptions?”, that may be worth reading up as well because the question of why checked exceptions are not there in C# usually takes root in comparisons to Java.
Because the response to checked exceptions is almost always:
try {
// exception throwing code
} catch(Exception e) {
// either
log.error("Error fooing bar",e);
// OR
throw new RuntimeException(e);
}
If you actually know that there is something you can do if a particular exception is thrown, then you can catch it and then handle it, but otherwise it's just incantations to appease the compiler.
The basic design philosophy of C# is that actually catching exceptions is rarely useful, whereas cleaning up resources in exceptional situations is quite important. I think it's fair to say that using (the IDisposable pattern) is their answer to checked exceptions. See [1] for more.
http://www.artima.com/intv/handcuffs.html
By the time .NET was designed, Java had checked exceptions for quite some time and this feature was viewed by Java developers at best as controversial controversial. Thus .NET designers chose not to include it in C# language.
Fundamentally, whether an exception should be handled or not is a property of the caller, rather than of the function.
For example, in some programs there is no value in handling an IOException (consider ad hoc command-line utilities to perform data crunching; they're never going to be used by a "user", they're specialist tools used by specialist people). In some programs, there is value in handling an IOException at a point "near" to the call (perhaps if you get a FNFE for your config file you'll drop back to some defaults, or look in another location, or something of that nature). In other programs, you want it to bubble up a long way before it's handled (for example you might want it to abort until it reaches the UI, at which point it should alert the user that something has gone wrong.
Each of these cases is dependent on the application, and not the library. And yet, with checked exceptions, it is the library that makes the decision. The Java IO library makes the decision that it will use checked exceptions (which strongly encourage handling that's local to the call) when in some programs a better strategy may be non-local handling, or no handling at all.
This shows the real flaw with checked exceptions in practice, and it's far more fundamental than the superficial (although also important) flaw that too many people will write stupid exception handlers just to make the compiler shut up. The problem I describe is an issue even when experienced, conscientious developers are writing the program.
Interestingly, the guys at Microsoft Research have added checked exceptions to Spec#, their superset of C#.
Anders himself answers that question in this episode of the Software engineering radio podcast
I went from Java to C# because of a job change. At first, I was a little concerned about the difference, but in practice, it hasn't made a difference.
Maybe, it's because I come from C++, which has the exception declaration, but it's not commonly used. I write every single line of code as if it could throw -- always use using around Disposable and think about cleanup I should do in finally.
In retrospect the propagation of the throws declaration in Java didn't really get me anything.
I would like a way to say that a function definitely never throws -- I think that would be more useful.
Additionally to the responses that were written already, not having checked exceptions helps you in many situations a lot. Checked exceptions make generics harder to implement and if you have read the closure proposals you will notice that every single closure proposal has to work around checked exceptions in a rather ugly way.
I sometimes miss checked exceptions in C#/.NET.
I suppose besides Java no other notable platform has them. Maybe the .NET guys just went with the flow...

Categories