realm / realm-dotnet

Realm is a mobile database: a replacement for SQLite & ORMs
https://realm.io
Apache License 2.0
1.25k stars 164 forks source link

Realm.GetInstance(path) throws Realms.RealmFileAccessErrorException: Operation not permitted exception Xamarin Android #542

Closed MilenPavlov closed 8 years ago

MilenPavlov commented 8 years ago

Using: Microsoft VisualStudio 2015 Enterprise Xamarin 4.0.3.214 Xamarin Android version 6.0.3.5 Android Compiler SDK config : Compile API level 23, Minimum Android target : API level 15. Running in debug mode. Trying to use Realm in my Xamarin Android project. Installed nuget package required (Realm 0.74.1). Device has read external storage permission. Tested on HTC One X (Android 4.2) and Android Emulator running Nexus 5 with Android Lollipop installed Following the api recepies I used this code in button click event handler:

var realm = Realm.GetInstance(path); where path is actual path to file created in my appfolder (file exists on device storage).

The exception I'm getting is

Realms.RealmFileAccessErrorException: Operation not permitted at Realms.NativeCommon.ExceptionThrower (IntPtr exceptionCode, IntPtr utf8String, IntPtr stringLen) [0x0003b] in :0 at (wrapper native-to-managed) Realms.NativeCommon:ExceptionThrower (intptr,intptr,intptr) at (wrapper managed-to-native) Realms.NativeSharedRealm:open (Realms.SchemaHandle,string,intptr,intptr,intptr,byte[],ulong) 05-15 12:57:18.384 I/mono-stdout( 5250): Realms.RealmFileAccessErrorException: Operation not permitted 05-15 12:57:18.384 I/mono-stdout( 5250): at Realms.NativeCommon.ExceptionThrower (IntPtr exceptionCode, IntPtr utf8String, IntPtr stringLen) [0x0003b] in :0 05-15 12:57:18.384 I/mono-stdout( 5250): at (wrapper native-to-managed) Realms.NativeCommon:ExceptionThrower (intptr,intptr,intptr) 05-15 12:57:18.385 I/mono-stdout( 5250): at (wrapper managed-to-native) Realms.NativeSharedRealm:open (Realms.SchemaHandle,string,intptr,intptr,intptr,byte[],ulong) 05-15 12:57:18.385 I/mono-stdout( 5250): at Realms.Realm.GetInstance (Realms.RealmConfiguration config) [0x0010c] in :0 05-15 12:57:18.385 I/mono-stdout( 5250): at Realms.Realm.GetInstance (System.String databasePath) [0x00019] in :0 05-15 12:57:18.385 I/mono-stdout( 5250): at MyApp.Activities.SplashScreenActivity+d_4.MoveNext () [0x00116] in C:\Users**\Source\Repos\AppName\MyApp\Activities\SplashScreenActivity.cs:66 at Realms.Realm.GetInstance (Realms.RealmConfiguration config) [0x0010c] in :0 at Realms.Realm.GetInstance (System.String databasePath) [0x00019] in :0 at MyApp.Activities.SplashScreenActivity+d_4.MoveNext () [0x00116] in C:\Users**\Source\Repos\AppName\MyApp\Activities\SplashScreenActivity.cs:66

I've tried with var realm = Realm.GetInstance(); too but I got another exception:

System.ArgumentNullException: Value cannot be null. Parameter name: type at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00006] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/activator.cs:205 05-15 13:05:05.257 I/mono-stdout( 5474): System.ArgumentNullException: Value cannot be null. 05-15 13:05:05.257 I/mono-stdout( 5474): Parameter name: type 05-15 13:05:05.257 I/mono-stdout( 5474): at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00006] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/activator.cs:205 05-15 13:05:05.257 I/mono-stdout( 5474): at System.Activator.CreateInstance (System.Type type) [0x00000] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/activator.cs:147 at System.Activator.CreateInstance (System.Type type) [0x00000] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/activator.cs:147 at Realms.Realm.CreateRealmObjectMetadata (System.Type realmObjectType) [0x0001e] in :0 at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, System.Func2 keySelector, System.Func2 elementSelector, IEqualityComparer1 comparer) [0x0004d] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:855 at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, System.Func2 keySelector, System.Func2 elementSelector) [0x00000] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:847 at Realms.Realm..ctor (Realms.SharedRealmHandle sharedRealmHandle, Realms.RealmConfiguration config) [0x00037] in :0

