Avatar ·

Как исправить ошибку java.lang.UnsupportedClassVersionError: Unsupported major.minor version

Привет всем! Я новичок в Java и уже второй день бьюсь над этой ошибкой. Пишу простую программу "Hello World" в IntelliJ IDEA, но при попытке запустить её через командную строку получаю вот такое сообщение: ``` Exception in thread "main" java.lang.UnsupportedClassVersionError: HelloWorld : Unsupported major.minor version 61.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(Unknown Source) ... ``` Вот мой код: ```java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } ``` Я скомпилировал этот файл через javac в папке проекта, а когда пытаюсь запустить java HelloWorld, вылетает эта ошибка. При этом в самой IntelliJ IDEA программа запускается нормально. Что значит "major.minor version 61.0"? И как это исправить? Я проверил версию Java — пишет, что у меня установлена Java 8 (1.8.0_291). Может, нужно обновить JDK? Или проблема в том, как я компилирую? Буду благодарен за подробное объяснение, потому что в интернете много ответов, но они для меня слишком сложные. <<>>

Что такое major.minor version и почему возникает ошибка?

Ошибка java.lang.UnsupportedClassVersionError возникает, когда вы пытаетесь запустить .class-файл (скомпилированный байт-код Java) с помощью Java Runtime Environment (JRE), версия которого ниже, чем версия компилятора (javac), которым этот файл был создан. Каждая версия Java имеет свой номер версии байт-кода (major.minor), например:

  • Java 8 (1.8) = major 52
  • Java 11 = major 55
  • Java 17 = major 61
  • Java 21 = major 65

В вашем случае "major.minor version 61.0" означает, что файл скомпилирован под Java 17, а запускаете вы его на Java 8 (major 52). IntelliJ IDEA работает нормально, потому что она использует свой встроенный JDK (скорее всего, 17+), а командная строка использует системную Java 8.

Решение проблемы (по шагам)

У вас есть два пути: либо повысить версию JRE для запуска, либо понизить версию компиляции. Рекомендую первый вариант, так как Java 8 уже устарела и не получает обновлений безопасности.

Способ 1: Установить и использовать JDK/JRE 17 или новее

  1. Скачайте JDK 17 LTS с официального сайта Oracle или Adoptium (Eclipse Temurin).
  2. Установите его и запомните путь (например, C:\Program Files\Java\jdk-17).
  3. Измените переменные окружения:
    • Удалите или переименуйте старую переменную JAVA_HOME.
    • Создайте новую JAVA_HOME = C:\Program Files\Java\jdk-17.
    • В переменной Path добавьте %JAVA_HOME%\bin (убедитесь, что это первая запись).
  4. Перезапустите командную строку и проверьте версии:
    java -version
    javac -version
  5. Теперь скомпилируйте и запустите вашу программу заново:
    javac HelloWorld.java
    java HelloWorld

Способ 2: Скомпилировать с указанием целевой версии (если нужно оставить Java 8)

Если по каким-то причинам вы обязаны использовать Java 8, укажите компилятору создавать байт-код для старой версии:

javac -source 8 -target 8 HelloWorld.java

Но учтите: если ваш код использует фичи Java 17+ (например, switch-выражения или текстовые блоки), компиляция с source/target 8 выдаст ошибку. В вашем простом примере это сработает.

Как проверить версию байт-кода в .class-файле?

Используйте утилиту javap:

javap -verbose HelloWorld.class | findstr "major"  # Windows
javap -verbose HelloWorld.class | grep major       # Linux/Mac

Вы увидите что-то вроде major version: 61.

Важные советы

  • Не смешивайте JDK от разных поставщиков в одной системе — это частая причина путаницы.
  • В IntelliJ IDEA проверьте настройки: File → Project Structure → Project SDK. Убедитесь, что там выбран JDK 17+.
  • Если вы работаете с Maven/Gradle, укажите версию Java в pom.xml или build.gradle.
<<>>

Альтернативный подход: использование Docker или SDKMAN

Если вы часто переключаетесь между версиями Java или не хотите менять системную Java 8 (например, она нужна для других проектов), рекомендую использовать менеджер версий SDKMAN (для Linux/Mac/WSL) или Docker.

Вариант с SDKMAN (рекомендую для разработчиков)

  1. Установите SDKMAN: curl -s "https://get.sdkman.io" | bash
  2. Установите нужную версию Java: sdk install java 17.0.9-tem
  3. Переключайтесь между версиями: sdk use java 17.0.9-tem
  4. Теперь команды java и javac будут использовать Java 17 только в текущем терминале.

Вариант с Docker (для изоляции)

Запускайте компиляцию и выполнение в контейнере:

docker run --rm -v "$PWD":/app -w /app openjdk:17 javac HelloWorld.java
docker run --rm -v "$PWD":/app -w /app openjdk:17 java HelloWorld

Это гарантирует, что версия Java будет строго соответствовать образу, и не повлияет на вашу основную систему.

Почему это полезно?

Оба метода позволяют избежать "загрязнения" системных переменных окружения и легко тестировать код на разных версиях Java. Особенно это ценно, если вы работаете над legacy-проектами (Java 8) и современными (Java 21) одновременно.