Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

TouchDB does not work on Android 4.1 #48

Closed
mschoch opened this Issue · 12 comments

6 participants

@mschoch
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)

@mschoch
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.

@dwt

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

@mschoch
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.

@nickwilkie

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?

@mschoch
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.

@mschoch
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.

@dongshengbc

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

@tleyden tleyden was assigned
@tleyden tleyden closed this
@tleyden
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.

@yaronyg yaronyg referenced this issue from a commit in thaliproject/couchbase-lite-android
@mschoch mschoch fixed support for Android 4.1 (in some cases)
not convinced this works in all cases, but unit tests pass
and AndroidGrocerySync works, so better than nothing

couchbaselabs/TouchDB-Android#48
ade012c
@mschoch mschoch referenced this issue in couchbase/couchbase-lite-android
Closed

Error creating database on L Developer Preview #373

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.