이번 오류 포스팅은 debug 모드로 빌드했을 때는 문제가 없었는데 release 모드로 빌드하니 오류 발생에 대해 해결방법을 포스팅해 보겠다.
물론 다른 경우에 따라 이 해결방법이 아닐 수도 있지만 나에 경우는 이 오류였기 때문에 혹시나 나랑 같은 분이 계실까 봐 공유를 한다.
# 오류 발단
기존 프로젝트에서 Active Build Variant를 release로 바꾸고 빌드하니 아래와 같은 오류가 발생했다.
AGPBI: {"kind":"error", "text":"Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in /Users/(폴더명)/StudioProjects/(안드로이드 프로젝트 명)/app/build/outputs/mapping/release/missing_rules.txt.", "sources":[{}]}
# 오류 원인
오류의 원인으로 간단하게 설명하면 proguard 문제이다.
더 정확한 이유는 아래와 같다.
보통 release 빌드 시에는 build.gradle - buildTypes에 isMinifyEnabled = true를 해놓기 때문에 proguard가 활성화된다.
이때 종종 특정 클래스나 메서드가 사용되지 않거나 특정 플랫폼에만 존재할 때 proguard는 경고를 생성함으로써 빌드 오류가 발생하는 것이다.
이 부분은 위 오류 코드에도 나와있다.
Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in
번역 : R8을 실행하는 동안 누락된 클래스가 탐지되었습니다. 누락된 클래스를 추가하거나 에서 생성된 추가 킵 규칙을 적용하십시오
# 해결 방법
해결 방법으로는 총 두 가지? 가 있다. 개인적으로는 2번 방법을 추천한다.
## 1. proguard 비활성하기
이 방법은 내 프로젝트에 프로가드가 필요 없고 귀찮다!라고 하는 사람한테 추천한다. (난독화고 뭐고 모르겠고 혼자만 사용하는 프로젝트에 추천)
buildTypes {
release {
// isMinifyEnabled = true -> false 로 변경한다.
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
build.gradle - buildTypes - release에 isMinifyEnabled = false로 변경하면 프로가드를 사용 안 하기 때문에 빌드가 정상적으로 될 것이다.
## 2. missing_rules.txt파일 확인 하고 적용하기
이 방법은 오류 코드를 보면 해결 방법이 나온다.
위에서도 보다시피 오류 원인은 R8을 실행하는 동안 누락된 클래스가 탐지이다.
이에 따른 해결방법도 다음과 같이 오류 코드에서 설명해 준다. - 누락된 클래스를 추가하거나 에서 생성된 추가 킵 규칙을 적용하십시오
여기서는 생성된 추가 킵 규칙을 적용해 보겠다.
### a. missing_rules.txt 파일 위치 확인 및 열기
생성된 추가 킵 규칙이 있는 파일이 missing_rules.txt이다.
missing_rules.txt 파일이 있는 위치는 오류 메시지 끝부분에 /Users/(폴더명)/StudioProjects/(안드로이드 프로젝트 명)/app/build/outputs/mapping/release/missing_rules.txt
이런 식으로 되어있을 것이다.
그럼 저 위치에 가서 missing_rules.text 파일을 열어준다.
### b. missing_rules.txt 파일 내용 복사 후 proguard 붙여 넣기
나는 아래와 같이 내용이 있었다. (이 부분은 프로젝트마다 다르다)
위 내용을 복사 후 기존 proguard 아무 곳이나 붙여준다.
(멀티모듈인 경우에는 각 모듈 proguard에 붙여준다)
<proguard.rules.pro>
# Please add these rules to your existing keep rules in order to suppress warnings.
# This is generated automatically by the Android Gradle plugin.
-dontwarn org.joda.convert.FromString
-dontwarn org.joda.convert.ToString
-dontwarn org.bouncycastle.jsse.BCSSLParameters
-dontwarn org.bouncycastle.jsse.BCSSLSocket
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
-dontwarn org.conscrypt.Conscrypt$Version
-dontwarn org.conscrypt.Conscrypt
-dontwarn org.conscrypt.ConscryptHostnameVerifier
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
-dontwarn org.openjsse.net.ssl.OpenJSSE
다 마치고 빌드를 해보면 정상적으로 될 것이다.
# 번외 오류코드에서 -keep 대신 -dontwarn을 추천하는 이유
도대체 -dontwarn은 단순히 경고를 무시해 주는 난독화 옵션이고 -keep은 난독화를 하지 못하게 하는 옵션인데
"경고가 난 패키지만 그냥 난독화를 안 하면 되는 게 아닌가?"라는 생각이 들었다.
나는 궁금한걸 못 참기 때문에 바로 GPT한테 물어봤다.
답변은 아래와 같이 해줬다.
너무 길게 답을 해줬다... 그래서 정리를 해봤다.
-dontwarn은 경고를 억제해 앱 크기와 성능을 최적화하는 반면, -keep은 불필요한 코드를 유지할 수 있어 주의가 필요합니다. 따라서, 불필요한 경고를 무시할 때는 -dontwarn이 더 적합하다.
오늘도 오류 코드를 잘 보자!라는 교훈을 얻은 거 같다.
참고
https://coinpipe.tistory.com/261