Java, default exception messages - java

Given the following:
public abstract class Test {
public static void main(String[] args) {
int[] testArray = {6, 3, 2};
System.out.println(testArray[3]);
}
}
when I run the program I get:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Test1.main(Test1.java:5)
In this case the JVM displays the index that is out of bounds i.e. 3.
This specific example aside, given that I choose not to catch an exception in a program's code:
How can I find out, for any exception, either checked or unchecked, what the default message would be that the JVM would display?
For a custom exception class that I write myself, and for an object of this class that I generate in my code using the 'throw' keyword (but, again, choose not to catch), can I set up a default message that the JVM would display?

How can I found out, for any exception, either checked or unchecked, what the default message would be that the JVM would
display?
As you might already suspect, the answer is "in general, you can't". Most of the time, the message is set from one of the constructors of the exception that takes a string message. If you're lucky, the message will be meaningful and provide useful information. Otherwise, as is common practice, the semantics of the exception will reside essentially in its class name and in the associated Javadoc. Also consider that exception messages are often localized.
For a custom exception class that I write myself, and for an object of this class that I generate in my code using the 'throw' keyword
(but, again, choose not to catch it), can I set up a default message
that the JVM would display?
That's entirely up to you. You could setup a default message in the default constructor like this:
public class MyException extends Exception {
public MyException() {
super("my default message");
}
public MyException(String message) {
super(message);
}
}

There is Thread.setDefaultExceptionHandler, all the uncaught exceptions will go there, so you can provide your own exception handler as an argument to that method somewhere in the beginning of your program.
I think, you can also construct any exception yourself and see the message as follows
new IOException().getMessage()
though probably the message in that case will be empty, I didn't try

I am only able to answer your second question.
In your Exception class (which should derive from java.lang.Exception) add (overwrite) the constructor accepting a String as an argument. Pass the message you want your thrown exception to have as a String to the new constructor et voilà → you got a personalized message for your exception. If you need a default message, just use this constructor from within the default one. Hope that helps.

Any exception that is of type or extends runtime exception is unchecked exception. Rest are checked exception.
You just need to extend runtime exception then you need not handle the exception that is thrown. And you can print default message for that exception by ovveriding getMessage method.

Related

Effects of Try/Catch against Throwing Exceptions in a constructing class' constructor

