Rails + Hotwire Native 앱을 Android로 빌드하다가 AGP(Android Gradle Plugin) 9.0과 Hotwire Native 1.2.5 조합에서 오류가 쏟아졌다. 하나씩 해결한 기록.
오류 1: kotlin-android plugin is no longer required
Plugin 'kotlin-android' is no longer required for Kotlin support since AGP 9.0
AGP 9.0부터 Kotlin 지원이 내장되어 별도 플러그인이 필요 없다.
// build.gradle.kts — 제거
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android) // ← 삭제
}
// 이것만 남김
plugins {
alias(libs.plugins.android.application)
}
오류 2: kotlinOptions unresolved reference
Unresolved reference: kotlinOptions
AGP 9.0에서 kotlinOptions가 제거됐다. kotlin { jvmToolchain() }으로 교체.
// 잘못됨
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
// 올바름
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlin {
jvmToolchain(17)
}
오류 3: HotwireWebBridgeFragment unresolved reference
Unresolved reference: HotwireWebBridgeFragment
Hotwire Native Android 1.2.5에는 HotwireWebBridgeFragment가 없다. HotwireWebFragment를 상속하면 된다.
// 잘못됨
class MainFragment : HotwireWebBridgeFragment() {
override val bridgeComponentFactories = listOf(...)
}
// 올바름
@HotwireDestinationDeepLink(uri = "myapp://fragment/web")
class MainFragment : HotwireWebFragment()
Bridge 컴포넌트 등록은 Fragment가 아니라 Application 클래스에서 한다.
class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
Hotwire.registerBridgeComponents(
BridgeComponentFactory("my-component", ::MyBridgeComponent)
)
}
}
오류 4: binding?.webView null
WebView 접근을 binding?.webView로 하면 null이 떨어진다. Hotwire Native는 WebView 준비 완료 시 콜백을 제공한다.
// 잘못됨
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding?.webView?.settings?.javaScriptEnabled = true
}
// 올바름
override fun onWebViewAttached(webView: HotwireWebView) {
super.onWebViewAttached(webView)
webView.settings.javaScriptEnabled = true
}
오류 5: navigator?.navigateUp() unresolved
Unresolved reference: navigateUp
navigateUp()이 제거됐다. navigator.pop()으로 교체.
// 잘못됨
navigator?.navigateUp()
// 올바름
navigator.pop()
오류 6: Firebase 패키지명 불일치
debug buildType에 applicationIdSuffix = ".debug"를 붙이면 Firebase에 등록한 패키지명(com.myapp.app)과 달라져서 FCM이 동작하지 않는다.
// 이렇게 하면 debug 빌드가 com.myapp.app.debug가 되어 Firebase 인식 못함
buildTypes {
debug {
applicationIdSuffix = ".debug" // ← 삭제
}
}
최종 build.gradle.kts
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.google.services)
}
android {
namespace = "com.myapp.app"
compileSdk = 36
defaultConfig {
applicationId = "com.myapp.app"
minSdk = 28
targetSdk = 36
versionCode = 1
versionName = "1.0.0"
}
signingConfigs {
create("release") {
storeFile = file("myapp.jks")
storePassword = "password"
keyAlias = "myapp"
keyPassword = "password"
}
}
buildTypes {
debug {
buildConfigField("String", "BASE_URL", "\"https://my-server.com\"")
}
release {
isMinifyEnabled = true
isShrinkResources = true
signingConfig = signingConfigs.getByName("release")
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
buildConfigField("String", "BASE_URL", "\"https://my-server.com\"")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlin {
jvmToolchain(17)
}
buildFeatures {
buildConfig = true
}
}
릴리즈 서명 키스토어 생성
keytool -genkey -v \
-keystore android/app/myapp.jks \
-keyalg RSA -keysize 2048 -validity 10000 \
-alias myapp \
-storepass yourpassword \
-keypass yourpassword
Makefile로 빌드 자동화
apk-debug:
cd android && ./gradlew assembleDebug
apk-release:
cd android && ./gradlew assembleRelease
aab-release:
cd android && ./gradlew bundleRelease
- Debug APK → 동업자 직접 설치 (설정 > 보안 > 알 수 없는 앱 허용)
- Release AAB → Play Store 제출용

💬 댓글
비밀번호를 기억해두면 나중에 내 댓글을 삭제할 수 있어요.