Bug 22074 - System.TypeLoadException: Could not load type 'Net.Sqlcipher.ICursorInvoker' from assembly 'SQLCipherBindingLibrary
Summary: System.TypeLoadException: Could not load type 'Net.Sqlcipher.ICursorInvoker' ...
Status: VERIFIED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: General ()
Version: 4.14.0
Hardware: PC Mac OS
: High major
Target Milestone: 5.1
Assignee: Jonathan Pryor
URL:
Depends on:
Blocks:
 
Reported: 2014-08-13 15:24 UTC by Jon Goldberger [MSFT]
Modified: 2016-05-12 04:05 UTC (History)
7 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
VERIFIED FIXED

Description Jon Goldberger [MSFT] 2014-08-13 15:24:42 UTC
Using a .dll from a Android Binding project for SQLCipher, when trying to Access data from the dSQLite database with:

Net.Sqlcipher.ICursor cursor = sqliteDB.RawQuery("SELECT Zip_Code FROM Test_Table", null);

a System.TypeLoadException is thrown when using XA 4.14 and targeting any Android version. Stack trace below. 

This does _not_ occur using XA 4.12 with Android target version >= 3.1 but <= 4.3

Tested on an emulator running Android version 4.4. 

To reproduce:

1. Run the attached test project using XA 4.14

Expected result: a list of Zipcodes will be output to the console.
Actual result: Exception noted above is thrown.

2. Run test project using XA 4.12

Expected result: a list of Zipcodes will be output to the console.
Actual result: As expected. 

Stack Trace:
>System.TypeLoadException: Could not load type 'Net.Sqlcipher.ICursorInvoker' from assembly 'SQLCipherBindingLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
>  at at System.Reflection.MonoCMethod.InternalInvoke (object,object[]) <IL 0x00024, 0x00107>
>  at at System.Reflection.MonoCMethod.DoInvoke (object,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo) <IL 0x00099, 0x00267>
>  at at System.Reflection.MonoCMethod.Invoke (System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo) <IL 0x00007, 0x0004b>
>  at at System.Reflection.ConstructorInfo.Invoke (object[]) <IL 0x00015, 0x00099>
>  at Java.Interop.TypeManager.CreateProxy (System.Type,intptr,Android.Runtime.JniHandleOwnership) [0x00059] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.14-series/8e79d361/source/monodroid/src/Mono.Android/src/Java.Interop/TypeManager.cs:271
>  at Java.Interop.TypeManager.CreateInstance (intptr,Android.Runtime.JniHandleOwnership,System.Type) [0x001ea] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.14-series/8e79d361/source/monodroid/src/Mono.Android/src/Java.Interop/TypeManager.cs:249
>  at Java.Lang.Object.GetObject (intptr,Android.Runtime.JniHandleOwnership,System.Type) [0x000ba] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.14-series/8e79d361/source/monodroid/src/Mono.Android/src/Java.Lang/Object.cs:333
>  at at Java.Lang.Object._GetObject<Net.Sqlcipher.ICursor> (intptr,Android.Runtime.JniHandleOwnership) <0x00093>
>  at at Java.Lang.Object.GetObject<Net.Sqlcipher.ICursor> (intptr,Android.Runtime.JniHandleOwnership) <0x0004f>
>  at at Net.Sqlcipher.Database.SQLiteDatabase.RawQuery (string,string[]) <IL 0x0008c, 0x00277>
>  at HelloWorld.MainActivity.OnCreate (Android.OS.Bundle) [0x00087] in /Users/apple/Downloads/HelloWorld2/HelloWorld/MainActivity.cs:67
>  at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (intptr,intptr,intptr) [0x00011] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.14-series/8e79d361/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.App.Activity.cs:2179
>  at at (wrapper dynamic-method) object.56a98bce-26c0-48fb-9a90-83a80c2da922 (intptr,intptr,intptr) <IL 0x00017, 0x0001f>

Version info:
=== Xamarin Studio ===

Version 5.2.1 (build 1)
Installation UUID: 2dc9022f-f9a8-424f-8284-bf224cbbfde0
Runtime:
	Mono 3.6.0 ((no/f540f8a)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 306000039

=== Apple Developer Tools ===

Xcode 5.1.1 (5085)
Build 5B1008

=== Xamarin.Mac ===

Version: 1.8.1.6

=== Xamarin.Android ===

Version: 4.14.0 (Business Edition)
Android SDK: /Users/apple/Library/Developer/Xamarin/android-sdk-mac_x86
	Supported Android versions:
		2.2   (API level 8)
		2.3   (API level 10)
		3.1   (API level 12)
		3.2   (API level 13)
		4.0   (API level 14)
		4.0.3 (API level 15)
		4.1   (API level 16)
		4.2   (API level 17)
		4.3   (API level 18)
		4.4   (API level 19)
Java SDK: /usr
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)

