Take A Look Into Java Runtime Errors

A quick overview of the Java Runtime Errors

Mouad Oumous
The Fresh Writes
11 min readFeb 24, 2023

--

· What are Runtime Errors in Java?
· Runtime Error VS Compile-Time Error
· Types of Runtime Errors
· How runtime error appears?
· Do i need to throw Runtime Errors
· What happend when you don’t catch a Runtime Exceptions
· Runtime Error Example

What are Runtime Errors in Java?

The errors that occur at the time of program execution are referred as runtime errors. These types of errors can’t be detected at the compile time as there is nothing wrong with their syntax. So Runtime errors occur when the program has successfully compiled without giving any errors and creating a “.class” file. However, the program does not execute properly. These errors are detected at runtime or at the time of execution of the program.

The Java compiler does not detect runtime errors because the Java compiler does not have any technique to catch these errors as it does not have all the runtime information available to it. Runtime errors are caught by Java Virtual Machine(JVM) when the program is running.

These runtime errors are called exceptions and they terminate the program abnormally, giving an error statement.

Exceptions are errors thrown at runtime. We can use exception handling techniques in Java to handle these runtime errors. In exception handling, the piece of code the programmer thinks can produce the error is put inside the try block and the programmer can catch the error inside the catch block.

Runtime Error VS Compile-Time Error

A compile-time error generally refers to the errors that correspond to the semantics or syntax. A runtime error refers to the error that we encounter during the code execution during runtime. We can easily fix a compile-time error during the development of code. A compiler cannot identify a runtime error.

Detection

Compilers can easily detect compile-time errors during the development of code.A compiler cannot easily detect a runtime error. Thus, we need to identify it during the execution of code.

Reference

A compile-time error generally refers to the errors that correspond to the semantics or syntax.A runtime error refers to the error which are not detected by the compiler but we encounter them during the code execution (during runtime).

impact

Compile-Time Errors are semantics or syntax errors, they prevent the code from running (compiling) as it detect some syntax errors. Wheares Runtime Errors prevent the code from complete execution.

Fixation

We can easily fix a compile-time error during the development of code.A compiler cannot identify a runtime error. But we can fix it after the execution of code and identification of the code in prior.

Types of Runtime Errors

There are multiple types of runtime errors that we can face at the time of program execution. Some frequently encountered runtime errors are listed below:

Data entry errors : Input-output errors

There are innumerable ways user input can corrupt an application.

On an HTML-based comment board, a user who is allowed to innocently submit an unencoded less than (<) or greater than sign (>) has the potential to completely ruin the ability of that webpage to render. Similarly, text-processing systems built to expect all input in ASCII format can prematurely terminate if they receive emojis or nonstandard character inputs.

More nefariously, a favorite attack vector of hackers is SQL injection, which hides a harmful executable database query inside an otherwise innocuous input field. This not only can cause an application to fail, but potentially surrender control of the entire data layer.

The process of input sanitization, or data scrubbing, converts the broad spectrum of data that could potentially be entered into applications into a safe range of values that a program comprehends. Use of such libraries helps mitigate runtime errors caused by input sanitization failures.

Popular Java frameworks such as Apache BVal and Hibernate Validator perform simple, annotation-based input cleansing, and they integrate easily into any Java-based application.

Poorly implemented logic

Just because code compiles doesn’t mean it works properly. Code often contains logical problems that cause an application to fail at runtime.

Java contains a built-in construct to handle a class of common code-related runtime errors, called the RuntimeException, or the unchecked exception. Java 17 defines 78 such errors in the SDK alone, and other projects and frameworks additionally define their own RuntimeException errors.

  • RuntimeException
  • ArrayIndexOutOfBoundException
  • ConcurrentModificationException
  • ClassCastException

Developers are not required to handle unchecked exceptions in their code. But an unchecked exception that is thrown and ignored will terminate an application.

At the very least, every application should include a generic exception harness that can catch every possible RuntimeException, log the error and allow the problematic thread of execution to die rather than abort the entire application.

Insufficient runtime resources