at Realms .Realm.GetInstance (Realms.RealmConfiguration config) [0x00171] in :0 at MyApp.Activities.SplashScreenActivity+d4.MoveNext () [0x00116] in C:\Users***\Source\Repos\AppName\MyApp\Activities\SplashScreenActivity.cs:66 05-15 13:05:05.257 I/mono-stdout( 5474): at Realms.Realm.CreateRealmObjectMetadata (System.Type realmObjectType) [0x0001e] in :0 05-15 13:05:05.257 I/mono-stdout( 5474): at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, System.Func2 keySelector, System.Func2 elementSelector, IEqualityComparer1 comparer) [0x0004d] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:855 05-15 13:05:05.257 I/mono-stdout( 5474): at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, System.Func2 keySelector, System.Func2 elementSelector) [0x00000] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:847 05-15 13:05:05.257 I/mono-stdout( 5474): at Realms.Realm..ctor (Realms.SharedRealmHandle sharedRealmHandle, Realms.RealmConfiguration config) [0x00037] in :0 05-15 13:05:05.257 I/mono-stdout( 5474): at Realms.Realm.GetInstance (Realms.RealmConfiguration config) [0x00171] in :0 05-15 13:05:05.257 I/mono-stdout( 5474): at MyApp.Activities.SplashScreenActivity+d4.MoveNext () [0x00116] in C:\Users***\Source\Repos\AppName\MyApp\Activities\SplashScreenActivity.cs:66

drungrin commented 8 years ago

Put only the name of the database.  You app have sdcard read and write permissions for storing the database on the sd card?

Enviado do Outlook Mobile

On Sun, May 15, 2016 at 5:51 AM -0700, "Milen Pavlov" notifications@github.com wrote:

Trying to use Realm in my Xamarin Android project.

Installed nuget package required (Realm 0.74.1).

Device has read external storage permission.

Tested on HTC One X (Android 4.2) and Android Emulator running Nexus 5 with Android Lollipop installed

Following the api recepies I used this code in button click event handler:

var realm = Realm.GetInstance(path);

where path is actual path to file created in my appfolder (file exists on device storage).

The exception I'm getting is

Realms.RealmFileAccessErrorException: Operation not permitted at Realms.NativeCommon.ExceptionThrower (IntPtr exceptionCode, IntPtr utf8String, IntPtr stringLen) [0x0003b] in :0 at (wrapper native-to-managed) Realms.NativeCommon:ExceptionThrower (intptr,intptr,intptr) at (wrapper managed-to-native) Realms.NativeSharedRealm:open (Realms.SchemaHandle,string,intptr,intptr,intptr,byte[],ulong) 05-15 12:57:18.384 I/mono-stdout( 5250): Realms.RealmFileAccessErrorException: Operation not permitted 05-15 12:57:18.384 I/mono-stdout( 5250): at Realms.NativeCommon.ExceptionThrower (IntPtr exceptionCode, IntPtr utf8String, IntPtr stringLen) [0x0003b] in :0 05-15 12:57:18.384 I/mono-stdout( 5250): at (wrapper native-to-managed) Realms.NativeCommon:ExceptionThrower (intptr,intptr,intptr) 05-15 12:57:18.385 I/mono-stdout( 5250): at (wrapper managed-to-native) Realms.NativeSharedRealm:open (Realms.SchemaHandle,string,intptr,intptr,intptr,byte[],ulong) 05-15 12:57:18.385 I/mono-stdout( 525 0): at R ealms.Realm.GetInstance (Realms.RealmConfiguration config) [0x0010c] in :0 05-15 12:57:18.385 I/mono-stdout( 5250): at Realms.Realm.GetInstance (System.String databasePath) [0x00019] in :0 05-15 12:57:18.385 I/mono-stdout( 5250): at MyApp.Activities.SplashScreenActivity+d4.MoveNext () [0x00116] in C:\Users\Source\Repos\AppName\MyApp\Activities\SplashScreenActivity.cs:66 at Realms.Realm.GetInstance (Realms.RealmConfiguration config) [0x0010c] in :0 at Realms.Realm.GetInstance (System.String databasePath) [0x00019] in :0 at MyApp.Activities.SplashScreenActivity+d4.MoveNext () [0x00116] in C:\Users\Source\Repos\AppName\MyApp\Activities\SplashScreenActivity.cs:66

I've tried with

var realm = Realm.GetInstance(); too but I got another exception:

