LiteCore DllNotFoundException

I’ve started upgrading our solution to Couchbase 2.1 from 1.4
(BTW - the changes are quite nice - thread safety, better live query semantics, indexes, selections etc).

I’ve modified the shared CoreLibrary code, and am trying to get the CoreLibrary unit tests working. I’m getting a DllNotFound for LiteCore. I’m sure I’m missing something obvious here.

Fortunately I’ve reproduced the problem in a new minimal project, so I’ll focus troubleshooting on that minimal project.

Environment:

  • MacOS (the projects build for iOS and Mac, but just focusing on Mac at the moment).
  • All software, all packages, all OS’s up to date.
  • Using Visual Studio 7.7.2.build 21
  • Couchbase Lite 2.1.2

I created a minimal UnitTest project with a single file, and a single test:

using NUnit.Framework;
using System;
using Couchbase.Lite;
namespace CBTester
{
    [TestFixture()]
    public class Test
    {
        Database db;

        [OneTimeSetUp()]
        public void OneTimeSetUp()
        {
            Couchbase.Lite.Support.NetDesktop.Activate();
        }

        [SetUp()]
        public void SetUp()
        {
            db = new Database("test");
        }
        [Test()]
        public void TestCase()
        {
            var doc = new MutableDocument();
            doc.SetString("var", "variable value");
            doc.SetInt("num", 4);
            db.Save(doc);
        }
    }
}

I added the following packages (plus dependencies):

  • Couchbase.Lite
  • Couchbase.Lite.Support.NetDesktop
  • NUnit

This reproduces the problem. Here is the exact error message:

System.TypeInitializationException : The type initializer for 'Couchbase.Lite.Sync.HTTPLogic' threw an exception.
  ----> System.DllNotFoundException : LiteCore

I’ve scanned the forums on this problem. It seems that there are a couple of things that have fixed it for some people:

  • an older version of couchbase had some issues (I’m running 2.1.2 - the latest).
  • mixing versions of couchbase across projects within a solution. I’ve updated all project’s packages to couchbase 2.1.2 (some of course wont build yet).

I have checked - libLiteCore.dylib does exist in the bin/Debug folder and is identical to the one in the nuget packages folder:

$ cmp CBTester/bin/Debug/libLiteCore.dylib ~/.nuget/packages/couchbase.lite.support.netdesktop/2.1.2/runtimes/osx-x64/native/libLiteCore.dylib
$ echo $?
0

I can see in the application output that it is not loading libLiteCore, although you can see it load all the other Couchbase libraries:

...
Thread started: EventPumpThread #10
Thread started: NonParallelWorker #11
Loaded assembly: /Users/Paul/Dev/Test/CBTester/bin/Debug/Couchbase.Lite.dll
Loaded assembly: /Users/Paul/Dev/Test/CBTester/bin/Debug/netstandard.dll
Loaded assembly: /Users/Paul/Dev/Test/CBTester/bin/Debug/Couchbase.Lite.Support.NetDesktop.dll
Loaded assembly: /Users/Paul/Dev/Test/CBTester/bin/Debug/SimpleInjector.dll
Thread finished: EventPumpThread #10
Thread finished: NonParallelWorker #11
Thread finished:  #3
...

Does anyone have any ideas as to how to fix this?
Many thanks.
Paul

Legal disclaimer: Couchbase Lite 2.x is not officially supported on macOS.

Technical note: It should work, because we run it through some automated tests in preparation for when we do support it eventually.

Test runners make such an insane environment that my first suspect would be NUnit. Does the same thing happen if you write a simple console application?

Hi @borrrden,
Thanks for getting back so quickly.

I created a console app. Added Couchbase.Lite and Couchbase.Lite.Support.NetDesktop.
Here is the program (basically the same as the unit test):

using System;
using Couchbase.Lite;

