Related
I am using eclipse to develop a web application. Just today I have updated my struts version by changing the JAR file. I am getting warnings at some places that methods are deprecated, but the code is working fine.
I want to know some things
Is it wrong to use Deprecated methods or classes in Java?
What if I don't change any method and run my application with warnings that I have, will it create any performance issue.
1. Is it wrong to use Deprecated methods or classes in Java?
From the definition of deprecated:
A program element annotated #Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists.
The method is kept in the API for backward compatibility for an unspecified period of time, and may in future releases be removed. That is, no, it's not wrong, but there is a better way of doing it, which is more robust against API changes.
2. What if I don't change any method and run my application with warnings that I have, will it create any performance issue.
Most likely no. It will continue to work as before the deprecation. The contract of the API method will not change. If some internal data structure changes in favor of a new, better method, there could be a performance impact, but it's quite unlikely.
The funniest deprecation in the Java API, is imo, the FontMetrics.getMaxDecent. Reason for deprecation: Spelling error.
Deprecated. As of JDK version 1.1.1, replaced by getMaxDescent().
You can still use deprecated code without performance being changed, but the whole point of deprecating a method/class is to let users know there's now a better way of using it, and that in a future release the deprecated code is likely to be removed.
Terminology
From the official Sun glossary:
deprecation: Refers to a class, interface, constructor, method or field that is no longer recommended, and may cease to exist in a future version.
From the how-and-when to deprecate guide:
You may have heard the term, "self-deprecating humor," or humor that minimizes the speaker's importance. A deprecated class or method is like that. It is no longer important. It is so unimportant, in fact, that you should no longer use it, since it has been superseded and may cease to exist in the future.
The #Deprecated annotation went a step further and warn of danger:
A program element annotated #Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists.
References
java.sun.com Glossary
Language guide/How and When to Deprecate APIs
Annotation Type Deprecated API
Right or wrong?
The question of whether it's right or wrong to use deprecated methods will have to be examined on individual basis. Here are ALL the quotes where the word "deprecated" appears in Effective Java 2nd Edition:
Item 7: Avoid finalizers: The only methods that claim to guarantee finalization are System.runFinalizersOnExit and its evil twin Runtime.runFinalizersOnExit. These methods are fatally flawed and have been deprecated.
Item 66: Synchronize access to shared mutable data: The libraries provide the Thread.stop method, but this method was deprecated long ago because it's inherently unsafe -- its use can result in data corruption.
Item 70: Document thread safety: The System.runFinalizersOnExit method is thread-hostile and has been deprecated.
Item 73: Avoid thread groups: They allow you to apply certain Thread primitives to a bunch of threads at once. Several of these primitives have been deprecated, and the remainder are infrequently used. [...] thread groups are obsolete.
So at least with all of the above methods, it's clearly wrong to use them, at least according to Josh Bloch.
With other methods, you'd have to consider the issues individually, and understand WHY they were deprecated, but generally speaking, when the decision to deprecate is justified, it will tend to lean toward wrong than right to continue using them.
Related questions
Difference between a Deprecated and Legacy API?
Aside from all the excellent responses above I found there is another reason to remove deprecated API calls.
Be researching why a call is deprecated I often find myself learning interesting things about the Java/the API/the Framework. There is often a good reason why a method is being deprecated and understanding these reasons leads to deeper insights.
So from a learning/growing perspective, it is also a worthwhile effort
It certainly doesn't create a performance issue -- deprecated means in the future it's likely that function won't be part of the library anymore, so you should avoid using it in new code and change your old code to stop using it, so you don't run into problems one day when you upgrade struts and find that function is no longer present
It's not wrong, it's just not recommended. It generally means that at this point there is a better way of doing things and you'd do good if you use the new improved way. Some deprecated stuff are really dangerous and should be avoided altogether. The new way can yield better performance than the deprecated one, but it's not always the case.
You may have heard the term, "self-deprecating humor". That is humor that minimizes your importance. A deprecated class or method is like that. It is no longer important. It is so unimportant, in fact, that it should no longer be used at all, as it will probably cease to exist in the future.
Try to avoid it
Generally no, it's not absolutely wrong to use deprecated methods as long as you have a good contingency plan to avoid any problems if/when those methods disappear from the library you're using. With Java API itself this never happens but with just about anything else it means that it's going to be removed. If you specifically plan not to upgrade (although you most likely should in the long run) your software's supporting libraries then there's no problem in using deprecated methods.
No.
Yes, it is wrong.
Deprecated methods or classes will be removed in future versions of Java and should not be used. In each case, there should be an alternative available. Use that.
There are a couple of cases when you have to use a deprecated class or method in order to meet a project goal. In this case, you really have no choice but to use it. Future versions of Java may break that code, but if it's a requirement you have to live with that. It probably isn't the first time you had to do something wrong in order to meet a project requirement, and it certainly won't be the last.
When you upgrade to a new version of Java or some other library, sometimes a method or a class you were using becomes deprecated. Deprecated methods are not supported, but shouldn't produce unexpected results. That doesn't mean that they won't, though, so switch your code ASAP.
The deprecation process is there to make sure that authors have enough time to change their code over from an old API to a new API. Make use of this time. Change your code over ASAP.
It is not wrong, but some of the deprecated methods are removed in the future versions of the software, so you will possibly end up with not working code.
Is it wrong to use Deprecated methods or classes in Java?"
Not wrong as such but it can save you some trouble. Here is an example where it's strongly discouraged to use a deprecated method:
http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
Why is Thread.stop deprecated?
Because it is inherently unsafe.
Stopping a thread causes it to unlock
all the monitors that it has locked.
(The monitors are unlocked as the
ThreadDeath exception propagates up
the stack.) If any of the objects
previously protected by these monitors
were in an inconsistent state, other
threads may now view these objects in
an inconsistent state. Such objects
are said to be damaged. When threads
operate on damaged objects, arbitrary
behavior can result. This behavior may
be subtle and difficult to detect, or
it may be pronounced. Unlike other
unchecked exceptions, ThreadDeath
kills threads silently; thus, the user
has no warning that his program may be
corrupted. The corruption can manifest
itself at any time after the actual
damage occurs, even hours or days in
the future.
What if don't change any method and run my application with warnings that I have, will it create any performance issue.
There should be no issues in terms of performance. The standard API is designed to respect some backward compatibility so applications can be gradually adapted to newer versions of Java.
Is it wrong to use Deprecated methods or classes in Java?
It is not "wrong", still working but avoid it as much as possible.
Suppose there is a security vulnerability associated with a method and the developers determine that it is a design flaw. So they may decide to deprecate the method and introduce the new way.
So if you still use the old method, you have a threat. So be aware of the reason to the deprecation and check whether how it affects to you.
what if don't change any method and run my application with warnings that I have, will it create any performance issue.
If the deprecation is due to a performance issue, then you will suffer from a performance issue, otherwise there is no reason to have such a problem. Again would like to point out, be aware of the reason to deprecation.
In Java it's #Deprecated, in C# it's [Obsolete].
I think I prefer C#'s terminology. It just means it's obsolete. You can still use it if you want to, but there's probably a better way.
It's like using Windows 3.1 instead of Windows 7 if you believe that Windows 3.1 is obsolete. You can still use it, but there's probably better features in a future version, plus the future versions will probably be supported - the obsolete one won't be.
Same for Java's #Deprecated - you can still use the method, but at your own risk - in future, it might have better alternatives, and might not even be supported.
If you are using code that is deprecated, it's usually fine, as long as you don't have to upgrade to a newer API - the deprecated code might not exist there. I suggest if you see something that is using deprecated code, to update to use the newer alternatives (this is usually pointed out on the annotation or in a Javadoc deprecated comment).
Edit: And as pointed out by Michael, if the reason for deprecation is due to a flaw in the functionality (or because the functionality should not even exist), then obviously, one shouldn't use the deprecated code.
Of course not - since the whole Java is getting #Deprecated :-) you can feel free to use them for as long as Java lasts. Not going to notice any diff anyway, unless it's something really broken. Meaning - have to read about it and then decide.
In .Net however, when something is declared [Obsolete], go and read about it immediately even if you never used it before - you have about 50% chance that it's more efficient and/or easier to use than replacement :-))
So in general, it can be quite beneficial to be techno-conservative these days, but you have to do your reading chore first.
I feel that deprecated method means; there is an alternate=ive method available which is better in all aspects than existing method. Better to use the good method than existing old method. For backward compatibility, old methods are left as deprecated.
I'm designing an infrastructure for a project and I've been wondering if it'd be a good idea to format the exception's message with parameters, making it dynamic.
This means, on the one hand, that exception messages can be really verbose.
The downside, which is a lot stronger, in my opinion, is that you can't expect certain messages. These can be used (though it's not a best-practice) in exception handling, testing whether the message is this or that and in logging. But what's even more disturbing is that it will make localization a lot harder if you intent on showing that message somewhere (which I do).
So my question is what's your take on it and whether you have a compromising solution, giving me both verbosity (in case I log the exception) and consistency.
Thanks.
I believe that including parameters in Exceptions is often extremely helpful. Think about that other developers (and you yourself) will read the message and try to find a bug. Or even worse: A user may read an exception message to you or post it on a forum and you have to find out what's wrong remotely.
Testing for certain messages in exceptions is indeed not best practice. I'd call it bad practice. All languages I know allow you to define our own Exception classes and also add custom properties to the class if the pure class name is not good enough for you (though it usually is). I believe messages in Exceptions should be as human readable as possible and there is no need for them to be predictable by code.
Of course you can overdo anything. Exception messages should not grow too large/long just because you wanted to include all possible variables in it. Select wisely ;-).
Why doesn't F# naturally support a try/with/finally block?
Doesn't it make sense to try something, deal with whatever exception it throws, at least to log the exception, and then be sure that some code executes after all that?
Sure, we can do
try
try
...
with ex -> ...
finally
...
But that seems too artificial, it clearly demonstrates that "F# is against try/with/finally". Why is that?
As somebody already mentioned, you would usually use try-with-finally to make sure that you properly release all resources in case of an exception. I think in most of the cases you can do this more easily using the use keyword:
let input =
try
use stream = new FileStream("C:\temp\test.txt");
use rdr = new StreamReader(stream);
Some(rdr.ReadToEnd())
with :? IOException as e ->
logError(e)
None
I think this is mostly the reason why you don't need try-with-finally as often as you would in other languages. But of course, there are some situations where you may need it (but you could of course avoid that by creating instance of IDisposable using object expressions (which is syntactically very easy). But I think this is so rare that the F# team doesn't really need to worry about this.
Orthogonality? You can simply nest a try-with inside a try-finally, as you show. (This is what happens at the IL level anyway, I think.)
That said, try-with-finally is something that we may consider in a future version of the language.
Personally I have only run into wanting it a couple times, but when you do need it, it is a little bothersome to have to do the extra nesting/indent. In general I find that I rarely write exception handling code, and it's usually just one or the other (e.g. a finally to restore an invariant or other transactional semantics, or a 'catch' near the top of an app to log an exception or show the user diagnostics).
But I don't think there's a lot to 'read in to' regarding the language design here.
Without going into great detail because the great details are in
[Expert .NET 2.0 IL Assembler] 01 by Serge Lidin
See: Ch. 14, Managed Exception Handling
"The finally and fault handlers cannot peacefully coexist with other handlers, so if a guarded block has a finally or fault handler, it cannot have anything else. To combine a finally or fault handler with other handlers, you need to nest the guarded and handler bocks within other guarded blocks, ..., so that each finally or fault handler has its own personal guarded block."
pg. 300
A try/catch uses a fault handler and a try/finally uses a finally handler.
See: ILGenerator.BeginFaultBlock Method
If you emit a fault handler in an exception block that also contains a
catch handler or a finally handler, the resulting code is
unverifiable.
So, all of the .net languages could be consider to be using syntactic sugar and since F# is so new, they just haven't implemented it yet. No harm no foul.
But that seems too artificial, it clearly demonstrates that "F# is against try/with/finally". Why is that?
I guess F# might be "against" exception-handling at all. For the sake of .NET interoperability, it has to support them, but basically, there is no exception-handling* in functional programming.
Throwing/Catching exceptions means performing "jumps to nowhere" that aren't even noticed by the type system which is both fundamentally against the functional philosophy.
You can use purely functional (monadic) code to wrap exceptions. All errors are handled through values, in terms of the underlying type system and free of jumps/side effects.
Instead of writing a function
let readNumber() : int = ...
that may throw arbitrary exceptions, you'll simply state
let readNumber() : int option = ...
which makes this point automatically clear by its type signature.
*This doesn't mean we don't handle exceptional situations, it's just about the kind of exception-handling in .NET/C++.
I will clarify my comment in this answer.
I maintain there is no reason to assume that you want to catch exceptions and finalize some resources at the same level. Perhaps you got used to do it that way in a language in which it was convenient to handle both at the same time, but it's a coincidence when it happens. The finalization is convenient when you do not catch all exceptions from the inner block. try...with is for catching exceptions so that the computation can continue normally. There simply is no relationship between the two (if anything, they go in opposite directions: are you catching the exception, or letting it go through?).
Why do you have to finalize anything at all? Shouldn't the GC be managing unreferenced resources for you? Ah... but the language is trying to give you access to system primitives which work with side-effects, with explicit allocations and de-allocations. You have to de-allocate what you have allocated (in all cases)... Shouldn't you be blaming the rotten interface that the system is providing instead of F#, which is only the messenger in this case?
Do you use the debugger of the language that you work in to step through code to understand what the code is doing, or do you find it easy to look at code written by someone else to figure out what is going on? I am talking about code written in C#, but it could be any language.
I use the unit tests for this.
Yes, but generally only to investigate bugs that prove resistant to other methods.
I write embedded software, so running a debugger normally involves having to physically plug a debug module into the PCB under test, add/remove links, solder on a debug socket (if not already present), etc - hence why I try to avoid it if possible. Also, some older debugger hardware/software can be a bit flaky.
I will for particularly complex sections of code, but I hope that generally my fellow developers would have written code that is clear enough to follow without it.
Depending on who wrote the code, even a debugger doesn't help to understand how it works: I have a co-worker who prides himself on being able to get as much as possible done in every single line of code. This can lead to code that is often hard to read, let alone understand what it does in the long run.
Personally I always hope to find code as readable as the code I try to write.
I will mostly use debugger to setup breakpoints on exceptions.
That way I can execute any test or unit test I wrote, and still be able to be right where the code fails if any exception should occur.
I won't say I used all the time, but I do use it fairly often. The domain I work in is automation and controls. You often need the debugger to see the various internal states of the system. It is usually difficult to impossible to determine these simply from looking at code.
Yes, but only as a last resort when there's no unit test coverage and the code is particularly hard to follow. Using the debugger to step through code is a time consuming process and one I don't find too fun. I tend to find myself using this technique a lot when trying to follow VBA code.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Google's Go language has no exceptions as a design choice, and Linus of Linux fame has called exceptions crap. Why?
Exceptions make it really easy to write code where an exception being thrown will break invariants and leave objects in an inconsistent state. They essentially force you to remember that most every statement you make can potentially throw, and handle that correctly. Doing so can be tricky and counter-intuitive.
Consider something like this as a simple example:
class Frobber
{
int m_NumberOfFrobs;
FrobManager m_FrobManager;
public:
void Frob()
{
m_NumberOfFrobs++;
m_FrobManager.HandleFrob(new FrobObject());
}
};
Assuming the FrobManager will delete the FrobObject, this looks OK, right? Or maybe not... Imagine then if either FrobManager::HandleFrob() or operator new throws an exception. In this example, the increment of m_NumberOfFrobs does not get rolled back. Thus, anyone using this instance of Frobber is going to have a possibly corrupted object.
This example may seem stupid (ok, I had to stretch myself a bit to construct one :-)), but, the takeaway is that if a programmer isn't constantly thinking of exceptions, and making sure that every permutation of state gets rolled back whenever there are throws, you get into trouble this way.
As an example, you can think of it like you think of mutexes. Inside a critical section, you rely on several statements to make sure that data structures are not corrupted and that other threads can't see your intermediate values. If any one of those statements just randomly doesn't run, you end up in a world of pain. Now take away locks and concurrency, and think about each method like that. Think of each method as a transaction of permutations on object state, if you will. At the start of your method call, the object should be clean state, and at the end there should also be a clean state. In between, variable foo may be inconsistent with bar, but your code will eventually rectify that. What exceptions mean is that any one of your statements can interrupt you at any time. The onus is on you in each individual method to get it right and roll back when that happens, or order your operations so throws don't effect object state. If you get it wrong (and it's easy to make this kind of mistake), then the caller ends up seeing your intermediate values.
Methods like RAII, which C++ programmers love to mention as the ultimate solution to this problem, go a long way to protect against this. But they aren't a silver bullet. It will make sure you release resources on a throw, but doesn't free you from having to think about corruption of object state and callers seeing intermediate values. So, for a lot of people, it's easier to say, by fiat of coding style, no exceptions. If you restrict the kind of code you write, it's harder to introduce these bugs. If you don't, it's fairly easy to make a mistake.
Entire books have been written about exception safe coding in C++. Lots of experts have gotten it wrong. If it's really that complex and has so many nuances, maybe that's a good sign that you need to ignore that feature. :-)
The reason for Go not having exceptions is explained in the Go language design FAQ:
Exceptions are a similar story. A
number of designs for exceptions have
been proposed but each adds
significant complexity to the language
and run-time. By their very nature,
exceptions span functions and perhaps
even goroutines; they have
wide-ranging implications. There is
also concern about the effect they
would have on the libraries. They are,
by definition, exceptional yet
experience with other languages that
support them show they have profound
effect on library and interface
specification. It would be nice to
find a design that allows them to be
truly exceptional without encouraging
common errors to turn into special
control flow that requires every
programmer to compensate.
Like generics, exceptions remain an
open issue.
In other words, they haven't yet figured out how to support exceptions in Go in a way that they think is satisfactory. They are not saying that Exceptions are bad per se;
UPDATE - May 2012
The Go designers have now climbed down off the fence. Their FAQ now says this:
We believe that coupling exceptions to a control structure, as in the try-catch-finally idiom, results in convoluted code. It also tends to encourage programmers to label too many ordinary errors, such as failing to open a file, as exceptional.
Go takes a different approach. For plain error handling, Go's multi-value returns make it easy to report an error without overloading the return value. A canonical error type, coupled with Go's other features, makes error handling pleasant but quite different from that in other languages.
Go also has a couple of built-in functions to signal and recover from truly exceptional conditions. The recovery mechanism is executed only as part of a function's state being torn down after an error, which is sufficient to handle catastrophe but requires no extra control structures and, when used well, can result in clean error-handling code.
See the Defer, Panic, and Recover article for details.
So the short answer is that they can do it differently using multi-value return. (And they do have a form of exception handling anyway.)
... and Linus of Linux fame has called exceptions crap.
If you want to know why Linus thinks exceptions are crap, the best thing is to look for his writings on the topic. The only thing I've tracked down so far is this quote that is embedded in a couple of emails on C++:
"The whole C++ exception handling thing is fundamentally broken. It's especially broken for kernels."
You'll note that he's talking about C++ exceptions in particular, and not exceptions in general. (And C++ exceptions do apparently have some issues that make them tricky to use correctly.)
My conclusion is that Linus hasn't called exceptions (in general) "crap" at all!
Exceptions are not bad per se, but if you know they are going to happen a lot, they can be expensive in terms of performance.
The rule of thumb is that exceptions should flag exceptional conditions, and that you should not use them for control of program flow.
I disagree with "only throw exceptions in an exceptional situation." While generally true, it's misleading. Exceptions are for error conditions (execution failures).
Regardless of the language you use, pick up a copy of Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (2nd Edition). The chapter on exception throwing is without peer. Some quotes from the first edition (the 2nd's at my work):
DO NOT return error codes.
Error codes can be easily ignored, and often are.
Exceptions are the primary means of reporting errors in frameworks.
A good rule of thumb is that if a method does not do what its name suggests, it should be considered a method-level failure, resulting in an exception.
DO NOT use exceptions for the normal flow of control, if possible.
There are pages of notes on the benefits of exceptions (API consistency, choice of location of error handling code, improved robustness, etc.) There's a section on performance that includes several patterns (Tester-Doer, Try-Parse).
Exceptions and exception handling are not bad. Like any other feature, they can be misused.
From the perspective of golang, I guess not having exception handling keeps the compiling process simple and safe.
From the perspective of Linus, I understand that kernel code is ALL about corner cases. So it makes sense to refuse exceptions.
Exceptions make sense in code were it's okay to drop the current task on the floor, and where common case code has more importance than error handling. But they require code generation from the compiler.
For example, they are fine in most high-level, user-facing code, such as web and desktop application code.
Exceptions in and of themselves are not "bad", it's the way that exceptions are sometimes handled that tends to be bad. There are several guidelines that can be applied when handling exceptions to help alleviate some of these issues. Some of these include (but are surely not limited to):
Do not use exceptions to control program flow - i.e. do not rely on "catch" statements to change the flow of logic. Not only does this tend to hide various details around the logic, it can lead to poor performance.
Do not throw exceptions from within a function when a returned "status" would make more sense - only throw exceptions in an exceptional situation. Creating exceptions is an expensive, performance-intensive operation. For example, if you call a method to open a file and that file does not exist, throw a "FileNotFound" exception. If you call a method that determines whether a customer account exists, return a boolean value, do not return a "CustomerNotFound" exception.
When determining whether or not to handle an exception, do not use a "try...catch" clause unless you can do something useful with the exception. If you are not able to handle the exception, you should just let it bubble up the call stack. Otherwise, exceptions may get "swallowed" by the handler and the details will get lost (unless you rethrow the exception).
Typical arguments are that there's no way to tell what exceptions will come out of a particular piece of code (depending on language) and that they are too much like gotos, making it difficult to mentally trace execution.
http://www.joelonsoftware.com/items/2003/10/13.html
There is definitely no consensus on this issue. I would say that from the point of view of a hard-core C programmer like Linus, exceptions are definitely a bad idea. A typical Java programmer is in a vastly different situation, though.
Exceptions aren't bad. They fit in well with C++'s RAII model, which is the most elegant thing about C++. If you have a bunch of code already that's not exception safe, then they're bad in that context. If you're writing really low level software, like the linux OS, then they're bad. If you like littering your code with a bunch of error return checks, then they not helpful. If you don't have a plan for resource control when an exception is thrown (that C++ destructors provides) then they're bad.
A great use-case for exceptions is thus....
Say you are on a project and every controller (around 20 different major ones) extends a single superclass controller with an action method. Then every controller does a bunch of stuff different from each other calling objects B, C, D in one case and F, G, D in another case. Exceptions come to the rescue here in many cases where there was tons of return code and EVERY controller was handling it differently. I whacked all that code, threw the proper exception from "D", caught it in the superclass controller action method and now all our controllers are consistent. Previously D was returning null for MULTIPLE different error cases that we want to tell the end-user about but couldn't and I didn't want to turn the StreamResponse into a nasty ErrorOrStreamResponse object (mixing a data structure with errors in my opinion is a bad smell and I see lots of code return a "Stream" or other type of entity with error info embedded in it(it should really be the function returns the success structure OR the error structure which I can do with exceptions vs. return codes)....though the C# way of multiple responses is something I might consider sometimes though in many cases, the exception can skip a whole lot of layers(layers that I don't need to clean up resources on either).
yes, we have to worry about each level and any resource cleanup/leaks but in general none of our controllers had any resources to clean up after.
thank god we had exceptions or I would have been in for a huge refactor and wasted too much time on something that should be a simple programming problem.
Theoretically they are really bad. In perfect mathematical world you cannot get exception situations. Look at the functional languages, they have no side effects, so they virtually do not have source for unexceptional situations.
But, reality is another story. We always have situations that are "unexpected". This is why we need exceptions.
I think we can think of exceptions as of syntax sugar for ExceptionSituationObserver. You just get notifications of exceptions. Nothing more.
With Go, I think they will introduce something that will deal with "unexpected" situations. I can guess that they will try to make it sound less destructive as exceptions and more as application logic. But this is just my guess.
The exception-handling paradigm of C++, which forms a partial basis for that of Java, and in turn .net, introduces some good concepts, but also has some severe limitations. One of the key design intentions of exception handling is to allow methods to ensure that they will either satisfy their post-conditions or throw an exception, and also ensure that any cleanup which needs to happen before a method can exit, will happen. Unfortunately, the exception-handling paradigms of C++, Java, and .net all fail to provide any good means of handling the situation where unexpected factors prevent the expected cleanup from being performed. This in turn means that one must either risk having everything come to a screeching halt if something unexpected happens (the C++ approach to handling an exception occurs during stack unwinding), accept the possibility that a condition which cannot be resolved due to a problem that occurred during stack-unwinding cleanup will be mistaken for one which can be resolved (and could have been, had the cleanup succeeded), or accept the possibility that an unresolvable problem whose stack-unwinding cleanup triggers an exception that would typically be resolvable, might go unnoticed as code which handles the latter problem declares it "resolved".
Even if exception handling would generally be good, it's not unreasonable to regard as unacceptable an exception-handling paradigm that fails to provide a good means for handling problems that occur when cleaning up after other problems. That isn't to say that a framework couldn't be designed with an exception-handling paradigm that could ensure sensible behavior even in multiple-failure scenarios, but none of the top languages or frameworks can as yet do so.
I havent read all of the other answers, so this ma yhave already been mentioned, but one criticism is that they cause programs to break in long chains, making it difficult to track down errors when debugging the code. For example, if Foo() calls Bar() which calls Wah() which calls ToString() then accidentily pushing the wrong data into ToString() ends up looking like an error in Foo(), an almost completely unrelated function.
For me the issue is very simple. Many programmers use exception handler inappropriately. More language resource is better. Be capable to handle exceptions is good. One example of bad use is a value that must be integer not be verified, or another input that may divide and not be checked for division of zero... exception handling may be an easy way to avoid more work and hard thinking, the programmer may want to do a dirty shortcut and apply an exception handling... The statement: "a professional code NEVER fails" might be illusory, if some of the issues processed by the algorithm are uncertain by its own nature. Perhaps in the unknown situations by nature is good come into play the exception handler. Good programming practices are a matter of debate.
Exception not being handled is generally bad.
Exception handled badly is bad (of course).
The 'goodness/badness' of exception handling depends on the context/scope and the appropriateness, and not for the sake of doing it.
Okay, boring answer here. I guess it depends on the language really. Where an exception can leave allocated resources behind, they should be avoided. In scripting languages they just desert or overjump parts of the application flow. That's dislikable in itself, yet escaping near-fatal errors with exceptions is an acceptable idea.
For error-signaling I generally prefer error signals. All depends on the API, use case and severity, or if logging suffices. Also I'm trying to redefine the behaviour and throw Phonebooks() instead. The idea being that "Exceptions" are often dead ends, but a "Phonebook" contains helpful information on error recovery or alternative execution routes. (Not found a good use case yet, but keep trying.)