Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In Owin, getting "Unable to create a storage engine, fatal error" message #396

Closed
chimon2000 opened this issue Apr 7, 2015 · 9 comments
Closed
Assignees
Labels
Milestone

Comments

@chimon2000
Copy link

I get the following error when I attempt to create my database within the context of OWIN.

Unable to create a storage engine, fatal error

Any simple example will fail but in my case I am using Nancy Modules. The same code works perfectly fine within a console app. I am not specifying platform.

@chimon2000 chimon2000 changed the title In Owin, getting Unable to create a storage engine, fatal error In Owin, getting "Unable to create a storage engine, fatal error" message Apr 7, 2015
@borrrden
Copy link
Member

borrrden commented Apr 8, 2015

There should be more detailed information than that in the log file. What this usually means is that the native sqlite library was unable to be found. This is a problem on Windows in particular. Can you provide some more information about your environment? Are you trying to run couchbase lite as a web service?

@chimon2000
Copy link
Author

Extra details:

  • Trying to run embedded in an MVC application (IIS Express)
  • Database logic is abstracted into a separate library and resolved using Autofac.
  • When examining the bin folder for the app, both the x64 & x86 versions of sqlite3 are present.
  • I get the same error even if I target x86.
  • Environment: 64-bit Windows, x64 Processor

If there are other details that you need, let me know. I'm not sure where I should be looking for the log file, here's the full stack trace:

