Com.couchbase.lite.CouchbaseLiteException: read failed: EBADF (Bad file number) + Document.update - java.lang.NullPointerException

**Update : **

Well no forget my last thoughts… I modified my code so that the upload of attachment was triggered by me (via a button).

I made the same steps : fresh installation, new DB locally, new document.

Everything works fine and 20 revisions mades and replicated.

When i try to add an attachment, bam !! exception :

08-06 20:25:37.270  12406-12406/com.xxxxx.xxxxE/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.xxxxx.xxxxxx, PID: 12406
    java.lang.NullPointerException
            at com.couchbase.lite.Database.generateIDForRevision(Database.java:3223)
            at com.couchbase.lite.Database.putRevision(Database.java:3622)
            at com.couchbase.lite.Database.putRevision(Database.java:3465)
            at com.couchbase.lite.Document.putProperties(Document.java:415)
            at com.couchbase.lite.UnsavedRevision.save(UnsavedRevision.java:102)
            at com.couchbase.lite.Document.update(Document.java:275)
            at com.xxxxx.xxxxx.MainActivity.updateProfileLocationinDB(MainActivity.java:777)
            at com.xxxxxx.xxxxx.MainActivity.access$900(MainActivity.java:158)
            at com.xxxxxx.xxxxx.MainActivity$4.onReceive(MainActivity.java:449)
            at android.support.v4.content.LocalBroadcastManager.executePendingBroadcasts(LocalBroadcastManager.java:297)
            at android.support.v4.content.LocalBroadcastManager.access$000(LocalBroadcastManager.java:46)
            at android.support.v4.content.LocalBroadcastManager$1.handleMessage(LocalBroadcastManager.java:116)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5081)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:781)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
            at dalvik.system.NativeStart.main(Native Method)

So i hope that my informations might help you anyway…but i think that the issue is really in the attachment feature.

Still on that last test scenario : I restarded the app after that last crash, and no exception.

The app runs correctly, replications occur correctly too.
Attachment is present…On Couchbase server and locally too.

The document contains this :
_attachments={picture1.jpg={stub=true, length=558336, digest=sha1-vgMxQuOWFlPnEnSPkINrxpuB3wE=, revpos=31, content_type=image/jpeg}}

I checked some view on my servers and i noticed that the rev between 22 and 31 are missing.

The revision 21 was the last one before the crash. (The 22 produced the exception)
And as we can see on the attachment it has been “added” at revpos=31.

I think that these elements will help you to understand the issue, and then …to help me :wink:

Regards,

Hi @heretyk,

  1. Is com.couchbase.lite.Manager a single instance per application? Can you check this?
  2. Without BroadcastReceiver, does update document work fine?
  3. CBL Android uses ScheduledExecutorService internally because AsyncTask is only for android. Using AsyncTask might cause the problem.

Honestly, I don’t know what causes problem. If you can provide simple sample app to reproduce this issue, it is fully appreciated.

Regards,
Hideki

Declaration

protected static Manager manager;

Instancied only 1 time in app :

manager = new Manager(new AndroidContext(this), Manager.DEFAULT_OPTIONS);

Just made a test with the Broadcast receiver disabled.
Yes, app doesn’t crash, and i made 4 revisions on doc successfully. (checked on server and i saw correct datas)
But picture isn’t uploaded : I have got an exception too, but not fatal. Not the same one.

08-07 19:44:09.164 8021-8963/com.xxxxxxx.xxxxxxx W/com.couchbase.lite﹕ Sync: com.couchbase.lite.replicator.PullerInternal@42abcce0: starting ChangeTracker with since=null mode=OneShot
08-07 19:44:09.164 8021-8965/com.xxxxxxx.xxxxxxx W/com.couchbase.lite﹕ Sync: Error converting lastSequence: null to long. Using 0
08-07 19:44:09.164 8021-8963/com.xxxxxxx.xxxxxxx W/com.couchbase.lite﹕ Sync: com.couchbase.lite.replicator.PullerInternal@42abcce0: started ChangeTracker com.couchbase.lite.replicator.ChangeTracker@42c1d590
08-07 19:44:09.284 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ com.couchbase.lite.CouchbaseLiteException: Conflicts not allowed and there is already an existing doc with id: TestNoBroadcast2015_7_7_1438969423910
08-07 19:44:09.284 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at com.couchbase.lite.Database.putRevision(Database.java:3530)
08-07 19:44:09.284 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at com.couchbase.lite.Database.putRevision(Database.java:3465)
08-07 19:44:09.284 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at com.couchbase.lite.Document.putProperties(Document.java:415)
08-07 19:44:09.284 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at com.couchbase.lite.UnsavedRevision.save(UnsavedRevision.java:102)
08-07 19:44:09.284 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at com.xxxxxxx.xxxxxxx.MainActivity$UploadPictureTask.doInBackground(MainActivity.java:3455)
08-07 19:44:09.294 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at com.xxxxxxx.xxxxxxx.MainActivity$UploadPictureTask.doInBackground(MainActivity.java:3419)
08-07 19:44:09.294 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
08-07 19:44:09.294 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
08-07 19:44:09.294 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
08-07 19:44:09.294 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
08-07 19:44:09.294 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
08-07 19:44:09.294 8021-8767/com.xxxxxxx.xxxxxxx W/System.err﹕ at java.lang.Thread.run(Thread.java:841)
08-07 19:44:09.294 8021-8021/com.xxxxxxx.xxxxxxx I/xxxxxxx - Main﹕ upload Picture DONE Content of document : null
08-07 19:44:09.334 8021-8944/com.xxxxxxx.xxxxxxx W/com.couchbase.lite﹕ Sync: com.couchbase.lite.replicator.PullerInternal@42abcce0: Received invalid doc ID from _changes: {seq=4251, id=_user/TestNoBroadcast2015_7_7_1438969423910, changes=}
08-07 19:44:09.334 8021-8976/com.xxxxxxx.xxxxxxx E/com.couchbase.lite﹕ Sync: PullerInternal stopGraceful.run() finished

For recall…line 3455 is " newRev.save();" of my “private class UploadPictureTask extends AsyncTask<File, String, Double>”

Well i hope not.UsingAsyncTask in Android, especially to upload attachment, is very common…and i would say a “best-practise”. It is in many case the bast way to upload data silently, with minimum ressources, without impacting UI or user experience.

So i hope that you can solve this issue.

For confidential purpose of my company (launch is in a few month), i cannot provide you any sample app.
But you can use the code i gave you on Android 4.4.2 with the same version of CBL, GW and SERVERS ?

My company plans to do business with you and purchase the Enterprise Subscriptions and Support, once the release of the app is scheduled.
So i hope you will be able to provide me a fix to upload attachment on Documents.

Please, let me know the advancements.

Best regards,

Hi @heretyk,

Thank you for additional information.

Please let me confirm.

  1. By disabling BroadcastReceiver, updateProfileLocation() method works fine.
  2. However, UploadPictureTask still fails.

From latest stacktrace you provided, document conflict is happening when UploadPictureTask was executed. If conflict happens, it requires to update document (set attachment) again.

Also from stack trace, non-continuous pull-replication was running same time UploadPictureTask was executed. I assume it causes conflict.

Following documentation might help you to understand how conflict happens
http://developer.couchbase.com/mobile/develop/guides/couchbase-lite/native-api/document/index.html#updating

Thanks,
Hideki

No.
updateProfileLocation() is triggered by BroadcastReceiver.

I don’t understand.

Replication is continuous. I call it like this :

pullReplication = database.createPullReplication(syncUrl);
if (continuousPull == true)
pullReplication.setContinuous(true);

pushReplication = database.createPushReplication(syncUrl);
pushReplication.setContinuous(true);

