New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VerifyError on Android since 1.3.7 #2041
Comments
Could you please attach a simple reproducer? I've played with simple Android application with 1.3.7 and it seems to work OK. Probably has something to do with untypical bytecode shape |
I can't. When I try it in one of my simplier apps, it works just fine. Trying to figure out why is that. They both uses same versions of pretty much everything compile-related (Kotlin, Gradle, Android Gradle Plugin, Build Tools, ...) |
Could you please share the piece of code around |
@Pitel I had the same issue but it was my fault. I had some buggy code that looked like this suspend fun action(model: Model) {
withContext(cpu context) {
withContext(db context) {
updateDb()
}
try {
updateRemoteApiCall()
} catch (t: HttpException) {
withContext(db context) {
revertDbOperation()
throw t
}
}
}
} the issue in my case was that I was rethrowing the exception within the db context! Hopefully it'll help you debug your issue. |
I guess I can share the whole file: App.ktpackage cz.masterapp.clones
import android.app.Application
import android.os.Build
import android.os.StrictMode
import android.widget.Toast
import androidx.fragment.app.FragmentManager
import coil.Coil
import coil.ImageLoaderBuilder
import coil.util.CoilUtils
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.iid.FirebaseInstanceId
import com.uxcam.UXCam
import cz.masterapp.annie2.core2.devicediscovery.DeviceDiscoveryManager
import cz.masterapp.annie2.coroutines.CoroutineContextProvider
import cz.masterapp.annie2.data.UserRepository
import cz.masterapp.annie2.log.AntispamDebugTree
import cz.masterapp.annie2.log.CrashlyticsTree
import cz.masterapp.annie2.log.Log
import cz.masterapp.annie2.messaging.di.MqttModule
import cz.masterapp.annie2.rest.annie2.Annie2RestHelper
import cz.masterapp.annie2.rest.annie2.model.Server
import cz.masterapp.annie2.rest.annie2.model.ServerResponse
import cz.masterapp.annie2.rest.annie2.model.TokenResponse
import cz.masterapp.annie2.rest.annie2.model.User
import cz.masterapp.annie2.rest.dependencyinjection.RestModule
import cz.masterapp.annie2.rest.error.Failure
import cz.masterapp.annie2.rest.extensions.onLeft
import cz.masterapp.annie2.stream2.di.Stream2Module
import cz.masterapp.annie2.types.DeviceId
import cz.masterapp.annie2.types.Mapper
import cz.masterapp.annie2.userModule
import cz.masterapp.clones.extensions.await
import cz.masterapp.clones.helpers.CoilTimberLogger
import cz.masterapp.clones.mapper.RestErrorToMessage
import cz.masterapp.clones.modules.dataModule
import cz.masterapp.clones.modules.viewModelsModule
import kotlinx.coroutines.*
import okhttp3.OkHttpClient
import org.koin.android.ext.android.get
import org.koin.android.ext.android.inject
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
import org.koin.core.logger.Level
import org.koin.core.qualifier.named
import org.koin.dsl.module
import org.webrtc.PeerConnection
import timber.log.Timber
import java.io.IOException
import java.net.UnknownHostException
import kotlin.time.ExperimentalTime
import kotlin.time.TimeSource
@OptIn(ExperimentalTime::class)
class App : Application() {
companion object {
private const val CRASHLYTICS_USER_KEY = "user"
private val TREE = if (BuildConfig.DEBUG) AntispamDebugTree() else null
fun setCrashlyticsUser(user: User) {
FirebaseCrashlytics.getInstance().setCustomKey(
CRASHLYTICS_USER_KEY,
user.copy(email = "", token = TokenResponse("", "", "", null)).toString()
)
}
}
init {
System.setProperty(
DEBUG_PROPERTY_NAME, if (BuildConfig.DEBUG && Log.COROUTINES) {
DEBUG_PROPERTY_VALUE_ON
} else {
DEBUG_PROPERTY_VALUE_OFF
}
)
FragmentManager.enableDebugLogging(BuildConfig.DEBUG && Log.FRAGMENT)
}
override fun onCreate() {
super.onCreate()
UXCam.occludeAllTextFields(true)
UXCam.startWithKey(getString(R.string.uxcam_key))
if (BuildConfig.DEBUG && Log.STRICT) {
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build()
)
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build()
)
}
TREE?.run { Timber.plant(this) }
startKoin {
androidContext(this@App)
modules(listOf(
RestModule.module,
dataModule,
MqttModule.module,
viewModelsModule,
Stream2Module.module,
userModule,
DeviceDiscoveryManager.module,
module {
single {
FirebaseAnalytics.getInstance(androidContext())
}
single<Mapper<Failure, String>>(named(Mapper.REST_ERROR_MAPPER)) {
RestErrorToMessage(
androidContext()
)
}
single(named("servers")) {
GlobalScope.async(start = CoroutineStart.LAZY) {
get<Deferred<Annie2RestHelper>>(named<Annie2RestHelper>()).await()
.getAllServersConfig().onLeft {
when (val failure = it.a) {
is Failure.NetworkError -> {
val ioe = failure.e
Timber.w(ioe, "DNS")
withContext(CoroutineContextProvider.UI) {
if (ioe.cause?.cause is UnknownHostException) {
Toast.makeText(
this@App,
ioe.cause?.cause?.localizedMessage,
Toast.LENGTH_LONG
).show()
} else {
Toast.makeText(
this@App,
ioe.localizedMessage,
Toast.LENGTH_LONG
).show()
}
}
}
}
return@async null
}
}
}
single(MqttModule.MQTT_URL) {
GlobalScope.async(start = CoroutineStart.LAZY) {
val mqttServer = get<Deferred<ServerResponse?>>(
named("servers")
).await()?.mqttServer
when {
mqttServer == null -> "tcp://null"
mqttServer.sslPort != null -> "ssl://${mqttServer.hostname}:${mqttServer.sslPort}"
mqttServer.port != null -> "tcp://${mqttServer.hostname}:${mqttServer.port}"
else -> "tcp://${mqttServer.hostname}"
}
}
}
single(MqttModule.USERNAME) {
GlobalScope.async(start = CoroutineStart.LAZY) {
get<Deferred<ServerResponse?>>(named("servers")).await()
?.mqttServer?.user
}
}
single(MqttModule.PASSWORD) {
GlobalScope.async(start = CoroutineStart.LAZY) {
get<Deferred<ServerResponse?>>(named("servers")).await()
?.mqttServer?.password
}
}
single(MqttModule.LOCAL_DEVICE_ID) {
GlobalScope.async(start = CoroutineStart.LAZY) {
get<UserRepository>().uuid.await()
}
}
single(MqttModule.CLIENT_ID) {
GlobalScope.async(start = CoroutineStart.LAZY) {
val deviceId = get<Deferred<DeviceId>>(
MqttModule.LOCAL_DEVICE_ID
).await()
"${BuildConfig.FLAVOR}-android-${BuildConfig.VERSION_NAME}-${deviceId.uuid}_"
}
}
factory(Stream2Module.GROUP_UUID) {
GlobalScope.async(start = CoroutineStart.LAZY) {
get<UserRepository>().getUser()!!.groupUUID
}
}
single<Deferred<List<PeerConnection.IceServer>>>(Stream2Module.ICE_SERVERS) {
val stunTurn = mutableListOf<PeerConnection.IceServer>()
/**
* Converts Server model class to IceServer
*/
fun Server.toIceServer(protocol: String) = if (port != null) {
PeerConnection.IceServer.builder("$protocol:$hostname")
} else {
PeerConnection.IceServer.builder("$protocol:$hostname:$port")
}.apply {
if (user != null) {
setUsername(user.toString())
}
if (password != null) {
setPassword(password.toString())
}
}.createIceServer()
GlobalScope.async(start = CoroutineStart.LAZY) {
get<Deferred<ServerResponse?>>(named("servers")).await()?.run {
stunServers?.forEach {
stunTurn.add(it.toIceServer("stun"))
}
turnServers?.forEach {
stunTurn.add(it.toIceServer("turn"))
}
}
stunTurn
}
}
single { TimeSource.Monotonic }
}
))
properties(
mapOf(
RestModule.API_KEY to getString(R.string.api_key),
RestModule.USER_AGENT to "${BuildConfig.FLAVOR}/${BuildConfig.VERSION_NAME} Android/${Build.VERSION.SDK_INT}",
MqttModule.BASE_TOPIC to getString(R.string.topic)
)
)
androidLogger(if (BuildConfig.DEBUG) Level.DEBUG else Level.INFO)
}
GlobalScope.launch {
get<Deferred<OkHttpClient>>(named<OkHttpClient>()).await()
.let { okHttp ->
Coil.setImageLoader(
ImageLoaderBuilder(this@App)
.okHttpClient(
okHttp.newBuilder().cache(
CoilUtils.createDefaultCache(this@App)
).build()
)
.apply {
if (BuildConfig.DEBUG) {
logger(CoilTimberLogger())
}
}
.build()
)
}
}
/*277*/ GlobalScope.launch {
get<UserRepository>().let { userRepository ->
try {
with(userRepository.uuid.await()) {
FirebaseCrashlytics.getInstance().setUserId(uuid.toString())
get<FirebaseAnalytics>().setUserId(uuid.toString())
}
} catch (ioe: IOException) {
Timber.w(ioe, "DNS")
withContext(CoroutineContextProvider.UI) {
if (ioe.cause?.cause is UnknownHostException) {
Toast.makeText(
this@App,
ioe.cause!!.cause!!.localizedMessage,
Toast.LENGTH_LONG
).show()
} else {
Toast.makeText(this@App, ioe.localizedMessage, Toast.LENGTH_LONG).show()
}
}
}
userRepository.getUser()?.let { setCrashlyticsUser(it) }
}
Timber.plant(CrashlyticsTree())
val rests: Deferred<Annie2RestHelper> by inject(named<Annie2RestHelper>())
try {
FirebaseInstanceId.getInstance().instanceId.await()?.token?.let {
rests.await().updateFcmToken(it)
}
} catch (t: Throwable) {
Timber.w(t)
}
}
}
} |
There was a few fixes on R8/D8 side for such kind of issues, what Android Gradle plugin version do you use ? |
It could happen either because of R8 or because of Kotlin compiler that has a bug around experimental contracts that were added to coroutine builders in 1.3.7. I am still trying to reproduce it. As a potential workaround, I'd recommend extracting suspicious |
For the record I've just build my next prod build with 1.3.7, Kotlin 1.3.72 and latest AGP 4.0 RC1 / R8 and have not had this issue but faced https://issuetracker.google.com/issues/157223339 that is good to know if someone else report the issue here. |
It's happening with Android Gradle Plugins 3.6.2, 3.6.3 and 4.0.0-rc01, so I think it's not caused by D8/R8. Also, it's happening with debug builds, and I think they are not using R8 in default configuration. |
@qwwdfsad Moving |
Unfortunately, this is a bug in Kotlin compiler related to function with contracts that were added in #2030. We are working on the fix, a workaround is to extract |
I confirm that a similar problem https://youtrack.jetbrains.com/issue/KT-39298 is not reproduced with Kotlin 1.4-M2. The bug with contracts mentioned above was fixed in 1.4-M2. |
It happend to me when I used coroutines- withContext in 1.3.7 to 1.3.8 on Android/Flutter, revert coroutines lib to 1.3.6 , the app does not crash anymore. |
Changing kotlin_version to 1.4.0-rc solved the problem. |
Fixed in 1.3.9 with Kotlin 1.4 |
The similar error here with Coroutines 1.3.9 and Kotlin 1.4 (Android Gradle Plugin 4.0.1).
Error on line
If I comment out |
Ok, after some research I found that none of the new features from Kotlin 1.4 work. I think there is a bug in Android Studio, because |
@personshelldon did you fixed the problem? I am having the same issue. Could you share the link to the issue tracker in Android Studio? |
@ocampoleandro, yes, I fixed this issue by moving |
# Why Fixes: ``` 2021-05-07 17:53:30.805 11096-11096/host.exp.nclexp E/AndroidRuntime: FATAL EXCEPTION: main Process: host.exp.nclexp, PID: 11096 java.lang.VerifyError: Verifier rejected class expo.modules.devlauncher.helpers.DevLauncherCoroutinesExtensionsKt: java.lang.Object expo.modules.devlauncher.helpers.DevLauncherCoroutinesExtensionsKt.runBlockingOnMainThread(kotlin.jvm.functions.Function0) failed to verify: java.lang.Object expo.modules.devlauncher.helpers.DevLauncherCoroutinesExtensionsKt.runBlockingOnMainThread(kotlin.jvm.functions.Function0): [0x1C] cannot access instance field java.lang.Object kotlin.jvm.internal.Ref$ObjectRef.element from object of type Reference: kotlin.jvm.functions.Function0 (declaration of 'expo.modules.devlauncher.helpers.DevLauncherCoroutinesExtensionsKt' appears in /data/app/~~Pctup_2b0rAIMhpgLMjdzQ==/host.exp.nclexp-Jvfz4oK2KizpZpVNYK5cJQ==/base.apk!classes81.dex) at expo.modules.devlauncher.helpers.DevLauncherCoroutinesExtensionsKt.runBlockingOnMainThread(Unknown Source:0) at expo.modules.devlauncher.DevLauncherController.ensureHostWasCleared(DevLauncherController.kt:139) at expo.modules.devlauncher.DevLauncherController.ensureHostWasCleared$default(DevLauncherController.kt:137) at expo.modules.devlauncher.DevLauncherController.navigateToLauncher(DevLauncherController.kt:99) at expo.modules.devlauncher.DevLauncherController.redirectFromStartActivity(DevLauncherController.kt:180) at expo.modules.devlauncher.DevLauncherController.access$redirectFromStartActivity(DevLauncherController.kt:46) at expo.modules.devlauncher.DevLauncherController$getCurrentReactActivityDelegate$1.invoke(DevLauncherController.kt:172) at expo.modules.devlauncher.DevLauncherController$getCurrentReactActivityDelegate$1.invoke(DevLauncherController.kt:46) at expo.modules.devlauncher.react.activitydelegates.DevLauncherReactActivityRedirectDelegate.onCreate(DevLauncherReactActivityRedirectDelegate.kt:13) at com.facebook.react.ReactActivity.onCreate(ReactActivity.java:45) at host.exp.nclexp.MainActivity.onCreate(MainActivity.java:40) at android.app.Activity.performCreate(Activity.java:8000) at android.app.Activity.performCreate(Activity.java:7984) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 2021-05-07 17:53:30.883 11096-11096/host.exp.nclexp I/Process: Sending signal. PID: 11096 SIG: 9 ``` # How - Updated coroutines package to the newest version. - Added a workaround for something that looks like a bug in the compiler (see Kotlin/kotlinx.coroutines#2041). # Test Plan - newly created app with older kotlin version ✅
In
App.kt:277
is justGlobalScope.launch {
Reverting to 1.3.6 fixes the crash (but it has the #2004, which has a workaround)
The text was updated successfully, but these errors were encountered: