Google Drive API 적용 중 발생한 Exception 입니다.
Debug 빌드로 테스트할때는 잘되었는데 release 빌드시에는 아래의 오류가 발생하며 앱이 빌드되지 않는 현상이 발생합니다.
Error: commons-logging defines classes that conflict with classes now provided by Android. Solutions include finding newer versions or alternative libraries that don't have the same problem (for example, for httpclient use HttpUrlConnection or okhttp instead), or repackaging the library using something like jarjar. [DuplicatePlatformClasses]
Error: httpclient defines classes that conflict with classes now provided by Android. Solutions include finding newer versions or alternative libraries that don't have the same problem (for example, for httpclient use HttpUrlConnection or okhttp instead), or repackaging the library using something like jarjar. [DuplicatePlatformClasses]
Explanation for issues of type "DuplicatePlatformClasses":
There are a number of libraries that duplicate not just functionality of
the Android platform but using the exact same class names as the ones
provided in Android -- for example the apache http classes. This can lead
to unexpected crashes.
To solve this, you need to either find a newer version of the library which
no longer has this problem, or to repackage the library (and all of its
dependencies) using something like the jarjar tool, or finally, rewriting
the code to use different APIs (for example, for http code, consider using
HttpUrlConnection or a library like okhttp).
build.gradle에 implementation 되어 있는 내용은 아래와 같습니다.
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
implementation 'com.squareup.okhttp3:okhttp:3.14.1'
implementation 'com.google.android.gms:play-services-auth:18.0.0'
implementation 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
implementation 'com.google.apis:google-api-services-drive:v3-rev110-1.23.0'
implementation 'com.google.api-client:google-api-client:1.26.0'
implementation 'com.google.http-client:google-http-client-gson:1.26.0'
implementation 'com.google.api-client:google-api-client-android:1.26.0'
*가장 윗부분의 guava 같은 부분은 Google Drive 구현시 사용하는 라이브러리의 버그로 guava 관련 글을 참고해주세요.
발생 원인은 구글이 안드로이드 6.0 부터 Apache HTTP에 대한 지원을 중단하기 시작하고 API 28 이상을 대상으로 하는 앱에서는 아예 Apache HTTP 관련 라이브러리를 제외하기 시작했기 때문에 이에 종속된 라이브러리에 대해서 충돌이 발생하기 때문입니다.
해결책으로 나와있는 방법중 하나는 아래의 방법으로 app단의 build.gradle에 해당 부분을 추가합니다.
configurations {
all {
exclude group: 'commons-logging', module: 'commons-logging'
exclude group: 'org.apache.httpcomponents', module: 'httpclient'
}
}
이방법은 httpclient와 commons-logging 모듈을 모두 제외하고 빌드하라는 옵션인데 이를 사용하면 build는 되지만 httpcliet 관련 기능을 사용할때 아래의 Exception을 뿜으며 앱이 종료되게 됩니다.
ClassNotFoundException: Didn't find class "org.apache.commons.codec.binary.StringUtils"
해당 Exception이 발생하는 부분은 아래의 부분인데 이 부분은 심지어 Apache HTTP가 아닌 com.google.api.client.http 라는 google의 라이브러리를 사용하는 부분인데도 오류가 발생하게 되는데 이것은 자사의 라이브러리에서조차 Apache HTTP에 대한 종속성을 해결하지 않아, 지원이 없으면 동작하지 않는다는 소리가 되겠습니다.
ByteArrayContent contentStream = ByteArrayContent.fromString("text/plain", content);
2020-04-22일자 기준으로 저는 별다른 해결책을 찾을 수 없었습니다.
다만, Debug 빌드시에는 별 문제가 발생하지 않았기 때문에 release 빌드때도 별 문제가 발생하지 않으리라 예상하고 해결책으로 나와 있는 또다른 방법을 사용하기로 했습니다.
우선은 commons-logging 모듈은 제외해도 문제가 발생하지 않는다는 것을 확인했기 때문에, 그대로 제외하고.
configurations {
all {
exclude group: 'commons-logging', module: 'commons-logging'
}
}
app단의 build.gradle에 아래의 내용을 추가해 줍니다.
lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}
build시 error가 발생하더라도, 무시하고 빌드하라는 옵션이고, 해당 옵션 부여후에는 빌드도 제대로 되고, httpclent 관련 기능도 제대로 작동하는것을 확인했습니다.
도대체 자사의 라이브러리 종속성도 해결할 수 없으면서 지원을 중단하는 이유는 무엇때문이며 지원을 중단했으면서도 자사의 라이브러리에서도 종속성을 걷어내지 않은 것에 굉장히 당황했습니다.
댓글