I succesfully managed to upgrade to 1.1.0.
There is improvment : My app doesn’t crash now when i call UploadPictureTask(), but still have an exception.

08-08 08:30:07.420 9322-9547/com.xxxxx.xxxxx W/System.err﹕ com.couchbase.lite.CouchbaseLiteException: Conflicts not allowed and there is already an existing doc with id: Yves2Pageau2015_7_8_1439015379828
08-08 08:30:07.420 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at com.couchbase.lite.Database.putRevision(Database.java:3988)
08-08 08:30:07.430 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at com.couchbase.lite.Database.putRevision(Database.java:3923)
08-08 08:30:07.430 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at com.couchbase.lite.Document.putProperties(Document.java:420)
08-08 08:30:07.430 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at com.couchbase.lite.UnsavedRevision.save(UnsavedRevision.java:107)
08-08 08:30:07.430 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at com.xxxxx.xxxxx.MainActivity$UploadPictureTask.doInBackground(MainActivity.java:3464)
08-08 08:30:07.430 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at com.xxxxx.xxxxx.MainActivity$UploadPictureTask.doInBackground(MainActivity.java:3428)
08-08 08:30:07.430 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
08-08 08:30:07.470 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
08-08 08:30:07.470 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
08-08 08:30:07.470 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
08-08 08:30:07.470 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
08-08 08:30:07.470 9322-9547/com.xxxxx.xxxxx W/System.err﹕ at java.lang.Thread.run(Thread.java:841)
08-08 08:30:07.510 9322-9322/com.xxxxx.xxxxx I/xxxxx - Main﹕ upload Picture DONE Content of document : null
08-08 08:30:07.600 9322-10183/com.xxxxx.xxxxx W/Sync﹕ Error converting lastSequence: null to long. Using 0
08-08 08:30:08.011 9322-10188/com.xxxxx.xxxxx W/Sync﹕ com.couchbase.lite.replicator.PullerInternal@427ce1b0: Received invalid doc ID from _changes: {seq=4771, id=_user/Yves2Pageau2015_7_8_1439015379828, changes=}


As a recall , line 3464 is newRev.save();

But when i call UploadPictureTask later in activity…it works.
I think the replicator need some time after being instanced to manage attachment…

Hi @heretyk,

About the document conflict, following document could helps you. Understanding Conflicts

If Exception is thrown with conflict, CBL failed to update the document because of conflict. So, when Exception is thrown, need to update document again with creating new Revision.

Thanks,
Hideki

1 Like

Exception says “…Conflicts not allowed…”

Does your link apply to this situation anyway ?

Thanks

Hi @hideki,

I’ve finally managed to solve my issue.
In my particular scenario, allowing confict on the revisions had no impact on data integrity.

So i just set the boolean to “true” on my newRev.save();
It became newRev.save(true);

The issue was caused because my app added attachment to doc only just a few seconds (on the mobile side) after document is created and push/pull replication is set up.

I noticed it because all upload with the same code were correctly processed when it was called later in the app.

So i also used a Handler to delay code execution :

public class UploadPictureHandler extends Handler {
@Override
public void handleMessage(Message msg) {
    new UploadPictureTask().execute();
}

public void sleep(long delayMillis) {
    this.removeMessages(0);
    sendMessageDelayed(obtainMessage(0), delayMillis);
}

I call it this way.

    UploadPictureHandler mUploadPictureHandler = new UploadPictureHandler();
    mUploadPictureHandler.sleep(20000);

Hope it can be useful for someone else.

Best regards :wink:

Hi @heretyk,
Thanks you very much for sharing your solution. I am glad to hear that you could find the solution.
As general advise, I recommend to write the logic to solve the conflict or recover from the conflict because it potentially happens.
Regards!
Hideki

This sounds like racing condition between document creation and document updating operation. @heretyk, you might checkout Database.runAsync to put these two threading operations in the same queue as the Database (I guessed you may be able to remove the 20 seconds sleep).

Hello @hideki,

Bad news, there is another issue with attachment feature.
com.couchbase.lite.CouchbaseLiteException: read failed: EBADF (Bad file number)

Despite of the exception, the attachment is corretcly synced to couchbase server, but then there is no more revisions made to that document…like if the replication doesn’t work anymore.
I have to restart application so that i can make revisions again.

Do you know what causes this issue ?

08-18 00:45:09.915  13301-15490/com.xxxxxx.xxxxxxxx I/xxxxxxxxx - Main? Uploadingpicture1.jpg
08-18 00:45:10.085  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? com.couchbase.lite.CouchbaseLiteException: read failed: EBADF (Bad file number)
08-18 00:45:10.195  13301-13301/com.xxxxxx.xxxxxxxx I/xxxxxxxxx - Main? setIsOnlineInDB() - Success
08-18 00:45:10.215  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? at com.couchbase.lite.Attachment.installAttachmentBodies(Attachment.java:240)
08-18 00:45:10.265  13301-13301/com.xxxxxx.xxxxxxxx I/Choreographer? Skipped 58 frames!  The application may be doing too much work on its main thread.
08-18 00:45:10.336  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? at com.couchbase.lite.Document.putProperties(Document.java:407)
08-18 00:45:10.696  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? at com.couchbase.lite.UnsavedRevision.save(UnsavedRevision.java:119)
08-18 00:45:11.066  13301-13301/com.xxxxxx.xxxxxxxx E/Spinner? setPopupBackgroundDrawable: incompatible spinner mode; ignoring...
08-18 00:45:13.298  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? at com.xxxxxx.xxxxxxxx.MainActivity$UploadPictureTask.doInBackground(MainActivity.java:3631)
08-18 00:45:13.379  13301-13301/com.xxxxxx.xxxxxxxx D/CustomDrawerAdapter? picture1.exists()
08-18 00:45:13.769  13301-13301/com.xxxxxx.xxxxxxxx D/CustomDrawerAdapter? picture2.exists()
08-18 00:45:14.319  13301-13301/com.xxxxxx.xxxxxxxx E/Spinner? setPopupBackgroundDrawable: incompatible spinner mode; ignoring...
08-18 00:45:14.730  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? at com.xxxxxx.xxxxxxxx.MainActivity$UploadPictureTask.doInBackground(MainActivity.java:3587)
08-18 00:45:14.760  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? at android.os.AsyncTask$2.call(AsyncTask.java:288)
08-18 00:45:14.770  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? at java.util.concurrent.FutureTask.run(FutureTask.java:237)
08-18 00:45:15.691  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
08-18 00:45:15.711  13301-13301/com.xxxxxx.xxxxxxxx E/Spinner? setPopupBackgroundDrawable: incompatible spinner mode; ignoring...
08-18 00:45:15.831  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
08-18 00:45:15.961  13301-13301/com.xxxxxx.xxxxxxxx I/Choreographer? Skipped 335 frames!  The application may be doing too much work on its main thread.
08-18 00:45:16.001  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
08-18 00:45:16.031  13301-15490/com.xxxxxx.xxxxxxxx W/System.err? at java.lang.Thread.run(Thread.java:841)
08-18 00:45:16.992  13301-13301/com.xxxxxx.xxxxxxxx I/xxxxxxxxx - Main? Upload Pictures DONE 

Code :

Document doc = database.getDocument(userId);
    UnsavedRevision newRev = doc.getCurrentRevision().createRevision();
    if (mImageViewNumber==1)
    {
        InputStream stream = new FileInputStream(picture1);
        newRev.setAttachment(fileNamePicture1 + ".jpg", "image/jpeg", stream);
        Log.i(TAG, "Uploading " + fileNamePicture1 + ".jpg");
    }
    if (mImageViewNumber==2)
    {
        InputStream stream2 = new FileInputStream(picture2);
        newRev.setAttachment(fileNamePicture2 + ".jpg", "image/jpeg", stream2);
        Log.i(TAG, "Uploading " + fileNamePicture2 + ".jpg");
    }
    if (mImageViewNumber==3)
    {
        InputStream stream3 = new FileInputStream(picture3);
        newRev.setAttachment(fileNamePicture3 + ".jpg", "image/jpeg", stream3);
        Log.i(TAG, "Uploading " + fileNamePicture3 + ".jpg");
    }
    newRev.save(true);
}  catch (FileNotFoundException | CouchbaseLiteException e) {
    e.printStackTrace();
}

