Skip to content
This repository

TouchDB does not work on Android 4.1 #48

Closed
mschoch opened this Issue July 07, 2012 · 12 comments

6 participants

Marty Schoch Traun Leyden Martin Häcker dehubbed Nicholas Wilkie dongsheng
Marty Schoch
Owner

java.lang.NoSuchFieldError: no field with name='mNativeHandle' signature='I' in class Landroid/database/sqlite/SQLiteDatabase;
at com.couchbase.touchdb.TDCollateJSON.nativeRegisterCustomCollators(Native Method)
at com.couchbase.touchdb.TDCollateJSON.registerCustomCollators(TDCollateJSON.java:10)
at com.couchbase.touchdb.TDDatabase.open(TDDatabase.java:222)
at com.couchbase.touchdb.TDDatabase.createEmptyDBAtPath(TDDatabase.java:161)
at com.couchbase.touchdb.testapp.tests.CRUDOperations.testCRUDOperations(CRUDOperations.java:46)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:190)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:175)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1584)

Marty Schoch
Owner

TouchDB relies on some low-level implementation details to manually install our own collators using native code. On the surface it looks like those low-level details changed and broke our implementation. Unfortunately, source code for Android 4.1 is not available yet, making it hard to diagnose further.

Martin Häcker
dwt commented July 19, 2012

Damn, running into this too.

I'ts kind of important for us to be able to deploy on 4.1 - can you maybe give an estimation when you'll be able to work on this one?

dehubbed

maybe time to move the whole thing to H2 anyways, see here and here

Marty Schoch
Owner

I've put in a fix that works in some cases (not convinced it works in all cases because of the way Android changed things)

ade012c

The unit tests pass and AndroidGrocerySync works as expected in the 4.1 emulator now, so its clearly an improvement worth sharing.

Nicholas Wilkie

Could you elaborate on where you think we might run into trouble with this fix? Does it seem that the new hook may be device-dependent?

Marty Schoch
Owner

The issue is that SQLiteDatabase no longer has a 1-1 mapping to the underlying sqlite handle (at the c library layer). Ideally, whenever a new sqlite handle is opened, we need to register our custom collation functions there. Now, SQLiteDatabase has a ThreadLocal reference to a SQLiteSession, which has reference to a SQLiteConnectionPool which has a pool of SQLiteConnections's. Each of these has their own sqlite handle (at the c library layer).

All of this means its a lot harder (maybe impossible) to reliably ensure our custom collation functions are always registered. I coded up what we needed to make sure it gets registered on the "primary" connection, which is the one that it uses when you first call openDatabase().

I actually didn't expect AndroidGrocerySync to work with this patch because I was pretty sure we have multiple threads accessing the SQLiteDatabase (in a coordinated manner). But, for some reason it does work. I have not had the time to go back and get a better understanding of why this is.

dehubbed

I think you're taking the wrong approach here. Both native code and custom collators were KISS violations anyway and now this mess. So instead of registering a custom collator, compute an artificial collation key from the JSON that is e.g. a string and that has the quality that a comparison on that string with the built-in collator matches comparison on the corresponding JSON. Then store that key in the key column of your table. If you look at java.text.spi.CollatorProvider that comes with Open/Sun JDK (not Android) then you see it does the same thing (computing an artificial key) for performance reasons, only it is a binary blob.

Marty Schoch
Owner

Thanks for the input, can you point me to any sample code doing this?

dehubbed

Sorry no. I had the artificial collation key mostly figured out in my mind when I did the research into porting TouchDB to H2/JDBC but I'd yet have to type it in.

dongsheng

Maybe it is better to include SQLite code in TouchDB? That way TouchDB is independent from the underneath changes?

Chris Anderson jchris referenced this issue in couchbase/couchbase-lite-android July 23, 2013
Open

future proof SQLite collator #40

Chris Anderson jchris referenced this issue in couchbase/couchbase-lite-android July 23, 2013
Closed

flesh out test matrix for Android versions #41

Traun Leyden tleyden closed this July 23, 2013
Traun Leyden
Owner

I've been testing extensively on Android 4.2 with no observed issues. Just now tried 4.1 and didn't see any problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.