=== Xamarin.iOS ===

Version: 7.2.6.28 (Business Edition)
Hash: 606f31a
Branch: 
Build date: 2014-08-01 15:27:48-0400

=== Build Information ===

Release ID: 502010001
Git revision: d06832ce9807d6be24aca225457e8b37c7669f6f
Build date: 2014-08-07 12:10:47-04
Xamarin addins: 1de032531be4cecf2f39dbee3b87aac78204058c

=== Operating System ===

Mac OS X 10.9.4
Darwin Jonathans-MacBook-Pro.local 13.3.0 Darwin Kernel Version 13.3.0
    Tue Jun  3 21:27:35 PDT 2014
    root:xnu-2422.110.17~1/RELEASE_X86_64 x86_64
Comment 3 Jonathan Pryor 2014-08-14 00:27:07 UTC
The problem is this (as seen in `adb logcat` output):

> W/Mono    ( 5372): no implementation for interface method Android.Database.ICursor::get_NotificationUri() in class Net.Sqlcipher.ICursorInvoker
> W/Mono    ( 5372): METHOD .ctor(intptr,Android.Runtime.JniHandleOwnership)
> W/Mono    ( 5372): METHOD get_ThresholdClass()
> ...list of LOTS of other methods...

WORKAROUND: Use Windows. :-/

One of the 4.14 features is:

> On OS X the installer size is 36% smaller (147MB vs. 229MB).

This was done by no longer distributing the ~11 different Mono.Android.Platform.apk files, each 20-33MB in size (thus saving LOTS of post-install space).

This in turn was done by creating a new Xamarin.Android.Platform.apk package "on demand" based on the contents of the $(TargetFrameworkRootPath) directory using the _latest_ API levels available.

Rephrased, we'd create a Xamarin.Android.Platform.apk file, which would contain the Mono.Android.dll corresponding to API-19 (for Xamarin.Android 4.14).

The problem is that this isn't, in fact, safe; Java interfaces are versionable, in that Google/Sun/etc. can add methods to interfaces. (They're not "baked in stone" like .NET requires.)

Which brings us to Cursor.getNotificationUri(): http://developer.android.com/reference/android/database/Cursor.html#getNotificationUri()

Cursor.getNotificationUri() was *added* in API-19. The SQLCipherBindingLibrary.dll binding assembly, meanwhile, was NOT built against API-19, and thus it's "missing" the API-19+ Cursor.getNotificationUri() method.

The result is the TypeLoadException trying to load Net.Sqlcipher.ICursorInvoker: the type cannot be constructed, because it doesn't implement the (new to API-19) Android.Database.ICursor.NotificationUri property.

(Windows doesn't suffer from this behavior because it continues with the previous behavior of having prebuilt Mono.Android.Platform.apk file for each API level, as there wasn't time to update the installer.)
Comment 4 David Schulte 2014-08-14 08:38:52 UTC
Rebuilding SQLCipherBindingLibrary.dll using the latest version of Xamarin and then using the result to build our application does *not* help. We see the same error. It sounds like the real problem is Xamarin.Android presuming that it can use the latest API in building the given application. Doesn't this in effect ignore Xamarin's "target framework" setting? If we have set the target framework to 4.0.3, but Xamarin is using the latest available API (e.g., API 19/KitKat/4.4), we won't be able to run the application on anything less than devices running Android 4.4.x.
Comment 5 Jonathan Pryor 2014-08-14 08:51:38 UTC
> Rebuilding SQLCipherBindingLibrary.dll using the latest version of Xamarin and
> then using the result to build our application does *not* help.

It's not a matter of using the latest Xamarin.Android version.

It's a matter of changing the $(TargetFrameworkVersion) of your SQLCipherBindingLibrary project to be Android v4.4 (API-19), instead of whatever it is now (presumably v4.0.3, API-15).

> It sounds like the real problem is Xamarin.Android presuming that it can
> use the latest API in building the given application

Close; the problem is that Xamarin.Android 4.14 assumes it can use the latest API when _running_ the given application. Building still uses the specified version (so that you don't inadvertently reference members that don't exist).

> Doesn't this in effect ignore Xamarin's "target framework" setting?