Hello @hideki,

New kind of error on a new document :

08-20 23:25:40.054  13204-14375/net.xxxxxxxxxW/Sync﹕ com.couchbase.lite.replicator.PullerInternal@425708e0 no 

new remote revisions to fetch.  add lastInboxSequence (14325) to pendingSequences (com.couchbase.lite.support.SequenceMap@42acc750)
08-20 23:25:42.327  13204-14783/net.xxxxxxxE/RemoteRequest﹕ Got error status: 409 for http://gwfr01.xxxxxxxxx.net:4984/tm-db01/_local/d0621109f71028276ad1f58ada55c67826930d05.  Reason: Conflict
08-20 23:25:42.337  13204-14783/net.xxxxxxxW/Sync﹕ com.couchbase.lite.replicator.ReplicationInternal$7@4259a040: Unable to save remote checkpoint

Hello @hideki :

Can you tell me if you are working on this ? What is the solution please ?

Basically, i just want to attach a jpg on a document, it shouldn’t be so a tricky task.
Especially since you confirmed the code is right.

As a summary of the situation, i successfully attach an attachment,but the error mentionned before happens : "

com.couchbase.lite.CouchbaseLiteException: read failed: EBADF (Bad file number)"

Anyhow, on server side, the attachment is successfully attached but no more revisions arrives then ! (So the attachment is the last revisions).
Then this spamming on logcat at every attempt to make a rev :

"W/CBLite﹕ No pending attachment for digest: sha1-JaGhoM9t1gn7tVuZOXhyzjDV5N4="

In order to restart making revisions, i have to restart the app. And i can query the attachment, or any news revisions.
Neither document or attachment are corrupted…

So please, what is going on ?

Regards

Hi @heretyk,

From current information, I can not identify where problem is, in Couchbase Lite codes or in other codes. Can you re-consider to create sample app to reproduce this issue? This helps us a lot.

Thanks,
Hideki

@hideki,

No i can’t reconsider it. I have supplied you a lot of information.

My company and myself are preparing the release of the app before the end of the year. And it is a confidential project.

What i can tell you is that we choosed couchbase Mobile as it seemed reliable and one of the best in terms of performance.
But we are rather disappointed of the situation and to not obtain efficient support on this SIMPLE need.

After the launch, we were aimaing to subscribe to Enterprise editions, and eventually, to ask Couchbase some contracts and training on architecture/data management and deployment as the app could lead us to IMPORTANT needs.

But if we can’t have support on such a simple feature as adding an attachment, maybe my company will have to re-consider the database solution for our project.

We just want to upload an attachment to a document via an ASYNCTASK.
As i told you, the upload attachment code i gave you works.
The revision arrives to servers and the attachment is correctly saved.
But no more revision can be done until app is restarted = so i guess that closing the CBlite local databate and manager “solve” the issue.

Can you re-consider giving us a solution to do that ?

@hideki :

Any update or solution on that ?

Our app launch is for December, and we might purchase an enterprise subscription.
But we want this issue to be fixed first.

Can you just provide a solution to upload attachment without needing to restart the app to make more revisions on the same doc ?

Hi @heretyk,

With currently given information, I am not sure what causes problem. I reopened [the ticket] (https://github.com/couchbase/couchbase-lite-java-core/issues/693). Can we continue to discuss this issue in the github issue.

Thanks,
Hideki

Ok @hideki

I contact you there.