以上标题只是个总结,此篇文章实际是踩坑记录。
起因
- 接手Kotlin项目时,前辈跟我说,项目中依赖的第一方Kotlin库无法调试。
- 排查调用栈时,依赖的第一方库的类竟然没有源码,是反编译出来的。
直接起因
- 其实前辈跟我说起因1时,我还没明白啥意思,怎么Kotlin就不能调试了。
- 今天下午排查内存泄漏问题时,发现第一方的aar包竟然没有关联上源码。
- 于是我就去maven仓库上把
*-source.jar
源码包下载到本地并解压,发现对于混合开发的项目,*-source.jar
包只包含了Java
源码,Kotlin
源码并没有被打包进来。 - 顿时,我回忆起了前辈跟我说的不能调试是啥情况,没有源码!没法跟踪调试。
解决过程
-
找到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.allSource
、from 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'
}