Status Update
Comments
ra...@google.com <ra...@google.com>
[Deleted User] <[Deleted User]> #2
Not at the moment. But we have been asked this before, so I will treat this as a feature request.
cs...@gmail.com <cs...@gmail.com> #3
OK thanks. At the moment I am just adding the name to the Data
for the work request and retrieving it in startWork()
, which works well enough.
ra...@google.com <ra...@google.com> #4
No # of crashes is not a good metric in this particular case. This is because when a crash happens JobScheduler
will retry the job, and this leads to a large number of crashes from a small number of devices affected. So a good metric to track is the total number of unique devices affected.
When the amount of disk space is low, there are very few things WorkManager can do as a client library. Apps should determine what they would like to do. You can use
cs...@gmail.com <cs...@gmail.com> #5
We might be able to handle it using UncaughtExceptionHandler but it could unexpectedly hide issue that should be resolved, especially without understanding crashes like those non-disk-full ones.
su...@google.com <su...@google.com> #6
Since WorkManager is initialized very early in your app lifecycle, it's quite likely that it will be the one that catches disk full errors first and be the first to fail. So this is a real problem that will affect your app no matter what, even if WorkManager wasn't there.
cs...@gmail.com <cs...@gmail.com> #7
If we want to look at these exception as a whole, how could application recover? I assume whenever workmanager hit these SQLiteExceptions, SQLiteDiskIOException or SQLiteFullException, restart will not help and WorkManager will no longer be able to ensure all the scheduled work being executed.
om...@a8c.com <om...@a8c.com> #8
Maybe adding a fallback solution when trying to read the database or having an error callback so we can try to remediate (clearing cache, or similar) or at least to let us know it couldn't initialize and we can continue the execution without work schedules, but i don't think crashing the whole process is the best choice.
ad...@linkedin.com <ad...@linkedin.com> #9
ra...@google.com <ra...@google.com> #10
We are working on the design for a new API to address this.
For now, the best you can do is to use a Exception
points to a StackTraceElement
that was WorkManager
or look at unrecoverable SQLiteException
sa...@gmail.com <sa...@gmail.com> #11
ra...@google.com <ra...@google.com> #12
Nothing yet. We plan to have something in version 2.6.x
time frame.
st...@gmail.com <st...@gmail.com> #13
Fatal Exception: android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 4874 SQLITE_IOERR_SHMSIZE): , while compiling: PRAGMA journal_mode
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(SQLiteConnection.java)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:903)
at android.database.sqlite.SQLiteConnection.executeForString(SQLiteConnection.java:648)
at android.database.sqlite.SQLiteConnection.setJournalMode(SQLiteConnection.java:333)
at android.database.sqlite.SQLiteConnection.setWalModeFromConfiguration(SQLiteConnection.java:298)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:217)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:195)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:503)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:204)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:196)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:880)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:865)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:739)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:729)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:355)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:298)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:145)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:106)
at androidx.room.RoomDatabase.beginTransaction(RoomDatabase.java:352)
at androidx.work.impl.utils.ForceStopRunnable.cleanUp(ForceStopRunnable.java:156)
at androidx.work.impl.utils.ForceStopRunnable.run(ForceStopRunnable.java:87)
at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:91)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
on
Brand: Xiaomi
Model: MiBox S
Orientation: Portrait
RAM free: 1.12 GB
Disk free: 808 KB
So it crashes during app start-up, when there is no free disk space
ba...@gmail.com <ba...@gmail.com> #14
ra...@google.com <ra...@google.com> #15
We are planning on introducing this API in SQLite, and Room so this is going to take a bit longer. In the meantime, you can consider using the @Restricted
API (
You will need to @Suppress
restricted APIs for now.
om...@a8c.com <om...@a8c.com> #16
Thanks for the update!
We are currently using setInitializationExceptionHandler
method, and while it helped reducing crashes happening in ForceStopRunnable
that solution doesn't cover the crashes happening in other runnables like WorkerWrapper
for Example:
Fatal Exception: android.database.sqlite.SQLiteDatabaseCorruptException
file is not a database (code 26 SQLITE_NOTADB)
android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow (SQLiteConnection.java)
android.database.sqlite.SQLiteConnection.executeForCursorWindow (SQLiteConnection.java:942)
android.database.sqlite.SQLiteSession.executeForCursorWindow (SQLiteSession.java:838)
android.database.sqlite.SQLiteQuery.fillWindow (SQLiteQuery.java:62)
android.database.sqlite.SQLiteCursor.fillWindow (SQLiteCursor.java:153)
android.database.sqlite.SQLiteCursor.getCount (SQLiteCursor.java:140)
androidx.work.impl.model.WorkTagDao_Impl.getTagsForWorkSpecId (WorkTagDao_Impl.java:96)
Also please make sure to consider the native crashes as well when creating that API, since that's the majority of the crashes.
For example:
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR)
android::nativePrepareStatement(_JNIEnv*, _jclass*, long, _jstring*)
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.example <<<
backtrace:
#00 pc 0000000000131658 /system/lib64/libandroid_runtime.so (android::nativePrepareStatement(_JNIEnv*, _jclass*, long, _jstring*)+96)
#00 pc 00000000002b5c44 /system/framework/arm64/boot-framework.oat (art_jni_trampoline+180)
#00 pc 000000000056cce0 /system/framework/arm64/boot-framework.oat (android.database.sqlite.SQLiteConnection.acquirePreparedStatement+192)
#00 pc 0000000000572e10 /system/framework/arm64/boot-framework.oat (android.database.sqlite.SQLiteConnection.prepare+176)
#00 pc 000000000046cbd0 /system/framework/arm64/boot-framework.oat (android.database.sqlite.SQLiteSession.prepare+288)
#00 pc 000000000057902c /system/framework/arm64/boot-framework.oat (android.database.sqlite.SQLiteProgram.<init>+444)
#00 pc 0000000000575a14 /system/framework/arm64/boot-framework.oat (android.database.sqlite.SQLiteDatabase.compileStatement+116)
#00 pc 0000000000137334 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548)
#00 pc 000000000014606c /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244)
#00 pc 00000000002e0784 /apex/com.android.runtime/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+384)
#00 pc 00000000002dba64 /apex/com.android.runtime/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+912)
#00 pc 000000000059a38c /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+648)
#00 pc 0000000000131814 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20)
#00 pc 00000000003b66f2 /system/framework/framework.jar (android.database.sqlite.SQLiteDatabase.isDatabaseIntegrityOk+222)
#00 pc 000000000059a69c /apex/com.android.runtime/lib64/libart.so (MterpInvokeVirtual+1432)
#00 pc 0000000000131814 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_virtual+20)
#00 pc 00000000003ab30c /system/framework/framework.jar (android.database.DefaultDatabaseErrorHandler.diagnoseDatabase+128)
#00 pc 000000000059ca2c /apex/com.android.runtime/lib64/libart.so (MterpInvokeDirect+1168)
#00 pc 0000000000131914 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_direct+20)
#00 pc 00000000003abb90 /system/framework/framework.jar (android.database.DefaultDatabaseErrorHandler.onCorruption+304)
#00 pc 000000000059be90 /apex/com.android.runtime/lib64/libart.so (MterpInvokeInterface+1740)
#00 pc 0000000000131a14 /apex/com.android.runtime/lib64/libart.so (mterp_op_invoke_interface+20)
#00 pc 00000000003b8a10 /system/framework/framework.jar (android.database.sqlite.SQLiteDatabase.onCorruption+80)
#00 pc 00000000002b13d0 /apex/com.android.runtime/lib64/libart.so (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.7142318256121416140)+240)
#00 pc 000000000058b994 /apex/com.android.runtime/lib64/libart.so (artQuickToInterpreterBridge+1012)
#00 pc 0000000000140468 /apex/com.android.runtime/lib64/libart.so (art_quick_to_interpreter_bridge+88)
#00 pc 000000000068f1fc /system/framework/arm64/boot-framework.oat (android.database.sqlite.SQLiteQuery.fillWindow+732)
#00 pc 00000000006d8fc8 /system/framework/arm64/boot-framework.oat (android.database.sqlite.SQLiteCursor.fillWindow+344)
#00 pc 00000000006d98e8 /system/framework/arm64/boot-framework.oat (android.database.sqlite.SQLiteCursor.getCount+56)
#00 pc 000000000059900c /data/app/com.example-2NKb9y8uQYC083YPNqBiBQ==/oat/arm64/base.odex (androidx.work.impl.n.u.a+300)
#00 pc 00000000003f6124 /data/app/com.example-2NKb9y8uQYC083YPNqBiBQ==/oat/arm64/base.odex (androidx.work.impl.k.run+84)
#00 pc 00000000003fbeb8 /data/app/com.example-2NKb9y8uQYC083YPNqBiBQ==/oat/arm64/base.odex (androidx.work.impl.utils.g$a.run+72)
#00 pc 00000000002fa878 /system/framework/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor.runWorker+984)
#00 pc 00000000002f7ee0 /system/framework/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor$Worker.run+64)
#00 pc 00000000001a5568 /system/framework/arm64/boot.oat (java.lang.Thread.run+72)
#00 pc 0000000000137334 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548)
#00 pc 000000000014606c /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244)
#00 pc 00000000004ab9d4 /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104)
#00 pc 00000000004aca68 /apex/com.android.runtime/lib64/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue const*)+416)
#00 pc 00000000004ecdac /apex/com.android.runtime/lib64/libart.so (art::Thread::CreateCallback(void*)+1176)
#00 pc 00000000000e28c0 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36)
#00 pc 000000000008503c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)
ra...@google.com <ra...@google.com> #17
Does the app use multiple processes ?
om...@a8c.com <om...@a8c.com> #18
No, single process (Also checked the merged manifest to double check third party libraries defining android:process
for any component, and couldn't find any)
st...@gmail.com <st...@gmail.com> #19
Any update since 2.6.0 release?
ja...@glance.com <ja...@glance.com> #20
ba...@gmail.com <ba...@gmail.com> #21
```
} catch (SQLiteCantOpenDatabaseException
| SQLiteDatabaseCorruptException
| SQLiteDatabaseLockedException
| SQLiteTableLockedException
| SQLiteConstraintException
| SQLiteAccessPermException exception) {
```
We are not passing to the "InitializationExceptionHandler" the exception when it is an i/o or disk issue (ex: SQLiteDiskIOException, SQLiteFullException or just plain SQLiteException). These are the exceptions reported. Any reason for that?
As is, "InitializationExceptionHandler" is not helping.
zh...@gmail.com <zh...@gmail.com> #22
I got the same issue when I use room v2.1.0 . Android 11
su...@gmail.com <su...@gmail.com> #23
We are using latest stable work manager (2.8.1) and for very few users we see following exception and all those users are on Android 13
java.lang.IllegalStateException: The database '/data/user/10/<package-name>/no_backup/androidx.work.workdb' is not open.
at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2483)
at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:431)
at android.database.sqlite.SQLiteDatabase$$ExternalSyntheticLambda1.get(Unknown Source:2)
at java.lang.ThreadLocal$SuppliedThreadLocal.initialValue(ThreadLocal.java:284)
at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180)
at java.lang.ThreadLocal.get(ThreadLocal.java:170)
at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:425)
at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:105)
at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:67)
at androidx.sqlite.db.framework.FrameworkSQLiteStatement.executeUpdateDelete(FrameworkSQLiteStatement.kt:38)
at androidx.work.impl.model.WorkSpecDao_Impl.setState(WorkSpecDao_Impl.java:380)
at androidx.work.impl.WorkerWrapper.resolve(WorkerWrapper.java:458)
at androidx.work.impl.WorkerWrapper.rescheduleAndResolve(WorkerWrapper.java:558)
at androidx.work.impl.WorkerWrapper.onWorkFinished(WorkerWrapper.java:360)
at androidx.work.impl.WorkerWrapper$2.run(WorkerWrapper.java:335)
at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at java.lang.Thread.run(Thread.java:1012)
se...@google.com <se...@google.com> #24
The database '/data/user/10/<package-name>/no_backup/androidx.work.workdb' is not open.
this one is 99% of direct boot. You can add UserManagerCompat.isUserUnlocked(mContext)
to see if it is the case, when you try to initialise WorkManager.
In the future version we've added
su...@gmail.com <su...@gmail.com> #25
Not 100% sure where one is supposed to insert that check. In our app we initialize work manager like this
@Provides
@Singleton
fun provideWorkManager(@ForApplication context: Context): WorkManager {
return WorkManager.getInstance(context)
}
So is the suggestion to change the code to something like this?
@Provides
@Singleton
fun provideWorkManager(@ForApplication context: Context): WorkManager? {
return if (UserManagerCompat.isUserUnlocked(mContext)) {
WorkManager.getInstance(context)
} else
null
}
}
su...@gmail.com <su...@gmail.com> #26
Also if the app doesn't explicitly declare that it is directBootAware, why is it even running? I don't have this android:directBootAware="true" directive in AndroidManifest.xml, do I really need to change workManager getInstance?
se...@google.com <se...@google.com> #27
directBootAware
could come from another library, you should check merged manifest of your application.
su...@gmail.com <su...@gmail.com> #28
Indeed FirebaseMessagingService & ComponentDiscoveryService request directBoot
<service
android:name="com.google.firebase.messaging.FirebaseMessagingService"
android:directBootAware="true"
android:exported="false" >
<intent-filter android:priority="-500" >
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service
android:name="com.google.firebase.components.ComponentDiscoveryService"
android:directBootAware="true"
android:exported="false" >
<meta-data
android:name="com.google.firebase.components:com.google.firebase.messaging.FirebaseMessagingRegistrar"
android:value="com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name="com.google.firebase.components:com.google.firebase.datatransport.TransportRegistrar"
android:value="com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name="com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar"
android:value="com.google.firebase.components.ComponentRegistrar" />
</service>
se...@google.com <se...@google.com> #29
FirebaseMessagingService
is an issue and we'll try to think what kind of pattern we can provide on WM side for better handling of this. For now you have to handle it on app side.
PS ComponentDiscoveryService
doesn't do anything actually, so its directBootAware = true
is kinda red herring.
su...@gmail.com <su...@gmail.com> #30
Perhaps orthogonal - our app also "upgrade" the database if we detect new installs, I take it one should also defer execution of performing any database upgrades if UserManagerCompat.isUserUnlocked(mContext)
returns false?
Perhaps updating WorkManager documentation to specifically call out the scenario of direct-boot might be useful to other developers as well.
Thanks for the help!
zz...@gmail.com <zz...@gmail.com> #31
It is the highest error reported so far,
Exception java.lang.RuntimeException: Exception while computing database live data.
at androidx.room.RoomTrackingLiveData$1.run (SourceFile:6)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:637)
at java.lang.Thread.run (Thread.java:1012)
Caused by android.database.sqlite.SQLiteCantOpenDatabaseException:
at android.database.sqlite.SQLiteConnection.open (SQLiteConnection.java:254)
at android.database.sqlite.SQLiteConnection.open (SQLiteConnection.java:205)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked (SQLiteConnectionPool.java:505)
at android.database.sqlite.SQLiteConnectionPool.open (SQLiteConnectionPool.java:206)
at android.database.sqlite.SQLiteConnectionPool.open (SQLiteConnectionPool.java:198)
at android.database.sqlite.SQLiteDatabase.openInner (SQLiteDatabase.java:928)
at android.database.sqlite.SQLiteDatabase.open (SQLiteDatabase.java:908)
at android.database.sqlite.SQLiteDatabase.openDatabase (SQLiteDatabase.java:772)
at android.database.sqlite.SQLiteDatabase.openDatabase (SQLiteDatabase.java:761)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked (SQLiteOpenHelper.java:373)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase (SQLiteOpenHelper.java:316)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase (SourceFile:2)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase (SourceFile:1)
at androidx.room.RoomDatabase.inTransaction (SourceFile:1)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction (SourceFile:1)
at androidx.room.RoomDatabase.query (SourceFile:4)
at androidx.room.util.DBUtil.query (SourceFile:2)
at com.transsion.repository.searchengine.source.local.SearchEngineDao_Impl$9.call (SourceFile:2)
at com.transsion.repository.searchengine.source.local.SearchEngineDao_Impl$9.call (SourceFile:1)
at androidx.room.RoomTrackingLiveData$1.run (SourceFile:5)
Caused by android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14 SQLITE_CANTOPEN): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen
at android.database.sqlite.SQLiteConnection.open (SQLiteConnection.java:224)
ma...@gmail.com <ma...@gmail.com> #32
WorkManager 2.8.1
SQLiteCantOpenDatabaseException: Cannot open database '/data/user/0/<package_name>/no_backup/androidx.work.workdb': Directory /data/user/0/<package_name>/no_backup doesn't exist
se...@google.com <se...@google.com> #33
se...@wbd.com <se...@wbd.com> #34
We're seeing this exception for Android 9 and 10 devices only. We're not even making use of WorkManager directly.
Exception java.lang.IllegalStateException: The file system on the device is in a bad state. WorkManager cannot access the app's internal data store.
at androidx.work.impl.utils.ForceStopRunnable.run (ForceStopRunnable.java:113)
at androidx.work.impl.utils.SerialExecutor$Task.run (SerialExecutor.java)
at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:641)
at java.lang.Thread.run (Thread.java:919)
Caused by android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14 SQLITE_CANTOPEN): Could not open database
at android.database.sqlite.SQLiteConnection.nativeOpen
at android.database.sqlite.SQLiteConnection.open (SQLiteConnection.java:215)
at android.database.sqlite.SQLiteConnection.open (SQLiteConnection.java:197)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked (SQLiteConnectionPool.java:505)
at android.database.sqlite.SQLiteConnectionPool.open (SQLiteConnectionPool.java:206)
at android.database.sqlite.SQLiteConnectionPool.open (SQLiteConnectionPool.java:198)
at android.database.sqlite.SQLiteDatabase.openInner (SQLiteDatabase.java:915)
at android.database.sqlite.SQLiteDatabase.open (SQLiteDatabase.java:895)
at android.database.sqlite.SQLiteDatabase.openDatabase (SQLiteDatabase.java:759)
at android.database.sqlite.SQLiteDatabase.openDatabase (SQLiteDatabase.java:748)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked (SQLiteOpenHelper.java:374)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase (SQLiteOpenHelper.java:317)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase (FrameworkSQLiteOpenHelper.java)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase (FrameworkSQLiteOpenHelper.java)
at androidx.room.RoomDatabase.inTransaction (RoomDatabase.java)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction (RoomDatabase.java)
at androidx.work.impl.model.SystemIdInfoDao_Impl.getWorkSpecIds (SystemIdInfoDao_Impl.java:50)
at androidx.work.impl.background.systemjob.SystemJobScheduler.reconcileJobs (SystemJobScheduler.java:50)
at androidx.work.impl.utils.ForceStopRunnable.cleanUp (ForceStopRunnable.java:50)
at androidx.work.impl.utils.ForceStopRunnable.forceStopRunnable (ForceStopRunnable.java:50)
at androidx.work.impl.utils.ForceStopRunnable.run (ForceStopRunnable.java:32)
ar...@glance.com <ar...@glance.com> #35
[Deleted User] <[Deleted User]> #36
an...@gmail.com <an...@gmail.com> #37
xu...@gmail.com <xu...@gmail.com> #38
Room : v2.3.0
Workmanager : v2.7.0
Android OS : 12
ay...@google.com <ay...@google.com> #39
Thanks for your support!
ka...@gmail.com <ka...@gmail.com> #40
bj...@linkedin.com <bj...@linkedin.com> #41
Please, let us know if there is any work being done for this issue. We are seeing in several Android versions, 9, 10, 11, 12, 13. pretty even amount device types too.
android.database.sqlite.SQLiteCantOpenDatabaseException:unknown error (code 14 SQLITE_CANTOPEN): Could not open database
at androidx.work.impl.utils . ForceStopRunnable . run() (ForceStopRunnable.java:153)
at androidx.work.impl.utils . SerialExecutorImpl . run() (SerialExecutorImpl.java:96)
at java.util.concurrent . ThreadPoolExecutor . runWorker() (ThreadPoolExecutor.java:1167)
at java.util.concurrent . ThreadPoolExecutor . run() (ThreadPoolExecutor.java:641)
at java.lang . Thread . run() (Thread.java:919)
at Caused by android.database.sqlite.SQLiteCantOpenDatabaseException:unknown error (code 14 SQLITE_CANTOPEN): Could not open database()
at android.database.sqlite . SQLiteConnection . nativeOpen() (SQLiteConnection.java:-2)
at android.database.sqlite . SQLiteConnection . open() (SQLiteConnection.java:215)
at android.database.sqlite . SQLiteConnection . open() (SQLiteConnection.java:197)
at android.database.sqlite . SQLiteConnectionPool . openConnectionLocked() (SQLiteConnectionPool.java:505)
at android.database.sqlite . SQLiteConnectionPool . open() (SQLiteConnectionPool.java:206)
at android.database.sqlite . SQLiteConnectionPool . open() (SQLiteConnectionPool.java:198)
at android.database.sqlite . SQLiteDatabase . openInner() (SQLiteDatabase.java:915)
at android.database.sqlite . SQLiteDatabase . open() (SQLiteDatabase.java:895)
at android.database.sqlite . SQLiteDatabase . openDatabase() (SQLiteDatabase.java:759)
at android.database.sqlite . SQLiteDatabase . openDatabase() (SQLiteDatabase.java:748)
at android.database.sqlite . SQLiteOpenHelper . getDatabaseLocked() (SQLiteOpenHelper.java:374)
at android.database.sqlite . SQLiteOpenHelper . getWritableDatabase() (SQLiteOpenHelper.java:317)
at androidx.sqlite.db.framework . FrameworkSQLiteOpenHelper . getWritableOrReadableDatabase() (FrameworkSQLiteOpenHelper.kt:232)
at androidx.sqlite.db.framework . FrameworkSQLiteOpenHelper . innerGetDatabase() (FrameworkSQLiteOpenHelper.kt:223)
at androidx.sqlite.db.framework . FrameworkSQLiteOpenHelper . getSupportDatabase() (FrameworkSQLiteOpenHelper.kt:151)
at androidx.sqlite.db.framework . FrameworkSQLiteOpenHelper . getWritableDatabase() (FrameworkSQLiteOpenHelper.kt:104)
at androidx.room . RoomDatabase . inTransaction() (RoomDatabase.kt:638)
at androidx.room . RoomDatabase . assertNotSuspendingTransaction() (RoomDatabase.kt:457)
at androidx.work.impl.model . SystemIdInfoDao_Impl . getWorkSpecIds() (SystemIdInfoDao_Impl.java:163)
at androidx.work.impl.background.systemjob . SystemJobScheduler . reconcileJobs() (SystemJobScheduler.java:311)
at androidx.work.impl.utils . ForceStopRunnable . cleanUp() (ForceStopRunnable.java:278)
at androidx.work.impl.utils . ForceStopRunnable . forceStopRunnable() (ForceStopRunnable.java:242)
at androidx.work.impl.utils . ForceStopRunnable . run() (ForceStopRunnable.java:134)
at androidx.work.impl.utils . SerialExecutorImpl . run() (SerialExecutorImpl.java:96)
at java.util.concurrent . ThreadPoolExecutor . runWorker() (ThreadPoolExecutor.java:1167)
at java.util.concurrent . ThreadPoolExecutor . run() (ThreadPoolExecutor.java:641)
at java.lang . Thread . run() (Thread.java:919
ra...@google.com <ra...@google.com> #42
For folks facing this issue:
There are many reasons why this could happen. This is a result of an underlying framework bug but one of the common cases is:
When an app is using multiple processes, and does not designate a "default" process using the
We recently added APIs that allow the app to recover.
This API can be used to clear your datastore, and start over from a clean slate.
su...@gmail.com <su...@gmail.com> #43
schedule few tasks to be executed in background using workmanager .
All of this gets kicked off in onapp create. What should be the process
name in that case?
Subodh
On Tue, Dec 19, 2023, 10:43 AM <buganizer-system@google.com> wrote:
ra...@google.com <ra...@google.com> #44
The default process name is the same as the package name of the app.
Secondary processes are defined in your AndroidManifest.xml
using the :suffix
convention.
If your package name is com.example.app
, and your manifest defines a :secondary
process then you will run as 2 processes:
com.example.app
, andcom.example.app:secondary
.
an...@sliide.com <an...@sliide.com> #45
I have a question regarding this point:
"This API can be used to clear your datastore, and start over from a clean slate."
How would clearing the app's datastore fix the issue?
I see that WorkManager internally uses a room database to keep track of the ongoing work. How are we supposed to clear the data of the room database that WorkManager uses internally?
Thanks
Ana
anai@sliide.com
lb...@gmail.com <lb...@gmail.com> #47
@46 That's not a good solution. This API doesn't even bring back the app when it's done. It force-stop of it...
le...@google.com <le...@google.com> #48
Re #44 - is it possible that having a service
with isolatedProcess=true
in our manifest could trigger the multi-process issue?
le...@google.com <le...@google.com> #49
Also, if the answer to #48 is yes and we are able to add a call to setDefaultProcessName
to fix, would we need to also add the setInitializationExceptionHandler
call and clear user data in order to get users out of a crash loop state? Or would just the former likely be enough and these crashes would stop once we set default process name? Would love to avoid clearing app data if possible.
Description
Version used: 2.3.2
Devices/Android versions reproduced on: This happens in our production environment. (We are an app with 500M+ installs). These exceptions happen for all Android OS and Android devices. And there are among the top 20 exceptions of our app.
This is a revival of
We have collected the following 4 exception traces from our internal crash reporting tool. We also checked that those exceptions exist from Android Vital crashes as well.
Here are steps we have attempted to fix but in vail:
- Bump
- We suspect this is due to full disk usage. We migrated all calls of enqueue() to enqueueWork() as an attempt to reduce the number of entries in the SQLiteDatabase, but it was not effective in reducing the number of exceptions.
- We also make sure that the first statement wrt WorkManager in Application.onCreate() is pruneWork() -> WorkManager.getInstance(application).pruneWork().
Please take a look at this and suggest the next steps. Thank you.
Crash 1:
android.database.sqlite.SQLiteException:not an error (Sqlite code 0): Could not open the database in read/write mode., (OS error - 30:Read-only file system)
android.database.sqlite.nativeOpen ( SQLiteConnection .java :-2)
android.database.sqlite.open ( SQLiteConnection .java :217)
android.database.sqlite.open ( SQLiteConnection .java :201)
android.database.sqlite.openConnectionLocked ( SQLiteConnectionPool .java :493)
android.database.sqlite.open ( SQLiteConnectionPool .java :194)
android.database.sqlite.open ( SQLiteConnectionPool .java :183)
android.database.sqlite.openInner ( SQLiteDatabase .java :826)
android.database.sqlite.open ( SQLiteDatabase .java :810)
android.database.sqlite.openDatabase ( SQLiteDatabase .java :713)
android.app.openOrCreateDatabase ( ContextImpl .java :652)
android.content.openOrCreateDatabase ( ContextWrapper .java :269)
android.database.sqlite.getDatabaseLocked ( SQLiteOpenHelper .java :235)
android.database.sqlite.getWritableDatabase ( SQLiteOpenHelper .java :175)
androidx.sqlite.db.framework.getWritableSupportDatabase ( FrameworkSQLiteOpenHelper .java :92)
androidx.sqlite.db.framework.getWritableDatabase ( FrameworkSQLiteOpenHelper .java :53)
androidx.room.inTransaction ( RoomDatabase .java :452)
androidx.room.assertNotSuspendingTransaction ( RoomDatabase .java :275)
androidx.work.impl.model.getTagsForWorkSpecId ( WorkTagDao_Impl .java :93)
androidx.work.impl.run ( WorkerWrapper .java :125)
androidx.work.impl.utils.run ( SerialExecutor .java :91)
java.util.concurrent.runWorker ( ThreadPoolExecutor .java :1113)
java.util.concurrent.run ( ThreadPoolExecutor .java :588)
java.lang.run ( Thread .java :833)
Crash 2:
android.database.sqlite.SQLiteFullException:disk I/O error (code 7690): , while compiling: PRAGMA journal_mode ################################################################# Error Code : 7690 (SQLITE_IOERR) Caused By : disk I/O error occurred. (disk I/O error (code 7690): , while compiling: PRAGMA journal_mode) #################################################################
android.database.sqlite.nativePrepareStatement ( SQLiteConnection .java :-2)
android.database.sqlite.acquirePreparedStatement ( SQLiteConnection .java :1095)
android.database.sqlite.executeForString ( SQLiteConnection .java :799)
android.database.sqlite.setJournalMode ( SQLiteConnection .java :448)
android.database.sqlite.setWalModeFromConfiguration ( SQLiteConnection .java :419)
android.database.sqlite.open ( SQLiteConnection .java :271)
android.database.sqlite.open ( SQLiteConnection .java :204)
android.database.sqlite.openConnectionLocked ( SQLiteConnectionPool .java :633)
android.database.sqlite.open ( SQLiteConnectionPool .java :242)
android.database.sqlite.open ( SQLiteConnectionPool .java :214)
android.database.sqlite.openInner ( SQLiteDatabase .java :1184)
android.database.sqlite.open ( SQLiteDatabase .java :1139)
android.database.sqlite.openDatabase ( SQLiteDatabase .java :854)
android.app.openOrCreateDatabase ( ContextImpl .java :729)
android.content.openOrCreateDatabase ( ContextWrapper .java :310)
android.database.sqlite.getDatabaseLocked ( SQLiteOpenHelper .java :254)
android.database.sqlite.getWritableDatabase ( SQLiteOpenHelper .java :194)
androidx.sqlite.db.framework.getWritableSupportDatabase ( FrameworkSQLiteOpenHelper .java :92)
androidx.sqlite.db.framework.getWritableDatabase ( FrameworkSQLiteOpenHelper .java :53)
androidx.room.inTransaction ( RoomDatabase .java :452)
androidx.room.assertNotSuspendingTransaction ( RoomDatabase .java :275)
androidx.work.impl.model.getTagsForWorkSpecId ( WorkTagDao_Impl .java :93)
androidx.work.impl.run ( WorkerWrapper .java :125)
androidx.work.impl.utils.run ( SerialExecutor .java :75)
java.util.concurrent.runWorker ( ThreadPoolExecutor .java :1162)
java.util.concurrent.run ( ThreadPoolExecutor .java :636)
java.lang.run ( Thread .java :764)
Crash 3:
android.database.sqlite.SQLiteDiskIOException:disk I/O error (code 4874): , while compiling: PRAGMA journal_mode ################################################################# Error Code : 4874 (SQLITE_IOERR_SHMSIZE) Caused By : No available space in disk. (disk I/O error (code 4874): , while compiling: PRAGMA journal_mode) #################################################################
android.database.sqlite.nativePrepareStatement ( SQLiteConnection .java :-2)
android.database.sqlite.acquirePreparedStatement ( SQLiteConnection .java :1058)
android.database.sqlite.executeForString ( SQLiteConnection .java :762)
android.database.sqlite.setJournalMode ( SQLiteConnection .java :443)
android.database.sqlite.setWalModeFromConfiguration ( SQLiteConnection .java :414)
android.database.sqlite.open ( SQLiteConnection .java :315)
android.database.sqlite.open ( SQLiteConnection .java :210)
android.database.sqlite.openConnectionLocked ( SQLiteConnectionPool .java :512)
android.database.sqlite.open ( SQLiteConnectionPool .java :206)
android.database.sqlite.open ( SQLiteConnectionPool .java :178)
android.database.sqlite.openInner ( SQLiteDatabase .java :908)
android.database.sqlite.open ( SQLiteDatabase .java :878)
android.database.sqlite.openDatabase ( SQLiteDatabase .java :699)
android.app.openOrCreateDatabase ( ContextImpl .java :633)
android.content.openOrCreateDatabase ( ContextWrapper .java :283)
android.database.sqlite.getDatabaseLocked ( SQLiteOpenHelper .java :223)
android.database.sqlite.getWritableDatabase ( SQLiteOpenHelper .java :163)
androidx.sqlite.db.framework.getWritableSupportDatabase ( FrameworkSQLiteOpenHelper .java :92)
androidx.sqlite.db.framework.getWritableDatabase ( FrameworkSQLiteOpenHelper .java :53)
androidx.room.inTransaction ( RoomDatabase .java :452)
androidx.room.assertNotSuspendingTransaction ( RoomDatabase .java :275)
androidx.work.impl.model.getTagsForWorkSpecId ( WorkTagDao_Impl .java :93)
androidx.work.impl.run ( WorkerWrapper .java :125)
androidx.work.impl.utils.run ( SerialExecutor .java :75)
java.util.concurrent.runWorker ( ThreadPoolExecutor .java :1113)
java.util.concurrent.run ( ThreadPoolExecutor .java :588)
java.lang.run ( Thread .java :818)
Crash 4:
android.database.sqlite.SQLiteDiskIOException:disk I/O error (code 4874 SQLITE_IOERR_SHMSIZE): , while compiling: PRAGMA journal_mode
android.database.sqlite.nativePrepareStatement ( SQLiteConnection .java :-2)
android.database.sqlite.acquirePreparedStatement ( SQLiteConnection .java :939)
android.database.sqlite.executeForString ( SQLiteConnection .java :684)
android.database.sqlite.setJournalMode ( SQLiteConnection .java :369)
android.database.sqlite.setWalModeFromConfiguration ( SQLiteConnection .java :299)
android.database.sqlite.open ( SQLiteConnection .java :218)
android.database.sqlite.open ( SQLiteConnection .java :196)
android.database.sqlite.openConnectionLocked ( SQLiteConnectionPool .java :503)
android.database.sqlite.open ( SQLiteConnectionPool .java :204)
android.database.sqlite.open ( SQLiteConnectionPool .java :196)
android.database.sqlite.openInner ( SQLiteDatabase .java :880)
android.database.sqlite.open ( SQLiteDatabase .java :865)
android.database.sqlite.openDatabase ( SQLiteDatabase .java :739)
android.database.sqlite.openDatabase ( SQLiteDatabase .java :729)
android.database.sqlite.getDatabaseLocked ( SQLiteOpenHelper .java :355)
android.database.sqlite.getWritableDatabase ( SQLiteOpenHelper .java :298)
androidx.sqlite.db.framework.getWritableSupportDatabase ( FrameworkSQLiteOpenHelper .java :92)
androidx.sqlite.db.framework.getWritableDatabase ( FrameworkSQLiteOpenHelper .java :53)
androidx.room.beginTransaction ( RoomDatabase .java :328)
androidx.work.impl.utils.cleanUp ( ForceStopRunnable .java :135)
androidx.work.impl.utils.run ( ForceStopRunnable .java :79)
androidx.work.impl.utils.run ( SerialExecutor .java :91)
java.util.concurrent.runWorker ( ThreadPoolExecutor .java :1167)
java.util.concurrent.run ( ThreadPoolExecutor .java :641)
java.lang.run ( Thread .java :764)