Previously I was using the regular MongoDB C# drivers to access my Atlas data, but eventually ran into an issue using IL2CPP that prevented the MongoDatabase client from completely being created on the client side.
Similar issues seem to persist in the Realm SDK.
Running this code in Editor works fine, and it works fine on Android when running on Mono. When running it on IL2CPP, it catches a NullReferenceException. Any idea why that might be happening and are there any known workarounds?
03-11 10:09:51.347 10058 10084 W Unity : Realm exception: System.NullReferenceException: Object reference not set to an instance of an object.
03-11 10:09:51.347 10058 10084 W Unity : at System.Linq.Expressions.Interpreter.LightLambda.MakeRunDelegateCtor (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0
03-11 10:09:51.347 10058 10084 W Unity : at System.Linq.Expressions.Interpreter.LightLambda.GetRunDelegateCtor (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0
03-11 10:09:51.347 10058 10084 W Unity : at System.Linq.Expressions.Interpreter.LightLambda.MakeDelegate (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0
03-11 10:09:51.347 10058 10084 W Unity : at System.Linq.Expressions.Expression`1[TDelegate].Compile (System.Boolean preferInterpretation) [0x00000] in <00000000000000000000000000000000>:0
03-11 10:09:51.347 10058 10084 W Unity : at MongoDB.Bson.Serialization.BsonClassMap.GetCreator () [0x00000] in <00000000000000000000000000000000>:0
03-11 10:09:51.347 10058 10084 W Unity : at MongoDB.Bson.Serialization.BsonClassMap.CreateInstance () [0x00000] in <00000000000000000000000000000000>:0
03-11 10:09:51.347 10058 10084 W Unity : at MongoDB.Bson.Serialization.BsonClassMapSerializer`1[TClass].DeserializeClass (MongoDB.Bson.Serial
Here’s a proper stack trace. It should be easy to reproduce, just set the Scripting Backend to IL2CPP, build for Android and call a Realm function somewhere.
Realm exception: System.NullReferenceException: Object reference not set to an instance of an object.
at System.Linq.Expressions.Interpreter.LightLambda.MakeRunDelegateCtor (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0
at System.Linq.Expressions.Interpreter.LightLambda.GetRunDelegateCtor (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0
at System.Linq.Expressions.Interpreter.LightLambda.MakeDelegate (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0
at System.Linq.Expressions.Expression`1[TDelegate].Compile (System.Boolean preferInterpretation) [0x00000] in <00000000000000000000000000000000>:0
at MongoDB.Bson.Serialization.BsonClassMap.GetCreator () [0x00000] in <00000000000000000000000000000000>:0
at MongoDB.Bson.Serialization.BsonClassMap.CreateInstance () [0x00000] in <00000000000000000000000000000000>:0
at MongoDB.Bson.Serialization.BsonClassMapSerializer`1[TClass].DeserializeClass (MongoDB.Bson.Serialization.BsonDeserializationContext context) [0x00000] in <00000000000000000000000000000000>:0
at MongoDB.Bson.Serialization.BsonSerializer.Deserialize[TNominalType] (System.String json, System.Action`1[T] configurator) [0x00000] in <00000000000000000000000000000000>:0
at Realms.Sync.User+FunctionsClient+<CallAsync>d__3`1[T].MoveNext () [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ContextCallback.Invoke (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <00000000000000000000000000000000>:0
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run () [0x00000] in <00000000000000000000000000000000>:0
at System.Action.Invoke () [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ContextCallback.Invoke (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.Tasks.AwaitTaskContinuation.RunCallback (System.Threading.ContextCallback callback, System.Object state, System.Threading.Tasks.Task& currentTask) [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.Tasks.Task.FinishContinuations () [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.Tasks.Task`1[TResult].TrySetResult (TResult result) [0x00000] in <00000000000000000000000000000000>:0
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[TResult].SetResult (TResult result) [0x00000] in <00000000000000000000000000000000>:0
at Realms.Sync.SyncUserHandle+<CallFunctionAsync>d__13.MoveNext () [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ContextCallback.Invoke (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <00000000000000000000000000000000>:0
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run () [0x00000] in <00000000000000000000000000000000>:0
at System.Action.Invoke () [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.SendOrPostCallback.Invoke (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.UnitySynchronizationContext.Exec () [0x00000] in <00000000000000000000000000000000>:0
--- End of stack trace from previous location where exception was thrown ---
Hm… that looks unfortunate. IL2CPP doesn’t support lambda compilation, but MongoDB.Bson uses that heavily. I’ll need to investigate why it’s working fine with some classes, but not with others. In the meantime, a few things we can try:
Do you have a constructor defined on the Items class? And are you using it anywhere in your code? It’s possible that this gets stripped by the linker.
Can you try not deserializing the result into Items? This means that CallAsync will return a BsonDocument - if that works, you can write a manual deserializer for Items that extracts the values from the document. It’s obviously not ideal, but if it works, it should unblock you while we investigate the lambda issue.
Forgot to mention in the OP but I’m running on Unity LTS 2020.3.17f1 if that helps.
Items doesn’t have a contructor defined. I’ve tried it with a few other classes with varying attributes and fields and so far the exception seems to occur when deserializing into any object. Even BsonDocument.
It does seem to work when not passing in a type to deserialize into!