Android:使用Retrofit的库项目导致NoClassDefFoundError [英] Android: library project with Retrofit results in NoClassDefFoundError

查看:1173
本文介绍了Android:使用Retrofit的库项目导致NoClassDefFoundError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图构建一个使用OkHttp和Retrofit来授权访问我们的REST后端的Android库项目。



它似乎在工作,只要我在 com.squareup.retrofit2的gradle-dependency中使用 api 而不是 implementation 变换器GSON 。看起来这是唯一需要它的依赖项(所有其他的可以与 implementation一起使用)。



当使用 implementation 在这里,调用应用程序将会崩溃,并且 NoClassDefFoundError


java.lang.NoClassDefFoundError:无法解析:Lcom / google / gson / GsonBuilder;






我使用 consumerProguardFiles 和一堆proguard规则文件(例如一个用于okhttp3,retrofit2等等) repo )。所有这些都会被打包到一个AAR中,所以还应该添加依赖关系的规则。



看起来我错过了<$的proguard规则C $ C>转换器-GSON 。有人可以发布在库项目中使用 com.squareup.retrofit2:converter-gson 所需的规则吗?






编辑1



我的目前的proguard-rule 用于改造是:

 #Retrofit 2.X 
## https://square.github.io/retrofit/ ##

-twtwarn retrofit2。**
维护类retrofit2。** {*; }
-keepattributes签名
-keepattributes异常

-keepclasseswithmembers类* {
@ retrofit2.http。*< methods> ;;
}

如上所述,这似乎还不够。也许我还需要别的东西来为 converter-gson !?



编辑2



我的依赖关系如下所示:

  implementationcom.squareup.okhttp3:okhttp:$ okHttpVersion
实现com.squareup.retrofit2:retrofit:$ retrofitVersion
apicom.squareup.retrofit2:converter-gson:$ retrofitVersion

我试图摆脱最后一个 api ,因为我不需要它在使用这个库的应用程序(或这是不可避免的)?






编辑3



嗯,也许proguard是错误的关键字。其实问题在于使用实现超过 api 。所以依赖关系不会暴露给消费者。请参阅 https://stackoverflow.com/a/44493379/2170109



但是我不明白为什么当只有库调用 GsonBuilder 时,我需要将> converter-gson code>?

解决方案

按照官方翻新的github链接:

https://github.com/square/retrofit



改装至少需要Java 7或Android 2.3。



如果您使用的是ProGuard,则需要添加以下选项:

 #保留通用类型信息,供转换器和适配器反射使用。 
-keepattributes签名
#保留服务方法参数。
-keepclassmembernames,allowobfuscation接口* {
@ retrofit2.http。*< methods>;
}
#忽略用于构建工具的注释。
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

#我的个人proguard配置ratrofit2
-dontwarn okio。**
-dontwarn javax.annotation。 **
-dontwarn retrofit2.Platform $ Java8

请检查一次您的配置是否存在任何错误:

app-> build.gradle

  //翻新gson 

实现'com.squareup.retrofit2:翻新:2.3.0'
实现'com.squareup.retrofit2:converter-gson:2.3.0'

如果出现更多错误,您可以分享错误日志来解释问题究竟是什么。


I'm trying to build an android library project which uses OkHttp and Retrofit to grant access to our REST-backend.

It seems to be working as long as I use api instead of implementation on my gradle-dependency for com.squareup.retrofit2:converter-gson. It seems that this is the only dependency needing this (all others can used with implementation).

When using implementation here as well, the calling app will crash with NoClassDefFoundError:

java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/gson/GsonBuilder;


I'm using consumerProguardFiles with a bunch of proguard-rule-files (e.g. one for okhttp3, retrofit2 etc. from this repo). All this will then be packed into an AAR, so rules from the dependencies should be added as well.

It seems that I'm missing a proguard-rule for converter-gson. Can somebody post the rules needed to use com.squareup.retrofit2:converter-gson in a library project?


Edit 1

My current proguard-rule for retrofit is:

# Retrofit 2.X
## https://square.github.io/retrofit/ ##

-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions

-keepclasseswithmembers class * {
    @retrofit2.http.* <methods>;
}

As mentioned, this seems not enough. Maybe I need something else for converter-gson!?

Edit 2

My dependencies look like this:

implementation "com.squareup.okhttp3:okhttp:$okHttpVersion"
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
api "com.squareup.retrofit2:converter-gson:$retrofitVersion"

And I'm trying to get rid of the api on the last one as I do not need it in the app using this library (or is this not avoidable)?


Edit 3

Hmm, maybe proguard is the wrong keyword. Actually the problem lies in the use of implementation over api. So dependencies will not be exposed to consumers. See https://stackoverflow.com/a/44493379/2170109.

But I don't get why I need to expose converter-gson to consumers of my library when only the library calls GsonBuilder?

解决方案

As per official retrofit github link :

https://github.com/square/retrofit

Retrofit requires at minimum Java 7 or Android 2.3.

If you are using ProGuard you need to add the following options:

# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain service method parameters.
-keepclassmembernames,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}
# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement

# My personal proguard configuration for ratrofit2
-dontwarn okio.**
-dontwarn javax.annotation.**
-dontwarn retrofit2.Platform$Java8

please check once your configuration if there is any mistake :

app-> build.gradle

// retrofit gson

implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'

If there is more error you can share your error log to explain you what exactly problem is.

这篇关于Android:使用Retrofit的库项目导致NoClassDefFoundError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