[Android, Kotlin] java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/LocalDateTime; 문제 해결하기

 

[문제 상황]

 

//현재 달에 대한 정보
@RequiresApi(Build.VERSION_CODES.O)
val dateMonth: Int = LocalDateTime.now().format(DateTimeFormatter.ofPattern("MM")).toInt()

 

avd로 컴파일 할 때는 아무런 이상이 없었는데,

개인 모바일 디바이스로 app을 실행하자 위의 코드에서 오류가 발생했다.

 

오류의 내용을 아래와 같다.

 

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.todolistjinuemong, PID: 4223
    java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/LocalDateTime;

 

LocalDateTime.now()는 java 8 버전을 사용한다.

java 8  버전을 사용하기 위한 세팅을 해주지 않아서 오류가 발생하는 것 같다.

 

 

[문제 해결]

 

자바 8 언어 기능 및 API 사용  |  Android 개발자  |  Android Developers

 

자바 8 언어 기능 및 API 사용  |  Android 개발자  |  Android Developers

사용할 수 있는 Java 8 언어 기능, 이러한 기능을 사용할 프로젝트를 올바르게 구성하는 방법 및 발생할 수 있는 알려진 문제를 알아봅니다.

developer.android.com

 

자바 8과 관련된 개발 문서를 읽어봤다.

 

"소스 코드나 모듈 종속 항목 중 하나에서 이러한 메서드 중 하나를 사용하는 경우 minSdkVersion 26 이상을 지정해야 합니다. 그러지 않으면 다음 오류가 발생합니다."

 

문제 해결을 위해서  app.Gradle의 minSdk를 26으로 수정 후에 컴파일 해봤다.

 

원인은 앱을 실행 진행 중인 디바이스에 있었다.

내 디바이스의 API는 25인데 API 26 버전의 기능을 사용하려고 해서 문제가 발생했다.

 

 

 

 

Android 스튜디오 프로젝트 설정  |  Maps SDK for Android  |  Google Developers

 

Android 스튜디오 프로젝트 설정  |  Maps SDK for Android  |  Google Developers

의견 보내기 Android 스튜디오 프로젝트 설정 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 이 페이지에서는 빠른 시작에 자세히 설명되어 있는 Google 지도

developers.google.com

 

이와 관련된 공식 문서를 읽어봤다.

에러가 발생한 LocalDateTime에 관련된 문서는 아니였지만 비슷한 문제를 다루고 있었다.

 

"앱이 API 수준 28(Android 9.0) 이상을 타겟팅하는 경우 AndroidManifest.xml <application> 요소 내에 다음 선언을 포함해야 합니다."

<uses-library
    android:name="org.apache.http.legacy"
    android:required="false" />

 

문제를 해결하기 위해서 Manifest에  library 관련 선언을 해주었다.

Ljava/time/LocalDateTime에서 L을 제외한 부분을 name에 넣어준다.

 

<uses-library
    android:name="java/time/LocalDateTime"
    android:required="false" />

 

계속 같은 문제가 발생한다..

sdk가 26 이상인 디바이스에서는 성공적으로 실행되나 25 이하인 앱에서는 같은 오류가 반복된다.

어쩔 수 없이 LocalDateTime 대신에 Calendar의 인스턴스로 날짜 정보를 불러오는 방법을 사용했다.

 

val date = Calendar.getInstance().time
val dateMonth: Int = SimpleDateFormat("MM", Locale.KOREA).format(date).toInt()

 

 

이제 오류가 발생하지 않는다.

java 8 관련 기능은 minSdkVersion 26이상의 앱을 개발할 때만 사용해야겠다.