[CouchbaseLiteException: Unable to create a storage engine, fatal error]
   Couchbase.Lite.Database.Open() +367
   Couchbase.Lite.Manager.GetDatabase(String name) +85
   CouchbaseLite.Demo.Data.LocalData.DatabaseManager.CreateDatabase() in c:\Work\Diligent\Sandbox\CouchbaseLite.Demo\source\CouchbaseLite.Demo.Data\LocalData\DatabaseManager.cs:46
   CouchbaseLite.Demo.Data.LocalData.DatabaseManager.InitializeDb() in c:\Work\Diligent\Sandbox\CouchbaseLite.Demo\source\CouchbaseLite.Demo.Data\LocalData\DatabaseManager.cs:25
   CouchbaseLite.Demo.Web.Bootstrapper.NancyBootstrapper.GetApplicationContainer() in c:\Work\Diligent\Sandbox\CouchbaseLite.Demo\source\CouchbaseLite.Demo.Web\Bootstrapper\NancyBootstrapper.cs:21
   Nancy.Bootstrapper.NancyBootstrapperBase`1.Initialise() +276
   Nancy.Owin.NancyMiddleware.UseNancy(NancyOptions options) +186
   Owin.AppBuilderExtensions.UseNancy(IAppBuilder builder, NancyOptions options) +126
   CouchbaseLite.Demo.Web.Startup.ConfigureNancy(IAppBuilder app) in c:\Work\Diligent\Sandbox\CouchbaseLite.Demo\source\CouchbaseLite.Demo.Web\App_Start\Startup.cs:24
   CouchbaseLite.Demo.Web.Startup.Configuration(IAppBuilder appBuilder) in c:\Work\Diligent\Sandbox\CouchbaseLite.Demo\source\CouchbaseLite.Demo.Web\App_Start\Startup.cs:19

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
   System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +92
   System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +155
   System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) +19
   Owin.Loader.<>c__DisplayClass12.<MakeDelegate>b__b(IAppBuilder builder) +118
   Owin.Loader.<>c__DisplayClass1.<LoadImplementation>b__0(IAppBuilder builder) +254
   Microsoft.Owin.Host.SystemWeb.<>c__DisplayClass2.<InitializeBlueprint>b__0(IAppBuilder builder) +89
   Microsoft.Owin.Host.SystemWeb.OwinAppContext.Initialize(Action`1 startup) +856
   Microsoft.Owin.Host.SystemWeb.OwinBuilder.Build(Action`1 startup) +136
   Microsoft.Owin.Host.SystemWeb.OwinHttpModule.InitializeBlueprint() +159
   System.Threading.LazyInitializer.EnsureInitializedCore(T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory) +86
   System.Threading.LazyInitializer.EnsureInitialized(T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory) +72
   Microsoft.Owin.Host.SystemWeb.OwinHttpModule.Init(HttpApplication context) +104
   System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +418
   System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +172
   System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +336
   System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +296

[HttpException (0x80004005): Exception has been thrown by the target of an invocation.]
   System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +9955652
   System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +101
   System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +254

@borrrden
Copy link
Member

borrrden commented Apr 9, 2015

As an extra annoying step, can you confirm that the sqlite3.dll native dll files are in the x86 and x64 folders, the folders being in the same directory as the SQLitePCL raw DLL file? I've been having a problem on Unity where it moves the native folders to another directory during the build process and then SQLitePCL cannot resolve them anymore. I assume since you are using Nancy that you are targeting the 4.5 version?

@borrrden borrrden self-assigned this Apr 9, 2015
@chimon2000
Copy link
Author

Looking at my Web project:

  • SQLitePCL raw & ugly are both in the /bin folder.
  • sqlite3.dll is in /bin/x86 & /bin/x64.

Also, yes I am targeting 4.5.

@chimon2000
Copy link
Author

This may help you reproduce (left out bootstrapper, startup, and some extension methods)

    public class DatabaseManager
    {
        public Database Db
        {
            get
            {
                return _database;
            }
        }

        Database _database;

        const string DatabaseName = "couchbase-bugs";

        public void InitializeDb()
        {
            CreateDatabase();
            SetupViews();
        }

        void CreateDatabase()
        {
            Manager manager = null;

            var _dbDir = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "temp", "db");

            var dirInfo = Directory.CreateDirectory(_dbDir);

            try
            {
                manager = new Manager(dirInfo, Manager.DefaultOptions);
            }
            catch (DirectoryNotFoundException e)
            {
                Log.E("", "Cannot create Manager instance", e);
            }

            _database = manager.GetDatabase(DatabaseName);
        }

        void SetupViews()
        {

            var view = _database.GetView("bugs");
            if (view.Map == null)
            {
                // Create a view and register its map function:
                view.SetMap((document, emit) =>
                {
                    if ("bug".Equals(document["type"]))
                    {
                        var keys = new List<object>();
                        keys.Add(document["created_at"]);
                        emit(keys, document);
                    }
                }, "1");
            }
        }
    }
    public class Repository
    {
        DatabaseManager _dbManager;
        private const string Bugs = "bugs";
        private const string Bug = "bug";

        public Repository()
        {
            _dbManager = new DatabaseManager();
            _dbManager.InitializeDb();
        }

        public Bug SaveBug(Bug bug)
        {
            var properties = bug.ToDictionary();
            properties.Add("created_at", DateTime.Now);

            var doc = SaveDocument(bug.Id, properties, Bug);
            var documentDetail = doc.Properties.ToObject<Bug>();
            documentDetail.Id = doc.Id;

            return documentDetail;
        }

        public Bug GetBug(string id)
        {
            var doc = _dbManager.Db.GetExistingDocument(id);
            var documentDetail = doc == null ? new Bug() : doc.Properties.ToObject<Bug>();

            return documentDetail;

        }

        public IEnumerable<Bug> GetBugs()
        {
            var query = _dbManager.Db.GetExistingView(Bugs).CreateQuery();

            var enumerator = query.Run();

            return enumerator.Select(row => row.Document.UserProperties.ToObject<Bug>());
        }

        Couchbase.Lite.Document SaveDocument(string docId, IDictionary<string, object> dict, string doctype)
        {
            Console.WriteLine("Saving [{0}] with Id [{1}]", doctype, docId ?? "None");

            var doc = string.IsNullOrEmpty(docId) ? _dbManager.Db.CreateDocument() : _dbManager.Db.GetDocument(docId);


            var revision = doc.CreateRevision();

            dict["id"] = doc.Id;
            dict.Add("type", doctype);
            revision.SetUserProperties(dict);
            revision.Save();

            return doc;

        }
    }

    public class Bug
    {
        public string Id { get; set; }
        public string Description { get; set; }
        public string Status { get; set; }
    }

    public class BugModule : NancyModule
    {

        public BugModule()
            : base("/api/bug")
        {

            Get["/"] = _ =>
            {
                var repository = new Repository();
                return Negotiate.WithModel(repository.GetBugs())
                                .WithStatusCode(HttpStatusCode.OK);
            };


        }
    }

@borrrden
Copy link
Member

Thanks for that, I'll have a look at it and should have something to say about it in the next few days.

@borrrden
Copy link
Member

I've successfully reproduced the issue, and will now look into the cause.

@borrrden
Copy link
Member

The issue is that IIS (I believe?) changes the base directory of the app domain. This will cause the search for sqlite3.dll to fail. The search code is not part of Couchbase Lite's codebase, but I have found a workaround. You need to move the x86/x64 folders out of the "bin" folder into their parent folder (i.e. the folder containing your .csproj file). This will work for running from visual studio. I'm not familiar with Web development, but you will need to follow a similar process for deployment as well. You can probably add it to your project as a post-build step. Does this help get things running?

@chimon2000
Copy link
Author

Yes, that worked! Extremely interesting workaround. What I'm assuming is the issue is that the search code assumes the executables are in its starting location when in reality they are always in the bin for IIS. If I self-hosted, this issue may disappear entirely. Thanks!

@zgramana zgramana modified the milestone: 1.1 Jun 11, 2015
@zgramana zgramana added the bug label Jun 11, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants