Blog |

How to Fix the Unsupported Class Version Runtime Error in Java

How to Fix the Unsupported Class Version Runtime Error in Java
Table of Contents

Introduction: Early-Stage Runtime Errors

Runtime errors occur when a program is being executed and, in the case of compiled languages, after the program has been successfully compiled. Runtime errors are, therefore, harder to detect and prevent than compile-time errors [1]. In Java, some of these runtime errors (namely throwable objects which are not exceptions) are triggered at a very early stage, while the program is basically starting up. Namely, there is a process of dynamic loading, linking, and initializing of classes and interfaces by the Java Virtual Machine (JVM) that occurs at the very beginning of execution of any Java application [2]. This allows for a certain category of errors to be captured and dealt with before the program effectively starts.

This category of high level runtime errors in Java is represented by classes which are direct descendants of the java.lang.Error class [3], including the java.lang.LinkageError class which denotes errors occurring during the aforementioned startup process [4]. An instance of the Error class (or any of its subclasses) is a throwable object that a program is not expected or advised to handle, but instead, should cause immediate termination of the program. This is because most of these errors occur as a result of abnormal conditions, often so severe that it is impossible to know or control what further execution of the program might do. LinkageError instances in particular indicate critical class-related errors triggered during the class linking phase of the startup process, usually as a consequence of some post-compilation changes in the bytecode or the Java environment.

 

What is the UnsupportedClassVersionError Error and Why Does it Happen?

The java.lang.UnsupportedClassVersionError class extends java.lang.ClassFormatError which is thrown whenever the JVM attempts to read a class file and determines that the file is malformed or otherwise cannot be interpreted as a class file [5][6]. As per Java’s error class hierarchy (Figure 1), an instance of UnsupportedClassVersionError is also a LinkageError which means that the error is identified during the JVM class linking process.

UnsupportedClassVersionError class hierarchy
Figure 1. UnsupportedClassVersionError class hierarchy

The specific issue that the UnsupportedClassVersionError error raises is the detection of a class file which had been compiled with a newer version of Java than the one used to run it. For instance, if a specific .class file has been compiled with Java Development Kit (JDK) 15, trying to run it with Java Runtime Environment (JRE) 8 will trigger the UnsupportedClassVersionError error. This almost invariably happens when someone attempts to run a program with a JDK or a JRE version that is incompatible with, i.e., lower than the Java version in which the code was compiled.

 

How to Fix the UnsupportedClassVersionError Error

The solution to the UnsupportedClassVersionError error generally boils down to two options:

  • Run the code with a newer version of Java/JRE, or
  • Recompile the code with an older Java/JDK compiler.

As a variant of #2, recompiling the code can also be done by specifying the “target” or “release” parameter of a newer Java/JDK compiler to an earlier version of Java, to produce backward-compatible bytecode.

Before recompiling any code, it is important to know the runtime version of both the already compiled code and the environment in which it needs to run on. The message accompanying the UnsupportedClassVersionError error provides this information in the form of class file versions, which can be mapped directly to a specific Java version, using the values from the table below.

Table 1. Class file format major versions
Java SE (JDK) Major Version Release Date
17 61 September 2021
16 60 March 2021
15 59 September 2020
14 58 March 2020
13 57 September 2019
12 56 March 2019
11 55 September 2018
10 54 March 2018
9 53 September 2017
8 52 March 2014
7 51 July 2011
6 50 December 2006
5.0 49 September 2004
1.4 48 February 2002
1.3 47 May 2000
1.2 46 December 1998
1.1 45 February 1997
1.01 45 May 1996

 

UnsupportedClassVersionError Error Example

Below is an example of the UnsupportedClassVersionError error, indicating that the class com.rollbar.ExampleApp was compiled with Java 17 (class file version 61) but executed with Java 8 (class file version 52).

Exception in thread "main" java.lang.UnsupportedClassVersionError: com/rollbar/ExampleApp 
  has been compiled by a more recent version of the Java Runtime (class file version 61.0), 
  this version of the Java Runtime only recognizes class file versions up to 52.0

Figure 2: UnsupportedClassVersionError example

 

Using a newer Java version

The most straightforward solution is to update the JRE on the machine on which the code is running. Executing the commands echo %JAVA_HOME% and java -version inside a terminal should point to the existing Java installation directory and its version number. This can be particularly useful to pinpoint which version is in use when multiple JREs are installed on the same machine. From there, downloading and updating the JAVA_HOME variable to point to the newer Java version (e.g. Java 17) [7] will fix the UnsupportedClassVersionError error.

 

Recompiling by Targeting an Older Java Version