System.ArgumentNullException: Value cannot be null. Parameter name: type at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00006] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/activator.cs:205 05-15 13:05:05.257 I/mono-stdout( 5474): System.ArgumentNullException: Value cannot be null. 05-15 13:05:05.257 I/mono-stdout( 5474): Parameter name: type 05-15 13:05:05.257 I/mono-stdout( 5474): at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00006] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/activator.cs:205 05-15 13:05:05.257 I/mono-stdout( 5474): at System.Activator.CreateInstance (System.Type type) [0x00000] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/mscorlib/system/activator.cs:147 at System.Activator.CreateInstance (System.Type type) [0x00000] in /Users/builder/data/lanes/3053/a94a03b5/s ource/mo no/external/referencesource/mscorlib/system/activator.cs:147 at Realms.Realm.CreateRealmObjectMetadata (System.Type realmObjectType) [0x0001e] in :0 at System.Linq.Enumerable.ToDictionaryTSource,TKey,TElement [0x0004d] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:855 at System.Linq.Enumerable.ToDictionaryTSource,TKey,TElement [0x00000] in

/Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:847

at Realms.Realm..ctor (Realms.SharedRealmHandle sharedRealmHandle,

Realms.RealmConfiguration config) [0x00037] in :0

at Realms .Realm.GetInstance (Realms.RealmConfiguration config)

[0x00171] in :0 at

MyApp.Activities.SplashScreenActivity+d__4.MoveNext ()

[0x00116] in

C:\Users*\Source\Repos\AppName\MyApp\Activities\SplashScreenActivity.cs:66

05-15 13:05:05.257 I/mono-stdout( 5474): at

Realms.Realm.CreateRealmObjectMetadata (System.Type realmObjectType)

[0x0001e] in :0 05-15 13:05:05.257 I/mono-stdout(

5474): at System.Linq.Enumerable.ToDictionaryTSource,TKey,TElement [0x0004d] in

/Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:855

05-15 13:05:05.257 I/mono-stdout( 5474): at

System.Linq.Enumerable.ToDictionaryTSource,TKey,TElement [0x00000] in /Users/builder/data/lanes/3053/a94a03b5/source/mono/external/referencesource/System.Core/System/Linq/Enumerable.cs:847 05-15 13:05:05.257 I/mono-stdout( 5474): at Realms.Realm..ctor (Realms.SharedRealmHandle sharedRealmHandle, Realms.RealmConfiguration config) [0x00037] in :0 05-15 13:05:05.257 I/mono-stdout( 5474): at Realms.Realm.GetInstance (Realms.RealmConfiguration config) [0x00171] in :0 05-15 13:05:05.257 I/mono-stdout( 5474): at MyApp.Activities.SplashScreenActivity+d__4.MoveNext () [0x00116] in C:\Users*\Source\Repos\AppName\MyApp\Activities\SplashScreenActivity.cs:66

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub

AndyDentFree commented 8 years ago

@MilenPavlov You said

Following the api recepies I used this code in button click event handler: var realm = Realm.GetInstance(path); where path is actual path to file created in my appfolder (file exists on device storage).

What is the full string in path when you call GetInstance?

MilenPavlov commented 8 years ago

Tried with var realm = Realm.GetInstance("myappDb.realm"); file exists under "/storage/sdcard0/myappDb.realm" and got exception:

Realms.RealmFileAccessErrorException: Operation not permitted 05-15 17:29:39.495 I/mono-stdout(23466): Realms.RealmFileAccessErrorException: Operation not permitted at Realms.NativeCommon.ExceptionThrower (IntPtr exceptionCode, IntPtr utf8String, IntPtr stringLen) [0x0003b] in :0

The app has read and write external storage permission:

  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
MilenPavlov commented 8 years ago

@AndyDentFree initially I used Custom app folder like so "/storage/sdcard0/myAppName/myappDb.realm" where I store app specific data. I also tried to store it under root folder of external storage "/storage/sdcard0/myappDb.realm" I both cases I checked that file actually exists. App has read and write external storage permissions

AndyDentFree commented 8 years ago

@MilenPavlov Try this approach to dump out the path:

                var con = new RealmConfiguration("myappDb.realm");
                System.Diagnostics.Debug.WriteLine(con.DatabasePath);
                var r = Realm.GetInstance(con);

What do you mean by:

I both cases I checked that file actually exists.

Did you write code that checks using system APIs? Can you post more context please.

MilenPavlov commented 8 years ago

@AndyDentFree I just meant that the file exists under specified path :)

Path we have is is: /data/data/myappname.mobile.droid/files/myappDb.realm

when got another exception when running last line of your code: var r = Realm.GetInstance(con);

System.ArgumentNullException: Value cannot be null. Parameter name: type at System.Activator.CreateInstance (System.Type type, Boolean nonPublic)

Realm nuget package is installed in droid project and two pcl projects (holding models and viewmodels)

