我正在尝试使用Shadow和以下Gradle配置重新定位软件包(OkHttp 4,具体而言):
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)
如您所见,该应用程序是Android应用程序,以防万一。
任何想法我的配置有什么问题吗?
我们在非Android项目中遇到了类似的情况。实际上,包级的“事物”(在我们的例子中是扩展功能)在编译器生成的类(在我们的例子中,其称为ExtensionKt.class)上是静态的。
我从Java或Scala代码访问该类都没有问题。但是,在Kotlin代码中,编译器不允许我访问ExtensionKt
类,并且通过影子Jar重新定位的包以某种方式破坏了原始语法,因此无法再通过包名称访问它。作为临时的解决方法,我们从Java访问包范围内的东西:
因此,此Kotlin代码:
import my.package.name.niceExtensionFunction
...
val x = SomeClass()
val y = x.niceExtensionFunction()
我们用Java实现:
import my.package.name.ExtensionKt;
...
SomeClass x = new SomeClass;
Object y = ExtensionKt.niceExtensionFunction(x)