프로젝트/쿠링

Proguard에 또 당한 썰 푼다

해스끼 2024. 3. 1. 18:27

문제

학교 홈페이지가 리뉴얼되면서 일부 공지를 제대로 보여주지 못하는 문제가 있었다. 해당 문제를 해결하여 오늘 낮에 업데이트를 출시했다.

 

쿠링 안드로이드 팀은 업데이트를 출시한 후 일주일 정도 Firebase Crashlytics를 모니터링하는데, 업데이트가 출시된 직후부터 심각한 크래시 문제가 보고되었다. 심지어 이메일로 버그를 보고하는 사용자도 있었다.

무려 두 자릿수

 

구체적으로는 온보딩 화면에서 맨 밑의 '공지 알림 설정하기' 버튼을 누르면 앱이 죽는다.

원인

모듈화 때문에 proguard rules를 수정해야 하는데, 수정하지 않았다.

 

Retrofit과 Proguard를 함께 사용한다면, Retrofit에서 사용하는 몇몇 클래스를 난독화로부터 보호해야 한다. 대표적으로 request, response 클래스 등이 있다.

 

따라서 쿠링 앱에서는 다음과 같이 proguard rule을 작성해서 사용하고 있었다.

-keep class com.ku_stacks.ku_ring.data.api.request.** { *; }
-keep class com.ku_stacks.ku_ring.data.api.response.** { *; }
-keep class com.ku_stacks.ku_ring.data.db.** { *; }
-keep class com.ku_stacks.ku_ring.data.model.** { *; }
-keep class com.ku_stacks.ku_ring.data.websocket.response.** { *; }
-keep class com.ku_stacks.ku_ring.data.websocket.request.** { *; }

 

그런데 얼마 전 앱을 모듈화하면서 위에서 작성한 클래스들의 경로가 바뀌었고, 따라서 proguard rule에도 바뀐 경로를 작성해야 한다. 

해결

``proguard-rules.pro`` 파일에 request, response 클래스의 바뀐 경로를 작성하였다.

# request, reponse data class which are used with Retrofit
-keep class com.ku_stacks.ku_ring.remote.department.request.** { *; }
-keep class com.ku_stacks.ku_ring.remote.department.response.** { *; }
-keep class com.ku_stacks.ku_ring.remote.notice.request.** { *; }
-keep class com.ku_stacks.ku_ring.remote.notice.response.** { *; }
-keep class com.ku_stacks.ku_ring.remote.notice.** { *; }
-keep class com.ku_stacks.ku_ring.remote.staff.response.** { *; }
-keep class com.ku_stacks.ku_ring.remote.user.request.** { *; }
-keep class com.ku_stacks.ku_ring.remote.util.** { *; }
# Room DAO, entity
-keep class com.ku_stacks.ku_ring.local.entity.** { *; }
-keep class com.ku_stacks.ku_ring.local.room.** { *; }
# domain classes
-keep class com.ku_stacks.ku_ring.domain.** { *; }

또, 문제를 일으킬 수 있는 일부 RxJava 및 Retrofit 클래스 등도 추가하였다.

# RxJava classes
-keep class io.reactivex.rxjava3.core.Flowable
-keep class io.reactivex.rxjava3.core.Maybe
-keep class io.reactivex.rxjava3.core.Observable
-keep class io.reactivex.rxjava3.core.Single
# Keep generic signature of Call, Response (R8 full mode strips signatures from non-kept items).
-keep interface retrofit2.Call
-keep class retrofit2.Response
# With R8 full mode generic signatures are stripped for classes that are not
# kept. Suspend functions are wrapped in continuations where the type argument
# is used.
-keep class kotlin.coroutines.Continuation

 

블린더를 개발할 때도 proguard에 많이 당했었는데(사례) 쿠링에서도 또 당했다. 하지만 이번에는 과거 경험을 참고하여 빠르게 해결할 수 있었다.

 

신입생 여러분, 이제 안심하고 사용하세요!

↓ 쿠링 앱 설치하기

 

쿠링 - 건국대학교 공지앱 - Google Play 앱

건국대학교 공지를 알림으로 제공합니다.

play.google.com

참고한 자료

 

Crash with R8 full mode enabled with generics and Rx · Issue #3774 · square/retrofit

Retrofit: 2.9.0 The crashing retrofit interface contains methods like these: @FormUrlEncoded @POST("token/oauth2") fun clientCredentials( @Field("client_id") clientId: String, @Field("client_secret...

github.com

 

 

java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType with retrofit2

I have this code: val profile: UserProfile = userApi.profile() @GET("users/profile") suspend fun profile(): UserProfile When i run userApi.profile() i get this error: java.l...

stackoverflow.com