Как исправить java.lang.UnsupportedClassVersionError: Полный гайд

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: "Машина времени" для вашего Java-кода

Представьте: вы скачали крутую библиотеку, написали несколько строк кода, нажимаете "Run" — и вместо работающей программы видите длинное, пугающее сообщение:

Exception in thread "main" java.lang.UnsupportedClassVersionError: 
com/example/MyApp 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 55.0

Знакомо? Если вы когда-нибудь сталкивались с java.lang.UnsupportedClassVersionError, то знаете, что это похоже на разговор двух людей на разных языках. Ваша Java-программа говорит на версии 61.0 (Java 17), а среда выполнения понимает только до версии 55.0 (Java 11).

В этом туториале мы разберем, что такое Unsupported major.minor version, почему она возникает и, самое главное, как её исправить. Мы не просто дадим готовые решения, а научим вас понимать корень проблемы. Поехали!

Что такое major.minor version? Краткий ликбез

Каждый .class файл в Java имеет внутреннюю метку — major.minor version. Это номер версии формата байт-кода, который создается компилятором javac. Например:

  • major 52 → Java 8
  • major 55 → Java 11
  • major 61 → Java 17
  • major 65 → Java 21

Когда вы запускаете приложение, JRE (Java Runtime Environment) проверяет, может ли она "понять" этот файл. Если версия файла новее, чем версия JRE, вы получаете java.lang.UnsupportedClassVersionError.

Простая аналогия: представьте, что вы пытаетесь открыть PDF-документ, созданный в Adobe Acrobat 2023, в Adobe Reader 2010. Программа скажет: "Я не знаю этот формат".

Основные причины ошибки UnsupportedClassVersionError

Ошибка Unsupported major.minor version может возникнуть по нескольким причинам:

  • Разные версии JDK и JRE: Вы скомпилировали код на JDK 17, а запускаете на JRE 11.
  • Библиотеки сторонних разработчиков: Вы подключили JAR-файл, скомпилированный под Java 17, а ваша среда выполнения — Java 8.
  • Неверная настройка Maven/Gradle: В файле сборки указана одна версия Java, а на сервере установлена другая.
  • Деплой на старый сервер: Вы разрабатываете на современной IDE, а продакшн-сервер работает на устаревшей Java.

Пошаговый туториал: как исправить ошибку

Давайте разберем конкретные шаги для решения проблемы. Мы рассмотрим три основных сценария.

Шаг 1: Проверьте версии Java

Первым делом нужно понять, кто "виноват". Откройте терминал и выполните:

# Версия, на которой вы компилируете (JDK)
javac -version

# Версия, на которой вы запускаете (JRE)
java -version

Если они не совпадают — вот и причина. Например, javac показывает "17.0.1", а java — "11.0.12".

Решение: Установите одинаковые версии, либо обновите JRE, либо понизьте версию компиляции (об этом ниже).

Шаг 2: Исправляем настройки компиляции

Если вы не можете обновить JRE (например, на сервере), нужно компилировать код под более старую версию. Используйте флаги -source и -target в компиляторе:

// Компилируем код Java 17, но генерируем байт-код для Java 11
javac -source 17 -target 11 MyApp.java

Важно: -source указывает, какой синтаксис Java вы используете, а -target — под какую версию JRE генерировать .class файл. Если ваш код использует возможности Java 17 (например, switch-выражения), они будут скомпилированы в совместимый байт-код.

Шаг 3: Работа с Maven и Gradle

В реальных проектах вы редко используете javac напрямую. Вот как настроить версии в популярных сборщиках.

Maven (pom.xml)

<properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>

Gradle (build.gradle)

java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}

После изменения конфигурации пересоберите проект: mvn clean compile или gradle build.

Шаг 4: Проверка библиотек (JAR-файлов)

Ошибка java.lang.UnsupportedClassVersionError может возникнуть не из-за вашего кода, а из-за подключенной библиотеки. Проверьте, под какую версию Java скомпилирован JAR:

# Распакуйте JAR и проверьте class-файл
jar -tf library.jar | grep ".class" | head -1
javap -verbose -cp library.jar com/example/SomeClass.class | grep "major"

Если major version больше, чем ваша JRE — ищите более старую версию библиотеки или обновляйте JRE.

Шаг 5: Используйте флаг --release (Java 9+)

Начиная с Java 9, появился удобный флаг --release, который одновременно устанавливает -source, -target и версию API:

javac --release 11 MyApp.java

Это гарантирует, что вы не используете API из более новых версий Java, что часто бывает причиной скрытых ошибок.

Реальный пример: от ошибки к исправлению

Давайте смоделируем ситуацию. У вас есть простой класс:

// MyApp.java (скомпилирован на Java 17)
public class MyApp {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

Вы запускаете его на Java 11 и получаете:

java.lang.UnsupportedClassVersionError: MyApp has been compiled by a more recent 
version of the Java Runtime (class file version 61.0)

Решение:

  1. Проверьте версии: javac -version (17) vs java -version (11).
  2. Блоги

    Рекомендаций по книгам