The error “unsupported class file major version 60” occurs when you try to run a Java application that was compiled using a higher JDK (Java Development Kit) version than the JRE (Java Runtime Environment) version used to execute the application. In this case, the error indicates that the class file was compiled using JDK 16 (major version 60) or higher, but the JRE being used to run the application is lower than JDK 16.
To resolve this issue, you have two options:
-
Upgrade your JRE: Update your Java Runtime Environment to a version that matches or is higher than the JDK version used to compile the application (in this case, JDK 16 or higher). You can download the latest JRE from the official Oracle website (https://www.oracle.com/java/technologies/javase-jre8-downloads.html). Make sure to set the JAVA_HOME environment variable and update the system PATH variable accordingly.
-
Recompile the application with a lower JDK version: If you have access to the application’s source code, you can recompile it using a lower JDK version that matches your current JRE. To do this, install the appropriate JDK version on your system and update the JAVA_HOME environment variable and system PATH variable accordingly. Then, recompile the application using the newly-installed JDK.
-
Use a multi-release JAR: If you have access to the application’s source code and want to support multiple Java versions, you can create a multi-release JAR file. Multi-release JAR files allow you to package class files compiled with different JDK versions into a single JAR file. When running the application, the appropriate class files will be used based on the JRE version. To create a multi-release JAR, refer to the official Oracle documentation: https://openjdk.java.net/jeps/238
-
Use a distribution tool like jlink or jpackage: These tools help you create a custom JRE that includes only the required modules for your application, along with the necessary dependencies. This custom JRE can be bundled with your application, ensuring that the correct JRE version is always used. For more information, refer to the official documentation for jlink (https://docs.oracle.com/en/java/javase/11/tools/jlink.html) and jpackage (https://docs.oracle.com/en/java/javase/14/jpackage/packaging-tool-user-guide.html).
-
Use a containerization technology like Docker: Containerizing your Java application ensures that the application runs in an isolated environment with the correct JDK and JRE versions, regardless of the host system’s Java environment. By using a Docker container, you can package your application along with its required Java environment, eliminating compatibility issues. For more information, refer to the official Docker documentation for Java applications: https://docs.docker.com/samples/java/
-
Use a build tool with built-in support for multiple JDKs: Some build tools, like Gradle and Maven, provide built-in support for managing multiple JDK versions. This allows you to compile your application with the appropriate JDK version based on the target environment. To set up a build tool for managing multiple JDK versions, refer to the official documentation for Gradle (https://docs.gradle.org/current/userguide/building_java_projects.html) or Maven (https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-source-and-target.html).
-
Use a tool like AdoptOpenJDK to manage multiple JDK installations: AdoptOpenJDK provides pre-built OpenJDK binaries that make it easy to install and manage multiple JDK versions on your system. You can use AdoptOpenJDK in combination with environment management tools like SDKMAN! (https://sdkman.io/) or Jabba (https://github.com/shyiko/jabba) to switch between different JDK versions when compiling and running your Java applications. This ensures that you always use a compatible JDK version for your target JRE.
-
Use the
-release
flag during compilation: If you have access to the application’s source code and need to target a specific JRE version, you can use the-release
flag during compilation. This flag ensures that your application is compiled with the correct JDK version for the target JRE. For example, to compile an application for JRE 11, you can use the following command:javac -release 11 MyApp.java
. Note that this option requires a JDK version that supports the-release
flag (JDK 9 or later). -
Use a Continuous Integration (CI) system: Implementing a CI system can help you automatically build and test your Java applications against multiple JDK versions, ensuring compatibility across different JREs. Popular CI systems like Jenkins, Travis CI, and GitHub Actions can be configured to build and test your application with various JDK versions, allowing you to catch compatibility issues early in the development process.
-
Encourage users to update their JRE: While this may not be a direct solution, sometimes the best approach is to encourage users to update their Java Runtime Environment to a more recent version. This can help minimize compatibility issues and ensure that users are running your application on a supported JRE. You can include a note in your application’s documentation or provide instructions on how to update the JRE as needed.
To avoid compatibility issues, it is generally recommended to use the same JDK and JRE versions when developing and deploying Java applications. Keep your Java environment up-to-date and ensure that your applications are compiled with a JDK version that is compatible with the target JRE.