Kinda; this is a ramification I hadn't thought of. :-(

> If we have set the target framework to 4.0.3, but Xamarin is using the 
> latest available API (e.g., API 19/KitKat/4.4), we won't be able to run the 
> application on anything less than devices running Android 4.4.x.

Wrong. As of Mono for Android 4.2, you can _use_ a Mono.Android.dll which binds an API level later than what the target device runs, SO LONG AS you don't use any types/members that don't exist on the target device.

Meaning you can use the v4.4 Mono.Android.dll and run your app on an Android v1.6 (API-4) device, so long as you don't use any types/members not present in API-4 at runtime. (You may perform version checks at runtime to assist in this.)

...except for interfaces, which is what you're running into. :-/
Comment 6 Jonathan Pryor 2014-08-14 08:52:53 UTC
Alternate workaround: do a Release build/disable use of the shared runtime. This will avoid use of Xamarin.Android.Platform.apk (which contains the latest Mono.Android.dll), and will allow your app to run.

It is possible to enable fast deployment while disabling use of the shared runtime, though Xamarin Studio doesn't allow this; you'd have to edit the .csproj directly to enable this.
Comment 7 David Schulte 2014-08-14 09:09:18 UTC
Jon,
Based on your latest posts, it sounds like Xamarin is presuming that it can run using the latest API, which it obviously can't. Will the Xamarin team address this including the appropriate runtime checks?

I wasn't sure about your last comment about doing a release build and disabling the use of the shared runtime. First, we need to do debug builds - I wasn't sure by your comment if disabling the use of the shared runtime was exclusive to doing release builds. You also didn't give any reference to how to disable the use of the shared runtime. Are you referring to the following section of the .csproj file, which we already have this set to false?

  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>none</DebugType>
    <Optimize>True</Optimize>
    <OutputPath>bin\Release</OutputPath>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <ConsolePause>False</ConsolePause>
    <AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
  </PropertyGroup>

Based on the above and the fact that the "AndroidUseSharedRuntime" only appears under the "Release" configuration, it looks like this would not be available for debug builds.

So far, it sounds like our best work-a-round at this point is to avoid using the latest version of Xamarin until the development team has a chance to address the runtime issue. Do you agree?
Thanks again,
Dave
Comment 8 David Schulte 2014-08-14 09:12:56 UTC
Also, we would rather not change the target framework from 4.0.3 to 4.4 for either the .NET assembly project or our main project for the point that you made about using interfaces that won't exist at runtime on the devices we are targeting. This is just dangerous and prone to errors that might not be recognized until the app got out into the field.
Dave
Comment 9 Jonathan Pryor 2014-08-14 10:49:40 UTC
> Will the Xamarin team address this.

Yes. This will be fixed for the next 4.16 beta release.

> I wasn't sure by your comment if disabling the use of the shared runtime
> was exclusive to doing release builds

It is not exclusive; in Xamarin Studio Project Options, see Build / Android Build > Packaging tab > [X] Use shared Mono runtime. This can be disabled for Debug builds, either through the IDE or by  copying this fragment:

    <AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>

into the the Debug configuration section:

  <PropertyGroup
      Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

See also: http://developer.xamarin.com/guides/android/under_the_hood/build_process/#Shared_Runtime

I see that you've disabled Fast assembly deployment in the Debug configuration:

    <EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk>

It is possible to both enable fast assembly deployment and disable the shared runtime. Xamarin Studio doesn't allow selecting this configuration, but you can select it by editing the .csproj. (This is what I was originally referring to in Comment #6, as I hadn't realized that you had disabled fast assembly deployment.)

    <EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk>
    <AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>

You are still be able to debug the resulting app.

