Gradle 什么是.kotlin_内置文件?我可以从uberjars中删除它们吗?

Gradle 什么是.kotlin_内置文件?我可以从uberjars中删除它们吗?,gradle,jar,proguard,kotlin,shadowjar,Gradle,Jar,Proguard,Kotlin,Shadowjar,我正在为一个用Kotlin编写的应用程序将proguard集成到我的gradle构建中。我发现proguard正在剥离Kotlin标准库(在我的简单Hello World程序中应该是这样),但它在我的jar中留下了一堆文件扩展名为.Kotlin\u builtins。当我将gradle任务配置为排除这些文件时,该程序似乎仍能正常工作。这些文件是什么?它们必须与我的可执行uberjar一起提供吗 以下是我的build.gradle文件内容供参考: buildscript { ext.kotl

我正在为一个用Kotlin编写的应用程序将proguard集成到我的gradle构建中。我发现proguard正在剥离Kotlin标准库(在我的简单Hello World程序中应该是这样),但它在我的jar中留下了一堆文件扩展名为
.Kotlin\u 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); \
    }'
}

这些文件包含标准(“内置”)Kotlin类声明的数据,这些类未编译为
.class
文件,而是映射到平台上的现有类型(在本例中为JVM)。例如,
kotlin/kotlin.kotlin_builtins
包含包
kotlin
中非物理类的信息:
Int
String
Enum
注释
集合
,等等

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

  • 编译器从类路径上的
    kotlin stdlib
    中查找它们,以确定哪些内置声明可用

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


  • 第一点显然不适用于你的情况。如果不在内置类上使用反射,我认为从结果jar中完全排除
    .kotlin\u内置文件是安全的。

    可以从jar/apk中优化/省略这些文件:

    packagingOptions {
      exclude "/META-INF/*.kotlin_module"
      exclude "**/kotlin/**"
    }
    
    更好的是:

    packagingOptions {
      exclude "/META-INF/*.kotlin_module"
      exclude "**/kotlin/**"
      exclude "**/*.txt"
      exclude "**/*.xml"
      exclude "**/*.properties"
    }
    
    资料来源: