Jetpack Compose 라이브러리 모듈에서 NoSuchMethodError

오리·2025년 5월 7일

문제 상황

Jetpack Compose 기반 앱에서 공통 UI 컴포넌트를 별도 라이브러리 모듈로 분리해 사용하려던 중, 다음과 같은 오류를 만났다

java.lang.NoSuchMethodError: No static method FilledButton(...)
in class kr.mintech.chat_engine.view.FilledButtonKt
  • FilledButton@Composable로 정의된 버튼 UI 함수였고
  • 앱 모듈에서 이 컴포저블을 호출하려 하자 위와 같은 런타임 크래시가 발생

왜 이런 에러가 발생했을까?

java.lang.NoSuchMethodError는 컴파일 타임에 있어야 할 함수가 런타임에 존재하지 않을 때 발생

특히 Jetpack Compose에서는 @Composable 함수들이 일반 함수처럼 보이지만, 컴파일 시 Compose Compiler가 실제로 사용하는 bytecode를 생성

Jetpack Compose는 내부적으로 Kotlin Compiler Plugin을 사용해 @Composable 함수를 처리

  • 라이브러리 모듈에 Compose Plugin을 적용하지 않으면
    - @Composable 함수가 컴파일 타임에 bytecode로 변환되지 않음
    - 즉, 런타임에 해당 메서드가 Dex 파일에 없음
    - 결과적으로 NoSuchMethodError가 발생

    Dex?
    Dex 파일은 Android에서 실행 가능한 바이트코드 파일로, .java.class.dex → APK 흐름으로 변환됨.
    - Android Runtime(ART)은 이 Dex 파일을 읽고 실행함.
    - 즉, Dex에 없다는 건 "실행 가능한 코드 자체가 앱 안에 없음"을 의미함 → 런타임 오류 발생.

특히 라이브러리 모듈에서 문제가 잘 발생함

  • 앱 모듈은 build.gradle에 android { composeOptions { ... } }가 보통 기본 설정돼 있어 문제가 잘 안 생김
  • 그러나 별도의 라이브러리 모듈은 Compose Plugin을 명시적으로 추가해줘야 함

⇒ 즉, 에러 메시지는 앱에서 발생하지만, 진짜 원인은 라이브러리 모듈의 설정 문제


해결 방법

1. 루트 settings.gradle.kts에 Compose 플러그인 등록

Compose 플러그인을 사용할 수 있도록 루트 Gradle 설정에 추가

pluginManagement {
    plugins {
        **id("org.jetbrains.kotlin.plugin.compose") version "2.0.0"**
    }
    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

※ Kotlin 버전과 Compose BOM 버전에 맞는 Compose Plugin 버전을 설정해야 한다. (2.0.0 기준)

2. 라이브러리 모듈에 Compose 플러그인 적용

chat_engine/build.gradle.kts

plugins {
    id("com.android.library")
    id("org.jetbrains.kotlin.android")
    **id("org.jetbrains.kotlin.plugin.compose")**
}
  • 이 설정을 추가해야만 해당 모듈 내 @Composable 함수가 정상적으로 바이트코드로 변환됨
  • 그래야 앱 모듈에서 호출 시 Dex에 메서드가 존재하여 런타임 오류가 발생하지 않음

결과

  • 라이브러리 모듈의 @Composable 함수가 문제없이 앱 모듈에서 호출됨
  • NoSuchMethodError는 발생하지 않음
  • Kotlin 2.0 및 Compose 최신 구조에 맞는 Gradle 설정 완료

0개의 댓글