What are .kotlin_builtins files and can I omit them from my uberjars?
Asked Answered
D

2

13

I'm working on integrating proguard to my gradle build for an application written in Kotlin. I'm finding that proguard is stripping out the Kotlin standard library (as it should in my simple Hello World program) but it's leaving a bunch of files in my jar that have the file extension .kotlin_builtins. When I configure my gradle task to exclude those files, the program still appears to work fine. What are those files and must they ship with my executable uberjar?

Here's my build.gradle file's contents for reference:

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); \
    }'
}
Disarm answered 9/12, 2016 at 4:0 Comment(0)
G
18

These files contain data for declarations of standard ("built-in") Kotlin classes which are not compiled to .class files, but rather are mapped to the existing types on the platform (in this case, JVM). For example, kotlin/kotlin.kotlin_builtins contains the information for non-physical classes in package kotlin: Int, String, Enum, Annotation, Collection, etc.

There are two main scenarios when these files are used:

  1. The compiler looks them up from kotlin-stdlib on the classpath to determine which built-in declarations are available.

  2. The reflection library (kotlin-reflect) loads these files as resources to provide reflection capabilities for built-in declarations. For example, String::class.members returns all members of the class kotlin.String exactly in the same way as the Kotlin compiler sees those members (despite the fact that there's no kotlin/String.class file and it's erased to java.lang.String in bytecode).

The first point is clearly not applicable in your case. And if you don't use reflection on built-in classes, I think it's safe to exclude .kotlin_builtins files completely from the resulting jar.

Gate answered 10/12, 2016 at 8:53 Comment(0)
D
3

You can optimize/omit these from yours JARs/APKs:

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

Even better:

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

Source: https://github.com/jaredsburrows/android-gif-example/blob/master/build.gradle.kts#L127

Daven answered 4/7, 2017 at 16:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.