-
Notifications
You must be signed in to change notification settings - Fork 127
Closed
Closed
Copy link
Labels
bugSomething isn't workingSomething isn't workingstorageRelated to the Storage category/pluginsRelated to the Storage category/plugins
Description
Before opening, please confirm:
- I have searched for duplicate or closed issues and discussions.
Language and Async Model
Kotlin
Amplify Categories
Storage
Gradle script dependencies
// libs.versions.toml
[versions]
aws = "2.16.0"
[libraries]
aws-storage-s3 = { group = "com.amplifyframework", name = "aws-storage-s3", version.ref = "aws" }
aws-auth-cognito = { group = "com.amplifyframework", name = "aws-auth-cognito", version.ref = "aws" }
aws-core-kotlin = { group = "com.amplifyframework", name = "core-kotlin", version.ref = "aws" }
// build.gradle.kts (Module: app)
implementation(libs.aws.storage.s3)
implementation(libs.aws.auth.cognito)
// build.gradle.kts (Module: sync)
implementation(libs.aws.storage.s3)
implementation(libs.aws.core.kotlin)Environment information
# Put output below this line
------------------------------------------------------------
Gradle 8.7
------------------------------------------------------------
Build time: 2024-03-22 15:52:46 UTC
Revision: 650af14d7653aa949fce5e886e685efc9cf97c10
Kotlin: 1.9.22
Groovy: 3.0.17
Ant: Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM: 17.0.10 (Amazon.com Inc. 17.0.10+7-LTS)
OS: Mac OS X 14.3.1 aarch64
Please include any relevant guides or documentation you're referencing
https://docs.amplify.aws/gen1/android/build-a-backend/storage/upload/#upload-files
Upload files with StoragePath
Describe the bug
The amplify version that i am using is 2.16.0, and I can't re-produce the problem because I counter it on Firebase Crashlytics.
But it occurs when I use workmanager for upload log files periodically using PeriodicWorkRequest.
Reproduction steps (if applicable)
No response
Code Snippet
// Put your code below this line.
// This is a simplified version of the code.
import android.content.Context
import androidx.hilt.work.HiltWorker
import androidx.work.CoroutineWorker
import androidx.work.ForegroundInfo
import androidx.work.WorkerParameters
import com.amplifyframework.kotlin.core.Amplify
import com.sample.sync.initializers.logSyncForegroundInfo
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
import java.io.File
import com.amplifyframework.storage.StoragePath
import com.sample.core.data.AppDispatchers.IO
import com.sample.core.data.Dispatcher
import com.sample.sync.BuildConfig
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import timber.log.Timber
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@HiltWorker
class LogUploadWorker @AssistedInject constructor(
@Assisted private val appContext: Context,
@Assisted workerParams: WorkerParameters,
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher
) : CoroutineWorker(appContext, workerParams) {
override suspend fun getForegroundInfo(): ForegroundInfo =
appContext.logSyncForegroundInfo()
override suspend fun doWork(): Result = withContext(ioDispatcher) {
try {
val externalFilesDirPath = inputData.getString("externalFilesDirPath")
val externalFilesDir = externalFilesDirPath?.let { File(it) }
if (externalFilesDir != null && externalFilesDir.exists()) {
uploadLogFiles(externalFilesDir)
}
} catch (e: Exception) {
Timber.e("Log upload exception: ${e.message}")
Result.retry()
}
Result.success()
}
@OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
private suspend fun uploadLogFiles(externalFilesDir: File) {
val curFiles = externalFilesDir.listFiles()?.filter { file ->
System.currentTimeMillis() - file.lastModified() < TWO_WEEK_TIME_MILLIS
}?.sortedByDescending { it.lastModified() }
if (curFiles.isNullOrEmpty()) {
Timber.i("No log files or directory found.")
return
}
val environmentPrefix = if (BuildConfig.DEBUG) "debug" else "release"
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
curFiles.forEach { file ->
val date = dateFormat.format(Date(file.lastModified()))
val fileIndex = file.name.substringBefore("_logs.txt").takeLastWhile { it.isDigit() }
val key = "$environmentPrefix/sample/$date/log$fileIndex.txt"
try {
val result = Amplify.Storage.uploadFile(
StoragePath.fromString("public/$key"),
file
).result()
Timber.i("Log file upload successful: ${result.path}")
} catch (error: Exception) {
Timber.e("Log file upload failed: ${error.message} - ${error.cause}")
}
}
}
companion object {
private const val TWO_WEEK_TIME_MILLIS = 14 * 24 * 60 * 60 * 1000L
fun startUpUploadWork(
externalFilesDirPath: File?
) = PeriodicWorkRequestBuilder<LogUploadWorker>(
1, TimeUnit.HOURS,
5, TimeUnit.MINUTES
)
.setConstraints(LogSyncConstraints)
.setBackoffCriteria(
BackoffPolicy.LINEAR,
MIN_BACKOFF_MILLIS,
TimeUnit.MILLISECONDS
)
.setInputData(
Data.Builder()
.putString("externalFilesDirPath", externalFilesDirPath?.absolutePath)
.build()
)
.build()
}
}
Log output
// Put your logs below this line
TransferWorkerObserver$attachObserverForPendingTransfer$1.invokeSuspend
Fatal Exception: java.lang.IllegalStateException: Couldn't read row 912, col 0 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetLong(CursorWindow.java)
at android.database.CursorWindow.getLong(CursorWindow.java:511)
at android.database.CursorWindow.getInt(CursorWindow.java:578)
at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:69)
at com.amplifyframework.storage.s3.transfer.TransferWorkerObserver$attachObserverForPendingTransfer$1.invokeSuspend(TransferWorkerObserver.kt:82)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:9)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:97)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
o9.J Dispatcher:
at java.lang.Object.wait(Object.java)
at java.lang.Thread.parkFor$(Thread.java:2127)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:201)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:432)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:333)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:908)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1057)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Firebase Background Thread #1:
at java.lang.Object.wait(Object.java)
at java.lang.Thread.parkFor$(Thread.java:2127)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at com.google.firebase.concurrent.CustomThreadFactory.lambda$newThread$0(CustomThreadFactory.java:290)
at java.lang.Thread.run(Thread.java:761)
o9.J Dispatcher:
at java.lang.Object.wait(Object.java)
at java.lang.Thread.parkFor$(Thread.java:2127)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:201)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:432)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:333)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:908)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1057)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
DefaultDispatcher-worker-6:
at java.lang.Object.wait(Object.java)
at java.lang.Thread.parkFor$(Thread.java:2127)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:324)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.park(CoroutineScheduler.kt:301)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.tryPark(CoroutineScheduler.kt:301)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:301)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:301)
o9.J Dispatcher:
at java.lang.Object.wait(Object.java)
at java.lang.Thread.parkFor$(Thread.java:2127)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:201)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:432)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:333)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:908)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1057)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
o9.J Dispatcher:
at java.lang.Object.wait(Object.java)
at java.lang.Thread.parkFor$(Thread.java:2127)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:201)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:432)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:333)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:908)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1057)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
DefaultDispatcher-worker-7:
at java.lang.Object.wait(Object.java)
at java.lang.Thread.parkFor$(Thread.java:2127)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:324)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.park(CoroutineScheduler.kt:301)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.tryPark(CoroutineScheduler.kt:301)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:301)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:301)
FinalizerWatchdogDaemon:
at java.lang.Thread.sleep(Thread.java)
at java.lang.Thread.sleep(Thread.java:371)
at java.lang.Thread.sleep(Thread.java:313)
at java.lang.Daemons$FinalizerWatchdogDaemon.sleepFor(Daemons.java:314)
at java.lang.Daemons$FinalizerWatchdogDaemon.waitForFinalization(Daemons.java:336)
at java.lang.Daemons$FinalizerWatchdogDaemon.run(Daemons.java:253)
at java.lang.Thread.run(Thread.java:761)
WM.task-2:
at java.lang.Object.wait(Object.java)
at java.lang.Thread.parkFor$(Thread.java:2127)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
pool-12-thread-1:
at java.lang.Object.wait(Object.java)
at java.lang.Thread.parkFor$(Thread.java:2127)
at sun.misc.Unsafe.park(Unsafe.java:325)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2035)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:413)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1058)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1118)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
HeapTaskDaemon:
at dalvik.system.VMRuntime.runHeapTasks(VMRuntime.java)
at java.lang.Daemons$HeapTaskDaemon.run(Daemons.java:433)
at java.lang.Thread.run(Thread.java:761)
// ...
amplifyconfiguration.json
No response
GraphQL Schema
// Put your schema below this line
Additional information and screenshots
Additional information
- Device: Infos_Duple
- Android Version: Nougat 7.1.2
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't workingstorageRelated to the Storage category/pluginsRelated to the Storage category/plugins