Software developers don’t shoulder the blame for every type of runtime error that occurs. Many runtime errors in Java involve resource limitations caused by problems with the underlying infrastructure. Examples include: network timeouts, out of memory conditions, CPU overutilization or an inability to schedule a thread on the processor.

One way to avoid resource-related runtime errors is to use a load testing tool, such as JMeter or LoadRunner, in an application’s CI/CD pipeline. If these tools detect a possible performance problem, they can stop the application before it moves further down the pipeline toward production deployment.

Some applications’ load varies drastically. For example, a financial services app may see steady load most of the time but be extremely busy at the end of trading day. A tax service might hit a peak load before the filing deadline but have relatively little load the rest of the year.

DevOps teams must monitor their performance metrics with tools to preemptively detect and mitigate resource-related runtime errors. Examples of such tools include JDK Flight Recorder and Java Mission Control.

For applications with completely unpredictable workloads, use cloud-based load balancing technology to allocate resources elastically. This eliminates both underallocated resources, and the trap of purchasing expensive, rarely used hardware.

External resource configuration

Enterprise applications rarely exist in an isolated bubble. They typically interact with everything from NoSQL databases and relational systems to Kafka queues and RESTful APIs. Unfortunately, if your application is unable to connect to a required, external system, this inevitably results in a runtime error.

An external resource can precipitate a runtime error if any of the following situations occur with no corresponding update to the calling program:

  • an IP address changes;
  • credentials change;
  • firewall configuration change; or
  • the external system goes down for maintenance.

Applications should react nimbly when resources change. The 12-Factor App insists developers keep all configuration data external to the application so that applications can react nimbly when resources change. The ability to update property files without changing the codebase allows applications to deal with external resource changes, and avoids an application rebuild.

Relatedly, chaos engineering tools randomly terminate the processes upon which an application depends. Such tools force developers to write code that remains responsive and resilient even when external systems fail.

The inherent problem with external resources is that developers cannot control them — but they can control how an application responds when those external resources fail. Anticipate runtime errors generated by the systems you don’t control, and write applications that respond gracefully when those external systems fail.

Third-party library vulnerabilities

Any nontrivial enterprise application includes dozens of dependencies on third-party libraries to perform functions such as logging, monitoring, input validation, form handling and more.

Unfortunately, any bugs in a third-party library become a bug in the application you deploy. This became uncomfortably real for the Java world in December 2021, as an LDAP inject flaw in the widely used Log4j 2 library forced JVMs throughout the world to go offline.

One way to mitigate against the possibility that software dependencies introduce runtime errors into applications is to only use trusted libraries from organizations such as Apache or Eclipse.

Another protective measure is to regularly update an application’s dependencies to the latest version as soon as updates become available.

Finally, be aware of secondary or tertiary dependencies — ones that your primary dependencies themselves rely upon — and be aware of any risks those bring with them.

In the world of software development, “perfect” is the enemy of “done.” No program is immune from the threat of an unanticipated runtime error. However, when enterprise developers raise their awareness of the possible causes and take steps to mitigate against potential threats, they can create software that minimizes the probability of encountering a runtime error.

How runtime error appears?

Congratulations! If your command prompt looks like this:

Then you have successfully compiled your program into Java bytecode, meaning that there were no syntactic issues with your code! But, as the filename implies, when we run this program:

We have now run into a runtime error. Run time errors generally occur when there is something logically incorrect with your code. This document will explain how to read and fix runtime errors.

Here are the major parts of the runtime error

Exception in thread “main”: This part appears for most runtime errors. It just tells you that the exception occurred in the main method, which should happen all the time.

java.lang.ArrayIndexOutOfBoundsException: 5: This is the error that occurred. The name of the error will generally give you an idea of what might have happened. In this case, we know it deals with arrays and going out of the allotted space for an array.

at RunTimeErrors.main(RunTimeErrors.java:10): This is called the stack trace, which tells you the list of the methods executing when the error occurred.

  • RunTimeErrors.main tells us that this error occurred within the main method of the RunTimeErrors class.
  • RunTimeErrors.java:10 tells us the file this occurred in and what line it happened at. In this case, this happened in our main class at line 10.

Do i need to throw Runtime Errors

Sometimes you need to perform a checking to decide wheather to throw a runtime exception if the system can’t do it alone, often when working with IllegalArgumentException, but most of the time you don’t need to perform a checking because this is part of the standard runtime checking that Java performs for you.

lets take NullPointerException as an example :

if(t == null) 
throw new NullPointerException();

It can be a bit horrifying to think that you must check for null on every reference that is passed into a method (since you can’t know if the caller has passed you a valid reference). Fortunately, you don’t — this is part of the standard runtime checking that Java performs for you, and if any call is made to a null reference, Java will automatically throw a NullPointerException. So the above bit of code is always superfluous, although you may want to perform other checks in order to guard against the appearance of a NullPointerException.

if(t != null) {
// work with t reference
}

What happend when you don’t catch a Runtime Exceptions

What happens when you don’t catch Runtime exceptions? Since the compiler doesn’t enforce exception specifications for these, it’s quite plausible that a RuntimeException could percolate all the way out to your main( ) method without being caught. To see what happens in this case, try the following example:

//: exceptions/NeverCaught.java 
// Ignoring RuntimeExceptions.
// {ThrowsException}
public class NeverCaught {
static void f() {
throw new RuntimeException("From f()");
}
static void g() {
f();
}
public static void main(String[] args) {
g();
}
} ///:~

You can already see that a RuntimeException (or anything inherited from it) is a special case, since the compiler doesn’t require an exception specification for these types. The output is reported to System.err:

Exception in thread "main" Java.lang.RuntimeException: From f() 
at NeverCaught.f(NeverCaught.Java:7)
at NeverCaught.g(NeverCaught.Java:10)
at NeverCaught.main(NeverCaught.Java:13)

So the answer is: If a RuntimeException gets all the way out to main( ) without being caught, printStackTrace( ) is called for that exception as the program exits.

Keep in mind that only exceptions of type RuntimeException (and subclasses) can be ignored in your coding, since the compiler carefully enforces the handling of all checked exceptions. The reasoning is that a RuntimeException represents a programming error, which is:

An error you cannot anticipate. For example, a null reference that is outside of your control.

An error that you, as a programmer, should have checked for in your code (such as ArraylndexOutOfBoundsException where you should have paid attention to the size of the array). An exception that happens from point #1 often becomes an issue for point

You can see what a tremendous benefit it is to have exceptions in this case, since they help in the debugging process.

It’s interesting to notice that you cannot classify Java exception handling as a single-purpose tool. Yes, it is designed to handle those pesky runtime errors that will occur because of forces outside your code’s control, but it’s also essential for certain types of programming bugs that the compiler cannot detect.

Runtime Error Example

public class Temp {
public static void main(String[] args) {
Temp t = initT();

t.foo("Hi");

}
private static Temp initT() {
return null;
}
public void foo(String s) {
System.out.println(s.toLowerCase());
}
}

When we run the above program, it throws the following NullPointerException error message.

Exception in thread "main" java.lang.NullPointerException
at Temp.main(Temp.java:7)

We are getting NullPointerException in the statement t.foo(“Hi”); because “t” is null here.

There’s a whole group of exception types that are in this category. They’re always thrown automatically by Java and you don’t need to include them in your exception specifications. Conveniently enough, they’re all grouped together by putting them under a single base class called RuntimeException, which is a perfect example of inheritance: It establishes a family of types that have some characteristics and behaviors in common. Also, you never need to write an exception specification saying that a method might throw a RuntimeException (or any type inherited from RuntimeException), because they are unchecked exceptions. Because they indicate bugs, you don’t usually catch a RuntimeException — it’s dealt with automatically. If you were forced to check for RuntimeExceptions, your code could get too messy. Even though you don’t typically catch RuntimeExceptions, in your own packages you might choose to throw some of the RuntimeExceptions.

See The Most Common Runtime Exceptions

Happy learning 😃

Join Mouad Oumous Java WhatsApp Group JOIN

Join Mouad Oumous Telegram Channel JOIN

Do support our publication by following it

--

--

Mouad Oumous
The Fresh Writes

I'm a blogger on medium, l'm a java and kotlin developer, also an Android Developer I mastered various topics such as Networking, UI , UX, Animation ...