使用Shadow重新定位的包中的java Kotlin属性不起作用
我试图用Shadow重新定位一个包(具体来说是OkHttp 4),并使用以下Gradle配置:
apply plugin: 'java'
apply plugin: 'com.github.johnrengelman.shadow'
shadowJar {
archiveBaseName.set('my_archive')
archiveClassifier.set(null)
version = null
relocate 'okhttp3', 'my.prefix.okhttp3'
relocate 'okio', 'my.prefix.okio'
}
dependencies {
implementation("com.squareup.okhttp3:okhttp:4.2.1") {
exclude group: "org.jetbrains.kotlin", module: "kotlin-stdlib"
}
}
(我省略了buildscript
部分,重要的一点是使用的Shadow版本是5.1.0
。包前缀等也已更改)
在OkHttp 3.12.0及更早版本中,这是完全Java的。既然OkHttp 4是用Kotlin编写的,我在使用属性时遇到了问题,尤其是在Kotlin代码中。从Java使用时,重新定位的OkHttp工作正常。但是访问Kotlin中的属性,比如:
val cache = httpClient.cache
。。。结果出现异常:
java.lang.NoSuchMethodError: No virtual method getCache()Lmy/prefix/okhttp3/Cache; in class Lmy/prefix/okhttp3/OkHttpClient; or its super classes (declaration of 'my.prefix.okhttp3.OkHttpClient' appears in /data/app/redacted.redacted-0yalPGR5aw0RSY2Zdxnq7Q==/base.apk)
如你所见,该应用程序是安卓应用程序,以防万一
知道我的配置有什么问题吗
# 1 楼答案
我们在一个非android项目中也经历了类似的事情。 包级别的“things”(在本例中是一个扩展函数)实际上在编译器生成的类(在本例中称为ExtensionKt.class)上是静态的
我可以从Java或Scala代码访问该类。 然而,在Kotlin代码中,编译器不允许我访问
ExtensionKt
类,而shadow Jar重新定位的包以某种方式破坏了原始语法,因此无法再通过包名访问它。作为一种临时解决方法,我们可以从Java访问包范围内的内容:因此,取而代之的是Kotlin代码:
我们在Java中这样做:
# 2 楼答案
这并不是一个完美的解决方案,但至少在一定程度上可以让事情顺利进行。与其完全排除嵌入式Kotlin stdlib,不如随它去,并重新定位它。最简单的方法是将所有内容重新定位到同一前缀,并将其添加到
build.gradle
:您可能还需要在
shadowJar
任务中排除一些KotlinMETA-INF
位这种方法的问题(至少对我来说)在于,虽然一切或多或少都能正常工作,但现在你的应用程序中可能有两个Kotlin stdlib:一个是你的前缀版本,另一个是你通常使用的版本。此外,属性语法也不起作用。就像问题中的例子一样
实际上变成了
。。。这不太好
我现在面临的另一个问题是,在Android Studio中,生成的
jar
中的所有内容在代码编辑器中显示为红色,即Android Studio看不到jar
中的内容。所有的东西都编译得很好,只是编辑代码本身是一件痛苦的事情,因为你没有完成任何代码,Android Studio有时会干扰你的导入。(因为它显然认为这些进口是无效的)