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?

下面是我的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); \
    }'
}

推荐答案

这些文件包含标准("内置")Kotlin类的声明数据,这些类没有编译成.class个文件,而是映射到平台上的现有类型(在本例中是JVM).例如,kotlin/kotlin.kotlin_builtins包含包kotlin中的非物理类的信息:IntStringEnumAnnotationCollection等.

使用这些文件时,主要有两种情况:

  1. 编译器在类路径上从kotlin-stdlib开始查找它们,以确定哪些内置声明可用.

  2. 反射库(kotlin-reflect)将这些文件作为资源加载,以便为内置声明提供反射能力.例如,String::class.members以与Kotlin编译器看到这些成员完全相同的方式返回类kotlin.String的所有成员(尽管没有kotlin/String.class文件,并且在字节码中被擦除为java.lang.String).

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.

Kotlin相关问答推荐

测试Compose Multiplatform UI时,为另一个文件设置ComposeRule()

Jetpack Compose Material3和Material2 Slider onValueChangeFinded()的行为不同

如何为集成测试配置Gradle JVM测试套件?

kotlin - 挂起简单方法调用链时可能存在冗余分支

为什么Kotlin不用static inner class来实现带有object关键字的单例呢?

Kotlin:调用 CoroutineScope.launch 与在协程内启动之间的区别

如何在 Spring Boot 3 中为内部类提供运行时提示

如何在 Spring Boot 3 中为内部类提供运行时提示

如何避免键盘打开时jetpack compose 内容上升

内容更改后的 var 重新计算

Kotlin RxJava 可空的错误

JobIntentService 被销毁,当应用程序被销毁时

Kotlin 中 lambda 表达式中的默认参数

如何使用 Kotlin Coroutines 使 setOnClickListener debounce 1 秒?

runInTransaction 块内的挂起方法

Kotlin惰性默认属性

在 gradle android library kotlin 项目中禁用 META-INF/* 生成

Kotlin - computed var 属性的用处?

将 Double 转换为 ByteArray 或 Array Kotlin

项目不会使用 Kotlin 1.1.3 构建