In the event handler of LinearLayout.Click event I have this code:

    public class SplashScreenActivity : FragmentActivityBase (this inherits from AppCompatActivity)
    {
.........
        private void SplashScreenOnClick(object sender, EventArgs eventArgs)
        {
            try
            {

                var con = new RealmConfiguration("myappDb.realm");
                System.Diagnostics.Debug.WriteLine(con.DatabasePath);
                var r = Realm.GetInstance(con);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

Will try to reproduce on another small solution in github

Update: Worked fine on small solution.Could it be because of one of the other nuget packages I have installed in my droid project?

<packages>
  <package id="akavache" version="4.1.2" targetFramework="monoandroid60" />
  <package id="akavache.core" version="4.1.2" targetFramework="monoandroid60" />
  <package id="akavache.sqlite3" version="4.1.2" targetFramework="monoandroid60" />
  <package id="Fody" version="1.29.4" targetFramework="monoandroid60" developmentDependency="true" />
  <package id="MonoDroid.Toolkit" version="1.1.0.0" targetFramework="monoandroid44" />
  <package id="Newtonsoft.Json" version="6.0.8" targetFramework="monoandroid60" />
  <package id="Plugin.CurrentActivity" version="1.0.1" targetFramework="monoandroid44" />
  <package id="Plugin.Permissions" version="1.1.3" targetFramework="monoandroid44" />
  <package id="Realm" version="0.74.1" targetFramework="monoandroid60" developmentDependency="true" />
  <package id="Refractored.PagerSlidingTabStrip" version="1.1.2" targetFramework="monoandroid50" />
  <package id="Rx-Core" version="2.2.5" targetFramework="monoandroid60" />
  <package id="Rx-Interfaces" version="2.2.5" targetFramework="monoandroid60" />
  <package id="Rx-Linq" version="2.2.5" targetFramework="monoandroid60" />
  <package id="Rx-Main" version="2.2.5" targetFramework="monoandroid60" />
  <package id="Rx-PlatformServices" version="2.2.5" targetFramework="monoandroid60" />
  <package id="Splat" version="1.3.3" targetFramework="monoandroid60" />
  <package id="SQLitePCL.raw_basic" version="0.7.1" targetFramework="monoandroid60" />
  <package id="StyleCop.Analyzers" version="1.0.0" targetFramework="monoandroid60" developmentDependency="true" />
  <package id="Xam.iTextSharpLGPL" version="0.1.0" targetFramework="monoandroid60" />
  <package id="Xamarin.Android.Support.Design" version="23.1.1.1" targetFramework="monoandroid60" />
  <package id="Xamarin.Android.Support.v4" version="23.1.1.1" targetFramework="monoandroid60" />
  <package id="Xamarin.Android.Support.v7.AppCompat" version="23.1.1.1" targetFramework="monoandroid60" />
  <package id="Xamarin.Android.Support.v7.CardView" version="23.1.1.0" targetFramework="monoandroid50" />
  <package id="Xamarin.Android.Support.v7.RecyclerView" version="23.1.1.1" targetFramework="monoandroid60" />
  <package id="Xamarin.GooglePlayServices.Ads" version="29.0.0.1" targetFramework="monoandroid60" />
  <package id="Xamarin.GooglePlayServices.Auth" version="29.0.0.1" targetFramework="monoandroid60" />
  <package id="Xamarin.GooglePlayServices.Base" version="29.0.0.1" targetFramework="monoandroid60" />
  <package id="Xamarin.GooglePlayServices.Basement" version="29.0.0.1" targetFramework="monoandroid60" />
  <package id="Xamarin.GooglePlayServices.Gcm" version="29.0.0.1" targetFramework="monoandroid60" />
  <package id="Xamarin.GooglePlayServices.Location" version="29.0.0.1" targetFramework="monoandroid60" />
  <package id="Xamarin.GooglePlayServices.Maps" version="29.0.0.1" targetFramework="monoandroid60" />
  <package id="Xamarin.GooglePlayServices.Measurement" version="29.0.0.1" targetFramework="monoandroid60" />
  <package id="Xamarin.GooglePlayServices.Plus" version="29.0.0.1" targetFramework="monoandroid60" />
</packages>
AndyDentFree commented 8 years ago

Can you please send us the entire program or a subset which reproduces this problem?

If you don't want to post it publicly but are willing to provide it for our testing, please mail me a zip at ad@realm.io

I'm starting to suspect some clash has stopped Fody from weaving the code into your objects descending from RealmObject.

If you look at your Build log, do you see an entry like Fody/RealmWeaver: Executing Weaver?

Is there a file FodyWeavers.xml in your project and what does it contain?

MilenPavlov commented 8 years ago

Will try to create example first thing in the morning, many thanks for your help!

MilenPavlov commented 8 years ago

Build log from Droid project:

2>CopyRealmWeaver: 2> CopyRealmWeaver 2> Copying file from "C:\Users\Milen\Source\Repos\myApp\packages/Realm.0.74.1/tools/RealmWeaver.Fody.dll" to "C:\Users\Milen\Source\Repos\myApp\/Tools\RealmWeaver.Fody.dll". 2>FodyTarget: 2> Fody: Fody (version 1.29.4.0) Executing 2> Fody: ProjectDirectory: 'C:\Users\Milen\Source\Repos\myApp\myApp.Mobile.Droid\'. 2> Fody: AssemblyPath: 'C:\Users\Milen\Source\Repos\myApp\myApp.Mobile.Droid\obj\Debug\myApp.Mobile.Droid.dll' 2> Fody: Found path to weavers file 'C:\Users\Milen\Source\Repos\myApp\myApp.Mobile.Droid\FodyWeavers.xml'. 2> Fody: SolutionDirectory path is 'C:\Users\Milen\Source\Repos\myApp\' 2> Fody: Finding weavers 2> Fody: Adding weaver dlls from 'C:\Users\Milen\Source\Repos\myApp\Packages'. 2> Fody: Could not find packages dir from nuget config. 2> Fody: SolutionDirectoryPath: C:\Users\Milen\Source\Repos\myApp\ 2> Fody: Adding weaver dlls from 'C:\Users\Milen\Source\Repos\myApp\packages'. 2> Fody: SolutionDirectoryPath: C:\Users\Milen\Source\Repos\myApp\ 2> Fody: Adding weaver dlls from 'C:\Users\Milen\Source\Repos\myApp\Tools'. 2> Fody: Fody weaver file added 'C:\Users\Milen\Source\Repos\myApp\Tools\RealmWeaver.Fody.dll' 2> Fody: No Weaver project file found. 2> Fody: Finished finding weavers 18ms 2> Fody: Creating a new AppDomain 2> Fody: Reference count=104 2> Fody: Found debug symbols at 'C:\Users\Milen\Source\Repos\myApp\myApp.Mobile.Droid\obj\Debug\myApp.Mobile.Droid.pdb'. 2> Fody: Weaver 'C:\Users\Milen\Source\Repos\myApp\Tools\RealmWeaver.Fody.dll'. 2> Fody: Initializing weaver 2> Fody: Loading 'C:\Users\Milen\Source\Repos\myApp\Tools\RealmWeaver.Fody.dll' from disk. 2> Fody/RealmWeaver: Executing Weaver 2> Fody/RealmWeaver: Finished 'RealmWeaver' in 582ms 2>
2> Fody: Writing assembly to 'C:\Users\Milen\Source\Repos\myApp\myApp.Mobile.Droid\obj\Debug\myApp.Mobile.Droid.dll'. 2> Fody: Finished writing assembly 242ms. 2> Fody: Finished Fody 1030ms.

and content of FodyWeavers.xml:

<?xml version="1.0" encoding="utf-8"?>
<Weavers>
    <RealmWeaver/>

</Weavers>
AndyDentFree commented 8 years ago

Thanks, that proves that Fody is working and that the RealmWeaver is in place and used.

MilenPavlov commented 8 years ago

Update: This morning I started new branch from my dev branch, started by just adding Realm nuget packages - worked, then merged changes from my old branch (30+ files and got the exception again). This clearly shows that there's nothing wrong with Realm and it's most likely mess that I created. Many thanks for your help :)

AndyDentFree commented 8 years ago

Let us help you with your mess :-)

Realm shouldn't just work when you do things the right way. We should cope with better error handling and documentation if you create a mess and we shouldn't ever leave you wondering who's code is to blame.

It should be OK to open the same Realm many times simultaneously so unless you've managed to do something weird with your filesystem, you shouldn't be seeing this error.

However, it does seem like it's going to take a bit of digging so it would really help if you can send me an entire sample that replicates it.

If that's not feasible, we can work through using a debug version from source, which may help narrow things down.

MilenPavlov commented 8 years ago

Hi @AndyDentFree I did some more digging.. My project structure is: droid project and couple of pcl projects (profile 111) one of them being myapp.Models holding the app's models. If even one of those classes inherits from RealmObject then I get exception. If I remove inheritance it's all good... Will keep digging and let you know what I've found.

MilenPavlov commented 8 years ago

@AndyDentFree could you close the issue since, as far as I can see it's duplicate to issue #541 ?

AndyDentFree commented 8 years ago

Yes agreed - for anyone reading, go see the fix and resolution in #541 please.