I was playing around with some of my code and came across something I didn't fully understand. I have a class called SentimentClassifier, the constructor of which looks like this:
public SentimentClassifier(final int nGramToBeUsed) {
try {
classifier = (DynamicLMClassifier<?>) AbstractExternalizable.readObject(new File(etc));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I have another class which creates this one, like so:
public TwitterManager(final int nGramToBeUsed) {
sentimentClassifier = new SentimentClassifier(nGramToBeUsed);
}
If I run the code like this, everything works fine. But if I change the first class from using try/catch to throw the exception, like so:
public SentimentClassifier(final int nGramToBeUsed) throws ClassNotFoundException, IOException {
classifier = (DynamicLMClassifier<?>) AbstractExternalizable.readObject(new File(etc));
}
Suddenly the second class complains that the IOException isn't being handled. Why is this thrown only for the thrown exception and not for the try/catch?
When you call a method M1 from another method M2:
If some code in M1 raises some Checked Exception, and the method M1 itself handles it, rather than throwing it, you don't have to worry about the exception while calling it.
Now, if the exception raised in M1, is not being handled in M1 itself, rather it is propagated up the stack trace, then M1 must declare that exception in the throws clause. This is just for the convenience of the calling method to know that it should be ready to handle those exception in case they are thrown. This is only the case with Checked Exception.
But if the calling method M2, doesn't handle that exception, it has the option to re-declare that exception to be thrown in it's own throws clause, in which case the exception will be propagated further up the stack trace.
If method M2 does neither of the previous two task, you will get a compiler error. Because you haven't given any proper path or way to handle the exception that can be thrown.
Note all the above arguments are true for Checked Exception only. For Unchecked exception, you don't need to handle it yourself, neither you need to declare it in throws clause.
Suggested Read:
Java: checked vs unchecked exception explanation
Unchecked Exception controversies
JLS - The Kinds and Causes of Exceptions
In Java, if a method declares that throws an Exception (other than RuntimeException), callers must handle the exception. They can do this one of two ways: catch it, or declare that they themselves throw it.
You moved the handling of these two exceptions from the SentimentClassifier constructor to its callers.
If the constructor declares any exceptions, the calling code must handle them or declare them. After all, the constructor could throw/propagate these exceptions, and any code that calls it must handle them.
When you catch an exception, it means that you will deal with it on the catch block, and its consequences, so the external code can continue to progress without being warned about the internal exception.
If your exception is thrown, you are forcing by contract to any creator/invoker class to deal with any declared exception that could be produced during the initialization/execution process, as it can be critical for the business logic.
In this case, if the exceptions that can be generated during init are critical, and could stop the class from working properly, they should be thrown, as the creator class TwitterManager could have a disfuncional or partially initialized instance of the SentinelClassifier object, leading to unexpected errors.

Why doesn't java.lang.ExceptionInInitializerError have a constructor with both message and cause?

I use java.lang.ExceptionInInitializerError to rethrow caught exceptions in static initialisation blocks. I noticed it is not possible to construct with both a message and a cause; only one or the other.
Is there a good reason why?
What alternatives can you suggest for rethrowing checked exceptions as unchecked exceptions from a static init block? Ex: Rethrow as java.lang.RuntimeException which allows both message and cause.
UPDATE: Clarified #2 and added sample code.
public class Sample {
private static final String _FILE_PATH = "blah/blah/blah";
static {
try {
FileReader in = new FileReader(new File(_FILE_PATH));
}
catch (FileNotFoundException e) {
// Option A: Without context message
throw new ExceptionInInitializerError(e);
// Option B: With context message
String msg = String.format("Failed to open file for reading: '%s'", _FILE_PATH);
throw new RuntimeException(msg, e);
}
}
}
Ref: Why doesn't Java allow to throw a checked exception from static initialization block?
As documented here, there is a constructor ExceptionInInitializerError(Throwable thrown), which you probably should be using instead: it conforms to standard exception chaining, which preserves the stack trace and does other useful stuff (see a sample chained-exception output).
Edit
As noted in this answer to the question you linked to: it is forbidden to allow a checked exception to fall out of a static block; unchecked exceptions are fine, but cannot be caught anywhere, unless one is doing manual dynamic class-loading with Class.forName (very uncommon).
This translates to "good luck catching anything you throw in a static initializer". Basically, whatever exception you construct and throw, it won't be much use.
You want to throw an exception with both a message (that you write) and the exception itself. I like to do the same, providing context for the error and the exception. I would throw an Exception (or an instance of an Exception class that extends Exception or a sub class), not RuntimeException since you probably want the exception to be checked. Right?
Generally speaking you should throw checked excpetions in cases where your system could potentially recover (at a higher level) from an exception and runtime exceptions (unchecked) when the system cannot. (James Gosling's view)
It's an Error. Generally errors are what an application shouldn't even try to catch and recover from.
As for why it doesn't have a constructor with both the message and cause, it's probably because the developers of that class didn't deem it necessary since the main purpose of that class is to let you know "oops shit happened bro, can't recover..."
Personally I think that one of those is enough to identify the error.

Java custom exception class usage [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Throws or try-catch
I'm writing an API and I wish to write code such that I can raise an exception in a particular scenario. I've created an exception class as follows :-
public class InvalidSeverityException extends Exception {
private static final long serialVersionUID = 1L;
public InvalidSeverityException() {
// TODO Auto-generated constructor stub
}
}
In the codebase im having the following to call the code :-
throw new InvalidSeverityException();
However Eclipse suggests that I either use throws or enclose it within a try ... catch block. I feel that I shouldn't be catching this error and that the developers who use my API should enclose the code within try...catch.
Does that make sense? Am I doing something wrong?
When handling with exceptions in Java you must understand the concept of checked exceptions and unchecked exceptions.
In your case currently you are defining a checked exception, maybe you want an unchecked one.
Here's a brief description about each one of the types:
Checked Exceptions
This exceptions must be part of the method's signature that raises them (or that invokes one method that does) or you must catch them with a try catch block and deal with the problem. Usually checked exceptions are used when there is something that can be done about the error and also when you want the developer to be aware that such error may occur and that has to be handled.
In java java.lang.Exception is a checked exception and all its subclasses will also be checked.
Unchecked Exceptions
This exceptions on the other hand don't need to make part of the method signature, nor you have to wrap methods that throw new in a try catch block. It's just expected that somewhere in the call stack there will be a try catch to handle it, otherwise if it reaches the JVM it will nicely dump you a stacktrace.
In java java.lang.RuntimeException is an unchecked exception and so are all its subclasses.
My opinion
If you are defining an API my suggestion is to use checked exceptions, this is mostly because you explicitly inform the developers using your API that such an exception might occur (so they can handle it anyway they want).
You are correct, you should not catch it. As suggested by eclipse, you should use throws so that the developers will know that your method potentially throws that exception and can then catch it.
.... method() throws YourException{
The method where you have throw new InvalidSeverityException(); should define throws InvalidSeverityException
Example:
void yourMethod() throws InvalidSeverityException
{
........//Some code
throw new InvalidSeverityException();
}
Well then surely you follow the first suggestion by Eclipse and set your method to throw the exception.
public void myMethod() throws InvalidSeverityException {
//throw it somewhere in here so that other
//developer can catch it while calling your method
}

Record instantiation of java.lang.Throwable transparently [duplicate]

How can I detect when an Exception has been thrown anywhere in my application?
I'm try to auto-magically send myself an email whenever an exception is thrown anywhere in my Java Desktop Application. I figure this way I can be more proactive.
I know I could just explicitly log and notify myself whenever an exception occurs, but I'd have to do it everywhere and I might(more likely will) miss a couple.
Any suggestions?
You probobly don't want to mail on any exception. There are lots of code in the JDK that actaully depend on exceptions to work normally. What I presume you are more inerested in are uncaught exceptions. If you are catching the exceptions you should handle notifications there.
In a desktop app there are two places to worry about this, in the event-dispatch-thread (EDT) and outside of the EDT. Globaly you can register a class implementing java.util.Thread.UncaughtExceptionHandler and register it via java.util.Thread.setDefaultUncaughtExceptionHandler. This will get called if an exception winds down to the bottom of the stack and the thread hasn't had a handler set on the current thread instance on the thread or the ThreadGroup.
The EDT has a different hook for handling exceptions. A system property 'sun.awt.exception.handler' needs to be registerd with the Fully Qualified Class Name of a class with a zero argument constructor. This class needs an instance method handle(Throwable) that does your work. The return type doesn't matter, and since a new instance is created every time, don't count on keeping state.
So if you don't care what thread the exception occurred in a sample may look like this:
class ExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
handle(e);
}
public void handle(Throwable throwable) {
try {
// insert your e-mail code here
} catch (Throwable t) {
// don't let the exception get thrown out, will cause infinite looping!
}
}
public static void registerExceptionHandler() {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
System.setProperty("sun.awt.exception.handler", ExceptionHandler.class.getName());
}
}
Add this class into some random package, and then call the registerExceptionHandler method and you should be ready to go.
The new debugging hooks in Java 1.5 let you do this. It enables e.g. "break on any exception" in debuggers.
Here's the specific Javadoc you need.
Check out Thread.UncaughtExceptionHandler. You can set it per thread or a default one for the entire VM.
This would at least help you catch the ones you miss.
If you're using a web framework such as Spring then you can delegate in your web.xml to a page and then use the controller to send the email. For example:
In web.xml:
<error-page>
<error-code>500</error-code>
<location>/error/500.htm</location>
</error-page>
Then define /error/500.htm as a controller. You can access the exception from the parameter javax.servlet.error.exception:
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
If you're just running a regular Java program, then I would imagine you're stuck with public static void main(String[] args) { try { ... } catch (Exception e) {} }
If you are using java 1.3/1.4, Thread.UncaughtExceptionHandler is not available.
In this case you can use a solution based on AOP to trigger some code when an exception is thrown. Spring and/or aspectJ might be helpful.
In my current project I faced the similar requirement regarding the errors detection. For this purpose I have applied the following approach: I use log4j for logging across my app, and everywhere, where the exception is caught I do the standard thing: log.error("Error's description goes here", e);, where e is the Exception being thrown (see log4j documentation for details regarding the initialization of the "log").
In order to detect the error, I use my own Appender, which extends the log4j AppenderSkeleton class:
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
public class ErrorsDetectingAppender extends AppenderSkeleton {
private static boolean errorsOccured = false;
public static boolean errorsOccured() {
return errorsOccured;
}
public ErrorsDetectingAppender() {
super();
}
#Override
public void close() {
// TODO Auto-generated method stub
}
#Override
public boolean requiresLayout() {
return false;
}
#Override
protected void append(LoggingEvent event) {
if (event.getLevel().toString().toLowerCase().equals("error")) {
System.out.println("-----------------Errors detected");
this.errorsOccured = true;
}
}
}
The log4j configuration file has to just contain a definition of the new appender and its attachement to the selected logger (root in my case):
log4j.rootLogger = OTHER_APPENDERS, ED
log4j.appender.ED=com.your.package.ErrorsDetectingAppender
You can either call the errorsOccured() method of the ErrorsDetectingAppender at some significant point in your programs's execution flow or react immidiately by adding functionality to the if block in the append() method. This approach is consistent with the semantics: things that you consider errors and log them as such, are detected. If you will later consider selected errors not so important, you just change the logging level to log.warn() and report will not be sent.
In this case I think your best bet might be to write a custom classloader to handle all classloading in your application, and whenever an exception class is requested you return a class that wraps the requested exception class. This wrapper calls through to the wrapped exception but also logs the exception event.
I assume you don't mean any Exception but rather any uncaught Exception.
If this is the case this article on the Sun Website has some ideas. You need to wrap your top level method in a try-catch block and also do some extra work to handle other Threads.
Sending an email may not be possible if you are getting a runtime exception like OutOfMemoryError or StackOverflow. Most likely you will have to spawn another process and catch any exceptions thrown by it (with the various techniques mentioned above).
There is simply no good reason to be informed of every thrown exception. I guess you are assuming that a thrown exception indicates a "problem" that your "need" to know about. But this is wrong. If an exception is thrown, caught and handled, all is well. The only thing you need to be worried about is an exception that is thrown but not handled (not caught). But you can do that in a try...catch clause yourself.

Custom Java exception printing when thrown

I want to design it such that whenever one of my custom exceptions is thrown, it automatically prints the stacktrace to a file. Is there a method I can override to accomplish this? Doing this would help to reduce a noticable amount of code in my project.
You can have your custom exceptions inherit from RuntimeException, then set the UncaughtExceptionHandler on the relevant Threads to look for your exceptions and handle them however you like.
The stacktrace is available as soon as you call the constructor of your exception. You can't react to the event of being thrown, but you can write the stacktrace inside your constructor.
If you have a common exception class that's the base of all your custom exceptions then you could do all this in its constructor.
Is there a method I can override to accomplish this?
Yes, the printStacktrace() method.
You can create a base class for your exceptions and them call to an "internal" print that would be redeirected to your file.
You can use a Logger and have that specific logger pointing to the file you desire ( and change it, disable it , re-enable it, etc when you need to )
Something along the lines:
class MyStackTrace extends Throwable {
public void printStacktrace() {
super.printStracTrace();
internalPrint();
}
private void internalPrint() {
StringWriter sw = new StringWriter();
printStackTrace( sw );
Logger logger = Logger.getLogger("exceptions");
logger.warning( sw.toString() );
}
}
I can'r help you print a stack trace when an exception is thrown. But it's easy enough to do when the exception is constructed - Just include the printStackTrace() in your custom exception's constructor.
In general, this is not a great idea to log on every exception creation. The catcher should really decide what is the best handling of an exception. Also overriding the method in exception and logging to a file breaks the general contract around exception.
On a side note, you may discover some horrible performance problem related to logging at later stage. Given overriding happens in a central place you will have hard time fixing this.
If you still want to log while throwing the exception then the better solution is to use/create a utility class like Throwables. Call the code as Throwables.logAndThrow(new CustomerException(...)), same one line of code but flexible for the long term. logAndThrow could be as simple as, using the logger technique of previous poster:
public static void logAndThrow(Throwable t) {
logger.warning(t);
throw t;
}

Categories

Resources