2016-12-09 1 views
6

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

Вот содержимое моего 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); \ 
    }' 
} 

ответ

6

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

Есть два основных сценария, когда эти файлы используются:

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

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

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

0

Вы можете оптимизировать/опустить их от ваших 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#L144

Смежные вопросы