Ошибка "Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6" в Kotlin
Причина ошибки и её решение
Ошибка "Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6" возникает, когда вы пытаетесь использовать inline-функцию (или функцию с inline модификатором), которая была скомпилирована с более новой версией JVM target (например, 1.8), в проекте, где JVM target установлен на более старую версию (например, 1.6).
Проблема в том, что inline-функции в Kotlin работают не так, как обычные. Когда вы вызываете inline-функцию, компилятор встраивает её тело прямо в место вызова, а не создаёт отдельный вызов метода. Для этого компилятор должен иметь доступ к байт-коду этой функции, который был сгенерирован с определённым JVM target. Если JVM target не совпадают, возникает конфликт.
В вашем случае, вы явно указали jvmTarget = "1.8", но ошибка всё равно возникает. Это может быть связано с тем, что:
- Модуль или библиотека, которую вы подключаете, скомпилирована с JVM target 1.6. Например, если вы используете старую версию Kotlin stdlib или другую библиотеку, которая не обновлена.
- Gradle или IntelliJ IDEA используют разные настройки. Иногда IDE может иметь свои настройки JVM target, которые переопределяют ваши.
- Конфликт между модулями. Если у вас многомодульный проект, один модуль может быть скомпилирован с JVM target 1.6, а другой — с 1.8.
Как исправить
Вот несколько шагов, которые помогут решить проблему:
1. Убедитесь, что все модули используют одинаковый JVM target
Проверьте build.gradle.kts (или build.gradle) для всех модулей вашего проекта. Убедитесь, что везде указан jvmTarget = "1.8". Если используете Android, добавьте настройку в блок android:
android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
2. Обновите зависимости
Проверьте, что вы используете последнюю версию Kotlin stdlib и других библиотек. Например, в вашем build.gradle.kts:
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0")
// или для Android:
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0")
}
Важно использовать kotlin-stdlib-jdk8, если вы работаете с Java 8, так как эта версия библиотеки скомпилирована с JVM target 1.8.
3. Проверьте настройки IntelliJ IDEA
В IntelliJ IDEA перейдите в File → Project Structure → Project и убедитесь, что Project SDK и Project language level установлены на 1.8 или выше. Затем перейдите в Settings → Build, Execution, Deployment → Compiler → Kotlin Compiler и проверьте, что Target JVM version установлен на 1.8.
4. Используйте явный inline-модификатор с осторожностью
Если вы пишете свою inline-функцию и хотите использовать её в разных модулях, убедитесь, что все модули скомпилированы с одинаковым JVM target. В противном случае, избегайте использования inline для функций, которые будут вызываться из других модулей с разными настройками.
Пример правильной настройки
Вот полный пример build.gradle.kts для Kotlin/JVM проекта:
plugins {
kotlin("jvm") version "1.9.0"
}
repositories {
mavenCentral()
}
dependencies {
implementation(kotlin("stdlib-jdk8"))
}
tasks.withType {
kotlinOptions {
jvmTarget = "1.8"
}
}
tasks.withType {
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
}
После этих изменений ошибка должна исчезнуть. Если нет, попробуйте очистить проект (Build → Clean Project) и пересобрать его.
<<Альтернативный подход: проверка цепочки зависимостей
Иногда проблема кроется не в вашем проекте, а в одной из зависимостей. Если вы используете библиотеку, которая сама содержит inline-функции (например, библиотеки для корутин или функционального программирования), то эта библиотека должна быть скомпилирована с тем же JVM target, что и ваш проект.
Проверьте, какие версии библиотек вы используете. Например, для корутин Kotlin:
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
}
Убедитесь, что версия библиотеки совместима с вашим JVM target. Если библиотека старая, она может быть скомпилирована с JVM target 1.6. В таком случае:
- Обновите библиотеку до последней версии.
- Если обновление невозможно, рассмотрите возможность использования
noinlineмодификатора для лямбда-параметров ваших inline-функций, чтобы избежать встраивания проблемного кода.
Также можно временно отключить inline для конкретной функции, изменив её на обычную (без inline), чтобы проверить, исчезнет ли ошибка. Если да, то проблема точно в несовместимости JVM target.
Используйте Gradle-команду ./gradlew dependencies, чтобы увидеть полное дерево зависимостей и найти, какая из них может быть скомпилирована под старую версию JVM.