namespace CBConsole
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            Couchbase.Lite.Support.NetDesktop.Activate();
            var db = new Database("test");
            var doc = new MutableDocument();
            doc.SetString("var", "variable value");
            doc.SetInt("num", 4);
            db.Save(doc);
        }
    }
}

Exactly the same error

System.DllNotFoundException: LiteCore
  at (wrapper managed-to-native) LiteCore.Interop.NativeRaw.c4_getVersion()
  at LiteCore.Interop.Native.c4_getVersion () [0x00001] in C:\Jenkins\workspace\couchbase-lite-net-edition-build\couchbase-lite-net-ee\couchbase-lite-net\src\LiteCore\src\LiteCore.Shared\Interop\Common\C4Base_native.cs:109 

This happens at the “new Database()” line.
The fact that this doesn’t work at all makes me think I’ve done something stupid. I know others have it working.

BTW - do you know roughly how long until you will start looking at official Mac support?
Thx.
Paul

I don’t have a timeline for official Mac support, and unfortunately I’m not the person who has that information either. I can only tell you if I am working on it or not (in this case, I am, but it remains unsupported for semantic internal reasons).

I’ve never seen this kind of failure on mac before, as usually mac is pretty good about having a reliable environment. I guess the next thing to do is to run otool -L on libLiteCore.dylib and make sure that everything that it needs exists in the correct location (things like libc++ etc, which I would be shocked if they were moved arbitrarily…).

Just a sanity question, but you are running 64-bit macOS right? I don’t think they even make 32-bit anymore but if for some reason you are on a 32-bit version of the OS then all bets are off.

Mac is definitely 64 bit. Its a 2016 MacBook Pro with the latest OS.
Checked libLiteCore using otool in the bin folder of my Console test app. It all looks fine:

$ otool -L libLiteCore.dylib 
libLiteCore.dylib:
	@rpath/libLiteCore.dylib (compatibility version 0.0.0, current version 0.0.0)
	/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1454.90.0)
	/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1454.90.0)
	/System/Library/Frameworks/CFNetwork.framework/Versions/A/CFNetwork (compatibility version 1.0.0, current version 902.1.0)
	/System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 58286.70.7)
	/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)
	/usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)

I just thought of something that I should have asked in the beginning. Are you using mono? Mono is definitely neither supported nor tested in 2.x and I’m pretty sure it does not work. .NET Core 2+ is the environment where it is known to work.

EDIT On the other hand, it is supported in 1.x and .NET Core is not (which is confusing, but 1.x was around far before .NET Core was released)

@borrrden
That was useful information. Thank you.

I had assumed my build was 64 bit. I created a small command line test app with Couchbase Lite. It failed.
I changed the project options to force 64bit for Platform Target (rather than “any”), That worked!

However, the NUnit apps are not so easy. I can select 64 bit build (NUnit projects build to libraries).
But the error is still there. I can run the NUnit tests on the command line:

  • install
    nuget install NUnit.ConsoleRunner

  • run:
    mono ~/.nuget/packages/nunit.consolerunner/3.9.0/tools/nunit3-console.exe bin/Debug/CoreTest.dll

This works (well… the DLLNotFound exception goes away - many tests still fail because of the large scale changes required for 1.x → 2.x, but that was expected).

I have been experimenting with trying to modify how VS runs the unit tests but to no avail so far.
A workaround that works for me is to switch to NUnitLite. This means changing the unit test project from building a library (for NUnit) to building an App, where the first line is:

    public static int Main(string[] args)
    {
        return new AutoRun().Execute(args);
    }

This works fine. There are undoubtedly better ways to do this - if anyone has read this far and knows how to better control NUnit execution on VS Mac, I’m all ears. (Note: I have played with setting up .runsettings files, and with using the NUnit Adapter. Neither worked).

Thanks for this information. I need to stick to .NET/Mono, not .NET Core because I’m building a GUI that runs on Mac and iOS. It sounds like I need to stick to 1.x for the time being (which is sad, because there is a lot to like in 2.x).