Что такое файлы .kotlin_builtins и могу ли я исключить их из своих uberjars?

Я работаю над интеграцией proguard в свою сборку gradle для приложения, написанного на Kotlin. Я обнаружил, что proguard удаляет стандартную библиотеку Kotlin (как и должно быть в моей простой программе Hello World), но оставляет в моей банке кучу файлов с расширением файла .kotlin_builtins. Когда я настраиваю свою задачу gradle для исключения этих файлов, программа по-прежнему работает нормально. Что это за файлы и должны ли они поставляться с моим исполняемым файлом uberjar?

Вот содержимое моего файла build.gradle для справки:

buildscript {
   ext.kotlin_version = '1.0.5'
   ext.shadow_version = '1.2.4'

   repositories {
    mavenCentral()
    maven {
        url "https://plugins.gradle.org/m2/"
    }
    flatDir dirs: "gradle/proguard"
   }

   dependencies {
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    classpath "com.github.jengelman.gradle.plugins:shadow:$shadow_version"
    classpath ":proguard:"
   }
}

apply plugin: 'kotlin'
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'

mainClassName = 'namespace.MainKt'

defaultTasks 'run'

repositories {
    mavenCentral()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    testCompile "junit:junit:4.12"
    testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
}

shadowJar {
    exclude 'kotlin/**/*.kotlin_builtins'
    exclude '.keep'
}

task minify(type: proguard.gradle.ProGuardTask, dependsOn: 'shadowJar') {
    libraryjars "${System.getProperty('java.home')}/lib/rt.jar"

    injars  'build/libs/artful-all.jar'
    outjars 'build/libs/artful-all.out.jar'

    printmapping 'build/libs/out.map'

    keepclasseswithmembers 'public class * { \
        public static void main(java.lang.String[]); \
    }'

    assumenosideeffects 'class kotlin.jvm.internal.Intrinsics { \
        static void checkParameterIsNotNull(java.lang.Object, java.lang.String); \
    }'
}

person Community    schedule 09.12.2016    source источник


Ответы (2)


Эти файлы содержат данные для объявлений стандартных (встроенных) классов Kotlin, которые не компилируются в .class файлы, а сопоставляются с существующими типами на платформе (в данном случае JVM). Например, kotlin/kotlin.kotlin_builtins содержит информацию о нефизических классах в пакете kotlin: Int, String, Enum, Annotation, Collection и т. д.

Существует два основных сценария использования этих файлов:

  1. Компилятор ищет их из kotlin-stdlib пути к классам, чтобы определить, какие встроенные объявления доступны.

  2. Библиотека отражения (kotlin-reflect) загружает эти файлы как ресурсы, чтобы обеспечить возможности отражения для встроенных объявлений. Например, String::class.members возвращает всех членов класса kotlin.String точно так же, как компилятор Kotlin видит эти члены (несмотря на то, что файла kotlin/String.class нет и он стирается до java.lang.String в байт-коде).

Первый пункт явно не применим в вашем случае. И если вы не используете отражение встроенных классов, я думаю, что можно полностью исключить файлы .kotlin_builtins из полученного jar.

person Alexander Udalov    schedule 10.12.2016

Вы можете оптимизировать/исключить их из своих JAR/APK:

packagingOptions {
  exclude "/META-INF/*.kotlin_module"
  exclude "**/kotlin/**"
}

Даже лучше:

packagingOptions {
  exclude "/META-INF/*.kotlin_module"
  exclude "**/kotlin/**"
  exclude "**/*.txt"
  exclude "**/*.xml"
  exclude "**/*.properties"
}

Источник: https://github.com/jaredsburrows/android-gif-example/blob/master/build.gradle.kts#L127

person Jared Burrows    schedule 04.07.2017