The impact of this is that "from clean" installs onto a target device will take longer (as they'll always need to copy over a separate Mono.Android.dll & BCL assemblies), but once deployed "IL-only" changes will only need to deploy the changed assemblies, instead of needing to rebuild and reinstall the entire .apk.
Comment 10 Jonathan Pryor 2014-08-15 11:23:29 UTC
Fixed in androidtools/0b7bcd77, monodroid/4a598c1f, monodroid-4.16-series/dc424d15, monodroid-4.17-series/7c776180.

Still requires a Xamarin Studio androidtools bump to be fully fixed; the above changes only fix `xbuild /t:Install`-based installs, not Xamarin Studio-based installs.
Comment 11 Jonathan Pryor 2014-08-15 14:45:21 UTC
Fixed in monodevelop/92d72c2 and monodevelop-5.3-branch/3166b1c
Comment 12 David Schulte 2014-08-15 15:33:47 UTC
Thanks Jonathan for resolving this so quickly. When will this be available in beta form? I'll install and try it out.
Dave
Comment 13 Jonathan Pryor 2014-08-15 16:40:39 UTC
@David: I don't know what the exact timeframe for the next beta is, and I have a history of being wrong anyway.

Let's just go with "soon" [0].

[0] for arbitrary values of "soon."
Comment 14 Mohit Kheterpal 2014-08-19 10:58:22 UTC
I have checked this issue and this issue does not exist i.e. attached project run successfully without any error and its generate list of zipcodes in application output.

Hence closing this issue.

Environment info :
=== Xamarin Studio ===

Version 5.3 (build 428)
Installation UUID: 449f40dd-b3f1-4028-9a6b-cca0d1a2307d
Runtime:
	Mono 3.8.0 ((no/62a857e)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 308000007

=== Apple Developer Tools ===

Xcode 5.1.1 (5085)
Build 5B1008

=== Xamarin.iOS ===

Version: 7.4.0.102 (Business Edition)
Hash: 141adb9
Branch: 
Build date: 2014-08-15 12:54:28-0400

=== Xamarin.Android ===

Version: 4.16.0 (Business Edition)
Android SDK: /Users/360logicaxamarinmacmini/Desktop/android-sdk-macosx
	Supported Android versions:
		1.6    (API level 4)
		2.1    (API level 7)
		2.3    (API level 10)
		3.1    (API level 12)
		3.2    (API level 13)
		4.0    (API level 14)
		4.0.3  (API level 15)
		4.1    (API level 16)
		4.2    (API level 17)
		4.3    (API level 18)
		4.4    (API level 19)
		4.4.87 (API level 20)
		4.5    (API level 21)
Java SDK: /usr
java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

=== Xamarin.Mac ===

Version: 1.10.0.9 (Business Edition)

=== Build Information ===

Release ID: 503000428
Git revision: 3166b1cd326fbea84dcf024e73cb31ccc83a9811
Build date: 2014-08-15 14:50:33-04
Xamarin addins: 3d041b1639f938107c5e1c71c54d9a346b30c660

=== Operating System ===

Mac OS X 10.8.4
Darwin 360Logicas-Mac-mini.local 12.4.0 Darwin Kernel Version 12.4.0
    Sun Mar 10 18:01:10 PDT 2013
    root:xnu-2050.24.6~1/RELEASE_X86_64 x86_64
Comment 15 Jonathan Pryor 2014-08-20 17:32:49 UTC
@David: The fix for this issue should now be in the beta channel.
Comment 16 PJ 2014-08-20 20:15:05 UTC
Just to head off any potential confusion, the fix for this is released in the new Android 4.16.0 in the Beta channel, but the fix in Xamarin Studio did not make it out.

Once we can resolve our code-signing issues with newer XS 5.3 builds, we'll be able to release the fix there as well.
Comment 17 David Schulte 2014-08-21 08:16:29 UTC
It sounds like there are 2 parts to this fix? Should I try upgrading to the latest beta or do should I wait a bit?
Comment 18 Jonathan Pryor 2014-08-21 11:09:17 UTC
@David: If you use `xbuild /t:Install Project.csproj`, it'll work properly. If you install from the Xamarin Studio IDE, it won't.

My apologies: I thought I checked that the fix had been likewise merged into Xamarin Studio, but apparently I was checking the wrong branch... :-/
Comment 21 Mohit Kheterpal 2015-04-21 15:15:46 UTC
I have tried to verify this issue but the link given in comment 1 for test sample gives 404 error. 
So could you please provide me the sample so that I can verify this issue ?

Thanks
Comment 23 Mohit Kheterpal 2015-04-22 13:37:08 UTC
Thanks Jon,

I have checked this issue with attached sample in comment 22 and observed that this issue is working fine with XA 5.1.0.115 without any error.

Hence closing this issue.
Comment 24 Abhishek 2016-04-08 16:43:36 UTC
I have checked this issue with the latest C7 build:

MonoFramework-MDK-4.4.0.106.macos10.xamarin.universal_197645cab370026033e41ce5bd5dd396a468ca9d
xamarin.android-6.1.0-37_b4be22e9776552090de37e08e0387a51e0c42104
XamarinStudio-6.0.0.4963_014b53382f43d1f07a3d773dc4a7f1332ee3816a.

Now this issue is working fine.Here is the screencast for the same: 
http://www.screencast.com/t/anjyTYWi1L.

Thanks!