App stürzt mit NoclassDeffoundError ab: io.ktor.client.plugins.httptimeout bei der Anmeldung bei Google on Android
Posted: 14 Apr 2025, 02:05
Ich entwickle eine Social -Media -Android -App mit Kotlin, Jetpack Compose und Supabase zur Authentifizierung. Wenn ich versuche, mich bei Google von meinem Authscreen komponierbar anzumelden, stürzt die App sofort ab. Der Logcat zeigt den folgenden Fehler an: < /p>
Der Absturz scheint mit dem von der Supabase Kotlin SDK verwendeten KTOR -Client in Verbindung zu stehen, insbesondere aufgrund der fehlenden io.ktor.client.plugins.httptimeout Klasse. Es tritt während der Initialisierung meines SupabaseClient -Objekts auf, wenn der Google-Anmeldefluss ausgelöst wird.
Authscreen.Kt:
bestätigte, dass SupabaseClient.kt die CIO -Motor verwendet, die mit der CIOEngine in der Stack -Trace übereinstimmt. Ich habe auch versucht, die Standard -Engine zu verwenden, indem ich httpengine = cio.create () entfernt habe, aber das Problem bleibt bestehen. /> [/list]
Beobachtungen [/b]:
Die Stapelspur zeigt auf cioEngine , in Übereinstimmung mit dem in Supabaseclient angegebenen CIO -Motor ist immer noch vermisst. Httptimeout Klasse ist Teil der Client -Plugins von KTOR, und ich vermute, dass es möglicherweise nicht in meinen aktuellen Abhängigkeiten enthalten ist oder dass Supabase eine bestimmte KTOR -Konfiguration benötigt. io.ktor.client.plugins.httptimeout fehlt und wie kann ich sicherstellen, dass es in meinem Projekt enthalten ist? Nichtübereinstimmung zwischen Supabase () und welche (() dieses Problem verursacht? Bitte lassen Sie mich wissen, ob Sie meinen vollständigen Build.gradle.KTS oder zusätzliche Details zum Google-Anmelde-Setup benötigen.
Code: Select all
FATAL EXCEPTION: main
Process: com.brandonnathanang.retrofy, PID: 4019
java.lang.NoClassDefFoundError: Failed resolution of: Lio/ktor/client/plugins/HttpTimeout;
at io.ktor.client.engine.cio.CIOEngine.(CIOEngine.kt:25)
at io.ktor.client.engine.cio.CIO.create(CIOCommon.kt:35)
at io.ktor.client.engine.HttpClientEngineFactory$DefaultImpls.create$default(HttpClientEngineFactory.kt:82)
at com.brandonnathanang.retrofy.SupabaseClient.(SupabaseClient.kt:26)
at com.brandonnathanang.retrofy.AuthScreenKt$AuthScreen$1$1$1$1.invokeSuspend(AuthScreen.kt:59)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:8919)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.ui.platform.MotionDurationScaleImpl@624b85f, androidx.compose.runtime.BroadcastFrameClock@649a2ac, StandaloneCoroutine{Cancelling}@9f2db75, AndroidUiDispatcher@cc3470a]
Caused by: java.lang.ClassNotFoundException: Didn't find class "io.ktor.client.plugins.HttpTimeout" on path: DexPathList[[zip file "/data/app/~~gdmVMlSlTsWTv8VnE93_lg==/com.brandonnathanang.retrofy-yHgBsaIaQtgrFBDqr6aqvA==/base.apk"],nativeLibraryDirectories=[/data/app/~~gdmVMlSlTsWTv8VnE93_lg==/com.brandonnathanang.retrofy-yHgBsaIaQtgrFBDqr6aqvA==/lib/arm64, /data/app/~~gdmVMlSlTsWTv8VnE93_lg==/com.brandonnathanang.retrofy-yHgBsaIaQtgrFBDqr6aqvA==/base.apk!/lib/arm64-v8a, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
at java.lang.ClassLoader.loadClass(ClassLoader.java:637)
at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
... 18 more
Code: Select all
package com.brandonnathanang.retrofy
import io.github.jan.supabase.SupabaseClient
import io.github.jan.supabase.createSupabaseClient
import io.github.jan.supabase.auth.Auth
import io.github.jan.supabase.postgrest.Postgrest
import io.github.jan.supabase.realtime.Realtime
import io.github.jan.supabase.storage.Storage
import io.ktor.client.engine.cio.CIO
object SupabaseClient {
private const val SUPABASE_URL = "https://aesfsowpmrmftctdwvyt.supabase.co"
private const val ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFlc2Zzb3dwbXJtZnRjdGR3dnl0Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDQ1MDAyMjgsImV4cCI6MjA2MDA3NjIyOH0.N00hDyxxg3U4kn5ONEYtQY9iO_dw_EWyVfhTIzPrOoU"
val client: SupabaseClient = createSupabaseClient(
supabaseUrl = SUPABASE_URL,
supabaseKey = ANON_KEY
) {
install(Auth) {
scheme = "retrofy"
host = "auth/callback"
}
install(Postgrest)
install(Realtime)
install(Storage)
httpEngine = CIO.create()
}
}
Code: Select all
package com.brandonnathanang.retrofy
import android.app.Activity
import android.content.Context
import android.util.Log
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import io.github.jan.supabase.auth.auth
import io.github.jan.supabase.exceptions.RestException
import io.github.jan.supabase.postgrest.from
import io.github.jan.supabase.auth.providers.Google
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.UUID
fun Context.findActivity(): Activity? {
var currentContext = this
while (currentContext is android.content.ContextWrapper) {
if (currentContext is Activity) {
return currentContext
}
currentContext = currentContext.baseContext
}
return null
}
@Composable
fun AuthScreen(navController: NavController) {
var error by remember { mutableStateOf(null) }
var isLoading by remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()
val context = LocalContext.current
val activity = context.findActivity() ?: run {
error = "Activity context unavailable"
return@run
}
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(
onClick = {
if (!isLoading) {
coroutineScope.launch {
isLoading = true
error = null
try {
Log.d("RetrofyAuth", "Starting Google Sign-In with Supabase")
SupabaseClient.client.auth.signInWith(Google)
repeat(10) {
val userId = SupabaseClient.client.auth.currentUserOrNull()?.id
if (userId != null) {
Log.d("RetrofyAuth", "Signed in user ID: $userId")
val userInfo = SupabaseClient.client.auth.currentUserOrNull()
var username = userInfo?.email?.substringBefore("@")
?: "user_${UUID.randomUUID().toString().substring(0, 8)}"
var suffix = 1
while (SupabaseClient.client.from("users")
.select { filter { eq("username", username) } }
.decodeList().isNotEmpty()) {
username = "${userInfo?.email?.substringBefore("@") ?: "user"}_$suffix"
suffix++
}
SupabaseClient.client.from("users").insert(
mapOf(
"id" to userId,
"email" to (userInfo?.email ?: ""),
"username" to username,
"favorite_decades" to emptyList()
)
)
Log.d("RetrofyAuth", "Inserted user: $username")
navController.navigate("throwback") { popUpTo("auth") { inclusive = true } }
return@launch
}
delay(1000)
}
error = "Sign-In timeout: No user detected"
Log.e("RetrofyAuth", "No user ID after polling")
} catch (e: RestException) {
error = "API error: ${e.error}"
Log.e("RetrofyAuth", "Rest error", e)
} catch (e: Exception) {
error = "Sign-In failed: ${e.message}"
Log.e("RetrofyAuth", "Unexpected error", e)
} finally {
isLoading = false
}
}
}
},
modifier = Modifier.fillMaxWidth(),
enabled = !isLoading
) {
Text(if (isLoading) "Signing in..." else "Sign in with Google")
}
if (error != null) {
Spacer(modifier = Modifier.height(8.dp))
Text(text = error ?: "", color = MaterialTheme.colorScheme.error)
}
}
}
< /code>
[b] Was ich ausprobiert habe < /strong>: < /p>
[list]
[*] Eingeschlossene Supabase- und KTOR-Abhängigkeiten in meinem Build.gradle.KTS < /code>:
implementation("io.github.jan-tennert.supabase:auth-kt:3.1.4")
implementation("io.github.jan-tennert.supabase:postgrest-kt:3.1.4")
implementation("io.github.jan-tennert.supabase:realtime-kt:3.1.4")
implementation("io.github.jan-tennert.supabase:storage-kt:3.1.4")
implementation("io.ktor:ktor-client-core:2.3.7")
implementation("io.ktor:ktor-client-cio:2.3.7")
Beobachtungen [/b]:
Die Stapelspur zeigt auf cioEngine , in Übereinstimmung mit dem in Supabaseclient angegebenen CIO -Motor ist immer noch vermisst. Httptimeout Klasse ist Teil der Client -Plugins von KTOR, und ich vermute, dass es möglicherweise nicht in meinen aktuellen Abhängigkeiten enthalten ist oder dass Supabase eine bestimmte KTOR -Konfiguration benötigt. io.ktor.client.plugins.httptimeout fehlt und wie kann ich sicherstellen, dass es in meinem Projekt enthalten ist? Nichtübereinstimmung zwischen Supabase (
Code: Select all
3.1.4
Code: Select all
2.3.7