How can you manage that complexity? Your first thoughts probably go to application monitoring and performance tools. Yet that is not a complete solution. To manage application complexity fully, you also need exception monitoring. Without exception monitoring, you’ll never stay ahead of the complexity of modern applications.
Let me explain why?
Access to failure data
Lots of monitoring tools exist to help you identify and troubleshoot issues across all application layers. However, most of these tools are designed to show you the overall system state. Only logs, and exceptions in particular, offer insight into a finer level of detail.
By definition, an exception is an event which occurs during the execution of a program that disrupts the normal flow of the program’s instructions.
Exceptions are used to indicate many different types of error conditions across all the application layers: out of memory, stack overflow, IO problems, null pointer exceptions, network timeouts, and many others. They could indicate system problems, problems in application logic, operating system problems, connectivity problems, and so on.
When an exception occurs within a method, the method creates an object and hands it off to the runtime system. The exception object contains information about the error, including its type and the state of the program when the error occurred. Therefore, exceptions— handled or not—provide access to very useful raw data that can be used for:
- Early error detection and prevention
- Root cause analysis when problems occur
- Reconstructing events after a problem occurred
- Identifying security problems
- Forensic evidence
Ace your coding skills with Entri !
Early problem detection
Many production problems build up gradually. Monitoring tools can often provide an indication that something is awry by monitoring metrics such as CPU load, RAM and storage access and network activity and connectivity, but that information alone can generally not be used to pinpoint the source of a problem. As a result, you run the risk of waiting until a problem becomes critical before you begin looking for the source.
Exception monitoring offers another better way of gaining early insight into production problems. By monitoring exceptions, you can trace a performance issue to its root case, thereby gaining the time and means to spot the problem before it reaches a tipping point and impacts your users or company.
Grab the opportunity to learn Java with Entri! Click Here
Impact on application performance
Quite often, an app throws a lot of exceptions that might be harmless in terms of application functionality. Sometimes they are even referred to as “good” exceptions.
However, exception throwing requires stack trace propagation, which basically means that your app pauses to walk back the stack to collect information which will be used to create the stack trace. While this timeout in thread execution is insignificant as a singular event, it can create huge performance overhead on a large scale.
Therefore, “good” exceptions can have a major impact on an application’s performance, and shouldn’t be left unattended.
Ace your coding skills with Entri !
Exception Tracking and security
Also worth noting is how important exception monitoring is from a security perspective. Following are a couple of reasons why.
Hackers can use information exposed by error messages
Application failure often results in throwing an exception. Detailed error messages can provide attackers with useful information such as stack traces, privacy information, and sometimes even passwords, which can lead to security vulnerabilities such as enumeration, buffer attacks, sensitive information disclosure, etc. Even HTTP 404 can expose your server to attacks. While good code is supposed to not allow exceptions to go unhandled, in practice, it’s nearly impossible to anticipate all the cases when an exception could be thrown, and control its content. Furthermore, with all honesty, error handling is rarely robust enough to survive a penetration test. Therefore, actively monitoring your logs for this kind of exposure and taking action to fix it immediately can prevent hacker attacks and drastically improve your system’s security.
Grab the opportunity to learn Java with Entri! Click Here
Identifying hacker attacks
In spite of all your efforts, if your system has been hacked, logs are often the only record that suspicious behavior is taking place, even if the system still works fine and all the monitoring tools show no problems. For this reason, monitoring exceptions may be your best shot at identifying when your system is being hacked.
The specifics of identifying such suspicious behavior depend on your application’s functionality, but generally you should be looking for any sign of abnormalities in your log files: new error messages and exceptions that could indicate elevation of access privileges, bulk downloads, privacy violations, etc.
Logs are also useful in reconstructing events after a problem has occurred, and as forensic evidence. Event reconstruction can allow a security administrator to determine the full extent of an intruder’s activities and expedite the recovery process.
Types of Exceptions in Java – Checked, Unchecked, & Error
Now, we will learn about the different types of exceptions in Java checked exceptions, unchecked exceptions, and errors.
Exceptions can happen in any scenario, and all developers would have come across exceptions, for example, whenever we try to read a file that doesn’t exist or whenever we try to read the elements in an array beyond its size and so on.
It is always better to know which exception occurs in which situation so that we will have better control in handling the exception.
Ace your coding skills with Entri !
Types of Exceptions in Java
Exceptions can be divided into three main categories
- Checked exceptions (Compile-time exceptions)
- Unchecked exceptions (Runtime exceptions)
- Errors
All the exceptions descend from the Throwable class, and then the hierarchy splits into two branches Error and Exception.
Error hierarchy describes the internal error or any resource exhaustion or any other malfunction which happens in the JVM. On the other hand, the Exceptions branch further splits into two IOException and Runtime exceptions.
Except for the Error and RuntimeException and its subclasses, all other classes will be a part of Checked Exception (Compile-time exception).
Checked Exception happens on the occurrence of events which is beyond the control of the JVM like File not present or reading from the database where there might be a situation that the database is down etc.
Whereas Runtime Exception happens due to bad programming such as not handling null properly, dividing a number by zero, etc.
Grab the opportunity to learn Java with Entri! Click Here
1. Checked Exception or Compile Time Exception
A Checked Exception or Compile-Time Exception is a subclass of the java.lang.Exception but not a subclass of java.lang.RuntimeException.
Checked Exception is the exception that will be checked during the compile-time, if a method throws a checked exception then the calling method must have one of the below
- A try-catch block to handle the exception
(or)
- Throw the exception using throws keyword in the method signature
A checked exception occurs whenever we are doing some operation that is not in the control of the JVM.
For example, Let’s try to open a file.
package com.javainterviewpoint; import java.io.FileInputStream; public class FileRead { public static void main(String[] args) { FileInputStream fileInputStream = new FileInputStream("test.txt"); } }
The above code throws a compile-time exception “FileNotFoundException”, as there can be a possibility of file not present at the mentioned location.
When we look at the constructor of FileInputStream,
public FileInputStream(String name) throws FileNotFoundException { this(name != null ? new File(name) : null); }
The declaration says that the above constructor produces the FileInputStream object using the string parameter passed, and in case of any issues, it will throw FileNotFoundException.
In order to make the above code work we need to enclose it in the try-catch block or throw the exception
package com.javainterviewpoint; import java.io.FileInputStream; import java.io.FileNotFoundException; public class FileRead { public static void main(String[] args) { try { FileInputStream fileInputStream = new FileInputStream("test.txt"); } catch (FileNotFoundException e) { e.printStackTrace(); } } }
2. Unchecked Exception or RunTimeException
A Runtime Exception or Uncheck Exception is a subclass of java.lang.RunTimeException class. Runtime exception usually occurs because of bad programming or programming error.
Since the Unchecked exceptions happen during the run time, we don’t need to throw the exception in the method signature, though we can do it but not mandatory.
For example, NullPointerExecption is a type of RunTimeException which occurs when a variable is not assigned an object and still points to null.
package com.javainterviewpoint; public class NullTest { public static void main(String[] args) { String name = null; System.out.println(name.length()); } }
The above code clearly shows that the exception occurred due to bad programming. A simple null check before performing any operation on the variable will sort out the issue.
package com.javainterviewpoint; public class NullTest { public static void main(String[] args) { String name = null; if (name != null) System.out.println(name.length()); } }
Like the Checked exception, we can use a try-catch to catch the runtime exception.
package com.javainterviewpoint; public class NullTest { public static void main(String[] args) { String name = null; try { System.out.println(name.length()); } catch (NullPointerException ne) { System.out.println("NullPointerException has occured!!"); } } }
Grab the opportunity to learn Java with Entri! Click Here
3. Error
An Error is a subclass of java.lang.Error class. The Error indicates a severe issue that cannot be controlled through the code.
For example, OutOfMemoryError occurs when the Java Heap space is full, StackOverflowError is another error which the JVM throws when the stack required for the program is higher than the memory allocated by the JRE.
package com.javainterviewpoint; public class StackOverFlow { public static void main(String args[]) { disp(); } public static void disp() { disp(); } }
The above code eventually throws StackOverFlowError as the disp() method runs infinite number of times.
Exception in thread "main" java.lang.StackOverflowError at com.javainterviewpoint.StackOverFlow.disp(StackOverFlow.java:12) at com.javainterviewpoint.StackOverFlow.disp(StackOverFlow.java:12) at com.javainterviewpoint.StackOverFlow.disp(StackOverFlow.java:12) at com.javainterviewpoint.StackOverFlow.disp(StackOverFlow.java:12) at com.javainterviewpoint.StackOverFlow.disp(StackOverFlow.java:12) at com.javainterviewpoint.StackOverFlow.disp(StackOverFlow.java:12) at com.javainterviewpoint.StackOverFlow.disp(StackOverFlow.java:12)
Tough Error represents a severe issue, and we should not handle it, we can still catch the Error like below.
package com.javainterviewpoint; public class StackOverFlow { public static void main(String args[]) { try { disp(); } catch (StackOverflowError se) { System.out.println("StackOverflowError has occured!!"); } } public static void disp() { disp(); } }
In Java, an Exception is essentially an event that occurs during the execution of a program and disrupts the program’s normal flow. Exceptions are unwanted and mostly unexpected, which generally arise at either run- or compile-time. All of these Exceptions need to be handled to ensure the program runs in its natural flow.
However, before you handle Exceptions, it would help to know what different kinds of Exceptions are present with Java. Through this article, let’s look at the various types of Exceptions in Java and the Exception Hierarchy that they follow.
Exceptions Hierarchy in Java
The hierarchy of Exceptions in the Java programming language begins with the Throwable class – which comes from the Object class and is its direct subclasswhileThe Exception class presents all This Throwable class further branches into two subclasses – Error and Exception. Here’s a flowchart to understand the Java Exception hierarchy better:
The Exception class presents all the Exceptions that you might need to handle while working with the Java programming language. Some commonly known and encountered examples of such Exceptions include NullPointerException, ClassNotFoundException, IllegalArgumentException, etc.
On the other hand, the Error class takes care of more severe problems in your Java program architecture and is not taken care of within the application code. Some examples of errors in Java are InternalError, AssertionError, OutOfMemoryError, etc.
Exceptions in Java are further divided into two categories:
- Checked Exceptions – These are also known as compile-time exceptions.
- Unchecked Exceptions – These are also known as runtime exceptions.
One important point to note at this juncture is that unchecked Exceptions are all subclasses of the RuntimeException class. Now, let’s look at essentially how Errors and Exceptions differ in their working so that there is no confusion.
Grab the opportunity to learn Java with Entri! Click Here
Errors and Exceptions in Java – How Do They Differ?
The official documentation of the Java programming language refers to Errors as occurrences during your Java programming that – “indicate serious problems that a reasonable application should not try to catch.” The seriousness of Errors is clear from the way this statement is poised. Clearly, this refers to the set of problems that your program might face that is not possible for it to recover from without either refactoring the code or modifying the Java application architecture.
Let’s look at a Java method that is going to throw an error:
public static void print(String S) {
print(S);
}
In the code mentioned above, the method print() acts as a recursive method that keeps calling itself repeatedly, over and over again, until it reaches the maximum allowed size for a thread stack in Java. At that point, it exits execution with a very common – StackOverflowError, which reads something like:
Exception in thread “main” java.lang.StackOverflowError
at StackOverflowErrorExample.print(StackOverflowErrorExample.java:3)
As the above example shows, the method throws an example, but this error cannot be handled in the code itself. So, the program simply quits execution because the damage is irrecoverable. As a solution, the code needs to be modified.
Contrary to Errors, Exceptions indicate conditions that can be caught by a reasonable application. Exceptions in Java include issues that might occur either at the compile-time or during run time. These Exceptions happen rather frequently in all applications – especially during the testing and debugging phase. As a result, Exceptions in Java can be handled within the program itself to ensure that the code runs its natural flow.
Ace your coding skills with Entri !
Conclusion
Please keep in mind that this is by no means comprehensive coverage of Exceptions in Java and how to go about handling them. For that, you should dig deeper and expose yourself to different possible Exceptions to see how they work. Knowing Exception Handling will set you up for a successful career as a full-stack developer since Exceptions form the basics of any application.