I am programming a Java Servlet application which needs certain environment variables and JNDI definitions to be present. These are defined in server.xml file. Using default values is not possible. So the program needs to throw a runtime (unchecked) exception. But which one? If none of the subclasses of java.lang.RuntimeException is suitable, I guess we will need to create a new type.
You could use exceptions already defined, but I just usually implement my own, because I can always quickly recognize it when it is thrown. (It tells you more, just by having your project's classpath.)
public class MissingInitialContextException extends RuntimeException {
public MissingInitialContextException() {
}
public MissingInitialContextException(String message) {
super(message);
}
public MissingInitialContextException(String message, Throwable cause) {
super(message, cause);
}
public MissingInitialContextException(Throwable cause) {
super(cause);
}
public MissingInitialContextException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
You can auto generate classes like this in most IDE. (IDEA, after you created the class, ALT+ENTER and override methods from the RuntimeException class)
Why use custom exceptions.:
You can use your IDE's find implementations and other search functions to locate usages
In some frameworks, like in Spring Boot, you can decorate your exceptions with annotations and quickly define the response text and http error code.
You can change the exception's implementation later.
You can define automatic break on exception in your IDE for your custom exception, while if you would do this for a built in one, your debugger would stop in unexpected lines.
You can avoid unintentionally catching other library's exceptions.
java.lang.NullPointerException
When the configuration of the application is not (yet) complete the variables will probably be null, a NullPointerException seems appropriate. This exception is pretty generic but can be customized with a specific detail message in the constructor.
From the API:
Applications should throw instances of this class to indicate other illegal uses of the null object.
When accessing or modifying the field of a null object.
throw new NullPointerException("environment variable XX is missing");
Related
This is a plain Java 8+ question, no frameworks used.
We are producing an API for a higher layer which deals with the presentation layer among other activities. We have and interface agreed with the invoker, so they are happy to receive some particular exceptions we throw.
At the same time, we are also using other APIs under the same agreement, so we can do stuff by ourselves and throw exceptions or we can invoke other APIs which throw the agreed exceptions.
Currently, we do nothing with the exceptions thrown by the APIs we are invoking.
Thing is, we are the best positioned in this infrastructure to deal with intermediate activities while exceptions are thrown, so we need to capture both, our exceptions and the exceptions provided by those we are invoking; basically reporting the issue, raising system controls, etc, and then re-throw the original exception so the top layer keeps as it is now.
We have around 300 methods in the entry point class of our API:
public void method1 (arguments for method 1) {
...
}
...
public void method300 (arguments for method 300) {
...
}
I clearly understand that I can create a method to centralise the actions to be taken in the exception management, something like:
public void myExceptionHandler (Exception e) {
if (e instanceOf X) {
} else if ...
...
throw particularExceptionAccordingTheCase
}
But I'd also avoid modifying those 300 methods.
Any idea how to inject a try-catch in those 300 methods to send the Exception to myExceptionHandler without really adding a try-catch in each of them?
Any comments and ideas are much appreciated!
----------- After mprev0 suggestion -------------------------------
I tried this approach. It really catches the exception and so on, but I can't re-trow an Exception: I'm forced to catch it, but this goes against the requirement of re-sending the exception back to the top layer.
While I can throw an Error, I got a compiler error at line throw new FileNotFoundException();
public class myExceptionHandler implements Thread.UncaughtExceptionHandler {
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("gotcha!");
if (e instanceof java.lang.Error) {
System.out.println("AAT-CORE: Fatal Error");
throw new java.lang.Error(e.getCause());
} else if (e instanceof java.lang.Exception) {
System.out.println("AAT-CORE: Exception Error");
throw new FileNotFoundException();
}
}
}
Any ideas?
------------ After some more digging, fixed with a decorator pattern -------
Previous class implementation does not work, as I can't change the signature of the method and I need to re-throw the java.lang.Exception.
Using a decorator and handling the interface there makes the trick.
As a summary:
Top layer class:
public class TopLayer {
public static void main (String[] args) {
MiddleLayer m = new MiddleLayer();
m.method1();
}
}
Bottom layer class contains specific APIs and some implementation, the only interesting thing is that it contains java.lang.Exceptions uncontrolled, expecting the top layer to do this job. But, we are working in the middle and we will do this job:
public class MiddleLayer extends BottomLayer {
public MiddleLayer () {
final UncaughtExceptionHandler subclass = Thread.currentThread().getUncaughtExceptionHandler();
Thread.currentThread().setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
System.out.println("gotcha2!");
// carry on with prior flow
subclass.uncaughtException(thread, ex);
}
});
}
}
In this way, I can get the system.out and the java.lang.Exception is propagated to the Top Layer.
Decorator inspiration came from here: Rethrow UncaughtExceptionHandler Exception after Logging It
Additional comments are welcome!
You can solve this by implementing the java.lang.Thread.UncaughtExceptionHandler interface:
public class MyExceptionHandler implements Thread.UncaughtExceptionHandler {
#Overrides
public void uncaughtException(Thread t, Throwable e) {
if (e instanceOf X) {
} else if ...
...
throw particularExceptionAccordingTheCase
}
}
Then you associate it to all threads as follows:
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler())
This will configure the exception handler to handle all uncaught exceptions in all threads of your application.
Note that this will only work for exceptions that aren't yet explicitly handled somewhere in your code and if there is no other handler configured for some particular thread (the uncaught exception handler can also be set for some specific thread).
EDIT: As discovered by #JBC, the above approach will not work for checked exceptions since we are forced to catch them explicitly in our uncaughtException method (note that we cannot add a throws clause to an overridden method). While it will work without problems if we only want to re-throw subtypes of RuntimeException and Error, there is a little adaptation needed if we want to make it work - you can find it explained in #JBC's question.
As you can see in the question updates, the final solution is a combination of two different approaches, in one side, having the mprev0 approach of implementing the java.lang.Thread.UncaughtExceptionHandler and, on top of this, adding a Decoration pattern to be able to re-throw a run-time exception.
There were no additional approaches so far, so I'm closing the question and bring this as the most complete response.
More information about UncaughtExceptionHandler can be found in the Java documentation, but as always, is short on examples, and here:
Advanced exception handling
Thread.UncaughtExceptionHandler Example
More information on Decorator pattern usage, can be found here:
Decorator Design Pattern in Java
Design Patterns - Decorator Pattern
And how to use to manipulate exceptions here:
Rethrow UncaughtExceptionHandler Exception after Logging It
You could also create a proxy API on top of your current API, have an invocation handler method in the proxy and put this method in a try catch block.
https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/proxy.html
https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html
I have a custom exception class written as
public class MyCustomException extends RuntimeException {
public MyCustomException(Throwable cause) {
super(cause);
}
enter code here
/**
* #param message
* #param cause
*/
public MyCustomException(String message, Throwable cause) {
super(message, cause);
}
}
In my serviceImpl layer
#Override
public List<SiteDetails> getSite() throws MyCustomException {
}
SONAR (Ecplise IDE plugin for linting) states:
Remove the declaration of thrown exception '.MyCustomException' which
is a runtime exception
Should I remove the declaration or should I extend Exception in MyCustomException class instead of RunTimeException?
The sonar issue is very very primarily opinion based.
A RuntimeException is not forced to be handled and so declared but it is not a bad practice to declare it in a method to document this case.
Should I remove the declaration or should I extend Exception in
MyCustomException class instead of RuntimeException
If you deem that MyCustomException is an exception that has to be necessarily handled by the client, MyCustomException should derive from Exception rather thanRuntimeException .
Otherwise if the exception cannot be handled by the client in most of circumstances, you should remove the declaration to make Sonar Happy or mark (at least trying) this issue as a false positive if you think that it makes sense to convey the exception even if it is a RuntimeException.
I had same situation, you have to catch the runtime exception, in my case was an Array Out Of Bound Exception due to I'm parsing a string separated from special char value but sometimes the string value is not corresponding to the right convention, right? So I must handle it, but Sonar was blaming me for the same reason! ArrayIndexOutOfBoundsException is derived from runtime exception
, anyway once you know that your block of code could retrieve some runtime exception, instead of throw it directly, use a catch block and into this just throw your custom exception.
catch (ArrayIndexOutOfBoundsException e) {
throw new YourCustomException("your message",e);
}
In this way you can remove the throws signature on your method, and Sonar will be happy
I had a discussion with one of the seniors on Exception in Java on concept
If I create a class by extending Exception class then it will be checked exception
If I create a class by extending Throwable,RuntimeException, or Error, then it will be unchecked Exception
Is the above statements correct ?
Note: I have through this link When to choose checked and unchecked exceptions
EDIT:
While going through the answer #Daemon, he says
'Throwable on the other hand, is extended by Exception, and is therefore a checked exception.'
I have a question : Throwable is extended by Error also, so why not it is Unchecked ?
Anything that extends Exception but does not extend RuntimeException. Error and Throwable should not be used by Java programs, as Error is intended to communicate serious, unrecoverable problems such as completely running out of memory, hardware problems, or the like.
Technically, only classes that extend Exception are exceptions; Errors and other Throwables are not exceptions and are not expected to be caught by regular programs.
You are correct that any class extending Exception will be a checked exception, however you are mistaken with your next statement:
If I create a class by extending Throwable,RuntimeException, or Error, then it will be unchecked Exception
If you extend RuntimeException or Error, your class will be a unchecked exception.
Throwable on the other hand, is extended by Exception, and like Exception is a checked exception.
The below code demonstrates these practically. For more information, Barry Ruzek's "Effective Java Exceptions" makes for some very interesting reading on the subject.
public class JavaExceptions {
public static void throwException() throws Exception {
throw new Exception("This is a Checked Exception.");
}
public static void throwRuntimeException() throws RuntimeException {
throw new RuntimeException("This is a Runtime Exception.");
}
public static void throwError() throws Error {
throw new Error("This is an Error.");
}
public static void throwThrowable() throws Throwable {
throw new Throwable("This is a Throwable.");
}
public static void main (String... args) {
//Exception extends Throwable, thus both are checked Exceptions.
try {
throwThrowable();
throwException();
} catch (Throwable e) {
//Handle exception (or throwable in this case)...
e.printStackTrace();
}
//RuntimeException and Error are both unchecked exceptions.
throwRuntimeException();
throwError();
}
}
EDIT 1: In regards to Error and its use, this is taken from Oracle's Documentation:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur. That is, Error and its subclasses are regarded as unchecked exceptions for the purposes of compile-time checking of exceptions.
EDIT 2: The classes we are dealing with here can be described as follows:
Throwable extends Object: Top-level class that should be extended by any class that needs to be thrown (like Exceptions and Errors). Throwables are checked. See: Throwable (Java Platform SE 7)
Error extends Throwable: A subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Overides Throwable functionality to become unchecked. See: Error (Java Platform SE 7)
Exception extends Throwable: Another subclass of Throwable that indicate conditions that a reasonable application might want to catch. Like Throwable, is checked. See: Exception (Java Platform SE 7)
RuntimeException extends Exception: The superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine. Overrides Exception functionality to become unchecked. See: RuntimeException (Java Platform SE 7)
From the oracle documentation: "For the purposes of compile-time checking of exceptions, Throwable and any subclass of Throwable that is not also a subclass of either RuntimeException or Error are regarded as checked exceptions. " So, your first statement is correct, the second is not.
You can read more in the SCJP Sun Certified Programmer for Java 6 pg. 356-380.
If I create a class by extending Exception class then it will be
checked exception
This is Correct.
If I create a class by extending Throwable,RuntimeException, or Error,
then it will be unchecked Exception
This is incorrect. The class RuntimeException and its subclasses, and the class Error and its subclasses are unchecked exceptions classes. Because the compiler doesn’t forces them to be declared in the throws clause. All the other exception classes that are part of Throwable hierarchy are checked exceptions.
Exception class and Error class both extends Throwable class. RuntimeException class extends Exception class. Checked exceptions should be handles using try catch or throws in compile time. No need for that handling for RunTimeExceptions. Errors should not be handled but let them occur cause they are serious things.
I am a c++ developer and I am pretty new with the checked and unchecked exception in java. The exception specifications in c++ are simply not good and that's why nobody is using it. I like the checked exception and I have a question, let's have this interface:
public interface Warehouse {
MyStuff fetch(int id);
}
The warehouse can be implemented in different way: file, database or in memory (mock object for test).
Now, if I want to implement using a file, I cannot try to open the file in the method otherwise my signature will change and my class will not implement the interface anymore. Also if I had another class with another checked exception all the other existing implementation will be affected.
I can see two solutions:
Catch the checked exception and throw another custom runtime exception. I don’t think this is a good solution, why the user should catch a runtime exception saying that a file is missing when there is already a standard and checked way to do that.
Do the entire job in the constructor of the implementation class and leave the fetch function unable to throw. I like this way, the object both exists and is valid or it doesn’t exist. The only drawback on this approach is that we cannot implement a lazy evaluation; we need to read and parse the file in the constructor even though nobody will use the object. This is not efficient.
Am I missing something? Is there a better way to avoid this problem?
Your first solution is the right one. Change your interface to :
public interface Warehouse {
MyStuff fetch(int id) throws FetchFailureException;
}
And make every subclass wrap its IO, JDBC or whatever exception inside a FetchFailureException. This FetchFailureException exception should be runtime if unrecoverable, and checked if recoverable.
Personally, I would have Warehouse list all the exceptions it can throw (including unchecked ones in the javadoc)
If you have an exception which is not listed, you need to handle it or wrap it. (Whether its checked or not)
You have to make your mind up whether you want Warehouse to throw an checked exception or not. You can't have it both ways. (Actually you can but its not a good idea as you can blindly throw a checked exception without the compiler knowing)
The Best practice is to specify the exceptions which the method will be throwing in the interface.
Suppose you have a custom Exception class :
class MyException extends Exception { public MyException
(String message) { super(message); } public
MyException (String message, Exception cause) { super(message,
cause); }
}
Handle all your exceptions in MyException class,
Now you can specify the exception which your method should throw in the interface
public Interface Warehouse
{
public MyStuff fetch() throws MyException;
}
I would suggest you to include in the Warehouse class all the exceptions and then working with subinterfaces in order to work with non checked exceptions, like this:
public interface Warehouse {
MyStuff fetch(int id) throws FileNotFoundException;;
}
public interface FileWarehouse extends Warehouse {
#Override
MyStuff fetch(int id) throws FileNotFoundException;
}
public interface OtherWarehouse extends Warehouse {
#Override
MyStuff fetch(int id);
}
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.