发布包含源码的Kotlin项目aar包到Maven

7,530 阅读2分钟

以上标题只是个总结,此篇文章实际是踩坑记录。

起因

  1. 接手Kotlin项目时,前辈跟我说,项目中依赖的第一方Kotlin库无法调试。
  2. 排查调用栈时,依赖的第一方库的类竟然没有源码,是反编译出来的。

直接起因

  1. 其实前辈跟我说起因1时,我还没明白啥意思,怎么Kotlin就不能调试了。
  2. 今天下午排查内存泄漏问题时,发现第一方的aar包竟然没有关联上源码。
  3. 于是我就去maven仓库上把*-source.jar源码包下载到本地并解压,发现对于混合开发的项目,*-source.jar包只包含了Java源码,Kotlin源码并没有被打包进来。
  4. 顿时,我回忆起了前辈跟我说的不能调试是啥情况,没有源码!没法跟踪调试。

解决过程

  • 找到lib用的打包发布到maven的gradle task 发现是这么配置源码包的:

    task sourcesJar(type: Jar) {
      if (project.hasProperty("android")) {
          from android.sourceSets.main.java.sourceFiles
      } else {
          println project
          from sourceSets.main.allSource
      }
      classifier = 'sources'
    }
    
  • 去网上搜了一圈,好像大家都是这么配置from

  • 具体去Google详细的“kotlin”+“aar”+“源码”关键字时,找到的大多都是开源打包插件的maven-publish等的配置,而我们公司的是自己写的,没法参考。

  • 尝试了一下使用from android.sourceSets.main.allSourcefrom android.sourceSets.main等配置,都报错。这个可能是因为项目使用了默认的源码路径没有配置sourceSets,所以检查不到

  • 但偶尔有一次我使用from android.sourceSets.main时报错提示如下

    * What went wrong:
    Cannot convert the provided notation to a File or URI: source set main.
    The following types/formats are supported:
    - A String or CharSequence path, for example 'src/main/java' or '/usr/include'.
    - A String or CharSequence URI, for example 'file:/usr/include'.
    - A File instance.
    - A Path instance.
    - A Directory instance.
    - A RegularFile instance.
    - A URI or URL instance.
    

灵感乍现,from后面可以跟路径呀。于是尝试如下配置

from android.sourceSets.main.java.getSrcDirs()

果然奏效,task执行不报错,*-source.jar也将kt源码打包进去了。所谓不能调试的问题也就不存在了。

总结

猜测使用.sourceFiles时,gradle筛选了.java类型的文件进行打包。

而使用.getSrcDirs()把整个目录作为参数时,gradle不再排查文件后缀,把所有目录下所有文件都打包进来了。

最终修改了打包任务如下,解决了含有kotlin的项目的打包问题:

task sourcesJar(type: Jar) {
    if (project.hasProperty("kotlin")) {
        from android.sourceSets.main.java.getSrcDirs()
    } else if (project.hasProperty("android")) {
        from android.sourceSets.main.java.sourceFiles
    } else {
        println project
        from sourceSets.main.allSource
    }
    classifier = 'sources'
}