If the program needs to be compatible with older versions of Java as a business requirement, compiling it accordingly would be the most sensible solution. This can be accomplished either by using an older JDK compiler, or by specifying the target version on a newer JDK compiler. Using the terminal command javac -target 8 com/rollbar/ExampleApp.java by specifying the targeted JDK version with the -target or alternatively the -release flag, will instruct the compiler to produce bytecode compatible with that version (Java 8 in this example).

This solution should work universally across different JDKs and compilers, so long as the target version is the same or older than that of the compiler, and given that the source code syntax is compatible with the target version. In instances where this isn’t the case, refactoring the code before compiling it might be necessary.

 

Working with IDEs

All major IDEs have configuration settings where one can specify which JDK and JRE versions to use, down to a project level. Newer IDEs even allow downloading newer versions directly through their graphical user interfaces which makes setting up a Java project a breeze, even if just for recompiling it. For this specific purpose, a setting normally called “Project language level” or “Compiler compliance level” can be tweaked, the project rebuilt/recompiled, and the aforementioned UnsupportedClassVersionError error resolved without ever leaving the IDE. An example for where to find this setting in JetBrains IDEs is shown below.

Jetbrains Intellij Idea IDE: Project Settings -> Language Level
Figure 3: JetBrains IntelliJ IDEA: Project Settings → Project language level

 

Maven Projects

When dealing with Maven projects, which the majority of both small and large enterprise Java programs are, it is possible to control the Java version targeted by the compilation process from the Maven configuration, i.e. Maven Project Object Model (POM) file. The relevant settings are shown in the Figure below.

Note that while it is possible to control the source and target versions independently, it is recommended to set them to equal values, as backward compatibility of the compiled bytecode cannot be guaranteed [8].

<project xmlns="http://maven.apache.org/POM/4.0.0"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
...
   <properties>
       <maven.compiler.source>17</maven.compiler.source>
       <maven.compiler.target>8</maven.compiler.target>
   </properties>
...
</project>

Figure 4: Maven POM file compiler properties

 

Conclusion

The UnsupportedClassVersionError error is a critical Java runtime error thrown during the class linking phase at the very beginning of a program's execution. This error occurs when attempting to run some code, usually a full-fledged pre-compiled program, on a platform that has a JRE older than the one the code was compiled on. Resolving the UnsupportedClassVersionError error involves either updating the JRE on the target machine or, if backward compatibility is needed, recompiling the program to target the older JRE. Modern IDEs make this process easy with their built-in tools and configuration settings, which is not to say that the same cannot be accomplished without them, as has been explained in this article.

 

Track, Analyze and Manage Errors With Rollbar

Rollbar in action

Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Java errors easier than ever. Sign Up Today!

 

References

[1] Rollbar, 2021. How to Fix "Illegal Start of Expression" in Java. Rollbar Editorial Team. [Online]. Available: https://rollbar.com/blog/how-to-fix-illegal-start-of-expression-in-java/. [Accessed Jan. 8, 2022]

[2] Oracle, 2021. Chapter 5. Loading, Linking, and Initializing. Oracle Corporation and/or its affiliates. [Online]. Available: https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-5.html. [Accessed Jan. 8, 2022]

[3] Oracle, 2021. Error (Java SE 17 & JDK 17). Oracle and/or its affiliates. [Online]. Available: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Error.html. [Accessed Jan. 8, 2022]

[4] Oracle, 2021. LinkageError (Java SE 17 & JDK 17). Oracle and/or its affiliates. [Online]. Available: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/LinkageError.html. [Accessed Jan. 8, 2022]

[5] Oracle, 2021. ClassFormatError (Java SE 17 & JDK 17). Oracle and/or its affiliates. [Online]. Available: https://docs.oracle.com/javase/9/docs/api/java/lang/ClassFormatError.html. [Accessed Jan. 8, 2022]

[6] Oracle, 2021. UnsupportedClassVersionError (Java SE 17 & JDK 17). Oracle and/or its affiliates. [Online]. Available: https://docs.oracle.com/javase/9/docs/api/java/lang/UnsupportedClassVersionError.html. [Accessed Jan. 8, 2022]

[7] Oracle, 2011. Installing the JDK Software and Setting JAVA_HOME. Oracle and/or its affiliates. [Online]. Available: https://docs.oracle.com/cd/E21454_01/html/821-2531/inst_jdk_javahome_t.html. [Accessed Jan. 8, 2022]

[8] E. Punzalan, 2019. Apache Maven Compiler Plugin – Setting the -source and -target of the Java Compiler. The Apache Software Foundation. [Online]. Available: https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html. [Accessed Jan. 8, 2022]

Related Resources

"Rollbar allows us to go from alerting to impact analysis and resolution in a matter of minutes. Without it we would be flying blind."

Error Monitoring

Start continuously improving your code today.

Get Started Shape