Aws-sdk-net: On Unity, compiling the Android version to il2cpp causes an ExecutionEngineException at runtime

Created on 28 Oct 2016  路  29Comments  路  Source: aws/aws-sdk-net

My code is working fine on Android, with Mono, and on iOS with il2cpp but I wanted to try compiling my Unity game on Android with il2cpp, as it is now supported, but I have encountered an error which causes the UnityMainThreadDispatcher to be null.

In my GameController object I have a script which attaches the UnityInitialiser to itself, as instructed:

``` C#
UnityInitializer.AttachToGameObject(gameObject);


Compiling this and running it will cause this exception to occur:

I/Unity ( 7756): (Filename: ./artifacts/generated/Android/runtime/UnityEngineDebugBindings.gen.cpp Line: 45)
I/Unity ( 7756):
I/Unity ( 7756): ExecutionEngineException: Attempting to call method 'UnityEngine.AndroidJavaObject::Get' for which no ahead of time (AOT) code was generated.
I/Unity ( 7756):
I/Unity ( 7756): Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation.
```

Which disrupts the initialisation and UnityMainThreadDispatcher is not correctly added as a component to my GameController. (It will be null if I attempt to retrieve it).
Searching about this error lead me to this (CTRL+F "ExecutionEngineException") if that helps.

It is hard for me to debug this more as I am just using the provided DLLs on a non-Windows machine. I am guessing this is just a case of Android il2cpp not being supported, if that is the case then I hope it will be supported in the future.

Unity bug duplicate modulunity

Most helpful comment

Here is a workaround that I use works for my project.

Put below method in one of your GameObject, preferably with one that loads quite early on and in every scene.

    #if UNITY_ANDROID
    public void UsedOnlyForAOTCodeGeneration() {
        //Bug reported on github https://github.com/aws/aws-sdk-net/issues/477
        //IL2CPP restrictions: https://docs.unity3d.com/Manual/ScriptingRestrictions.html
        //Inspired workaround: https://docs.unity3d.com/ScriptReference/AndroidJavaObject.Get.html

        AndroidJavaObject jo = new AndroidJavaObject("android.os.Message");
        int valueString = jo.Get<int>("what");
    }
    #endif

All 29 comments

Hi. I am confused to ask what the request is. Could you explain a bit more how the SDK is involved in your project and detail specific feature requests if any? From the code snippets it seems like a general C# and and Unity issue.

Yeah sure. I use the SDK for Cognito Sync for online save data storage in Unity.

The Unity Engine had recently released il2cpp for android, allowing developers to natively compile their game from C# to C++. The SDK doesn't seem to work with it, even though it works for il2cpp on iOS.

This seems like an issue with il2cpp than the SDK itself. Unity forum/support would be a more appropriate place to ask this question. Feel free to reopen, if you find issues with the SDK.

Hi,

I'm not quite sure this is an IL2CPP issue.
We have a similar problem in our project:

Android log extract:

 ExecutionEngineException: Attempting to call method 'UnityEngine.AndroidJavaObject::Get' for which no ahead of time (AOT) code was generated.
   at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
   at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0 
   at Amazon.Util.Internal.AndroidInterop.GetJavaField[T] (System.Object androidJavaObject, System.String methodName) [0x00000] in <filename unknown>:0 
   at Amazon.Util.Internal.AmazonHookedPlatformInfo.Init () [0x00000] in <filename unknown>:0 
   at Amazon.Util.Internal.AmazonHookedPlatformInfo.get_Instance () [0x00000] in <filename unknown>:0 
   at Amazon.UnityInitializer.Awake () [0x00000] in <filename unknown>:0 
   at UnityEngine.GameObject.AddComponent[T] () [0x00000] in <filename unknown>:0

Let鈥檚 have a look at AmazonHookedPlatformInfo.Init:

public void Init()
{
  if (InternalSDKUtils.IsAndroid)
  {
    ...
    object androidJavaObject2 = AndroidInterop.CallMethod(androidJavaObject1, "getPackageInfo", (object) this.PackageName, (object) 0);
    ...
    this.VersionCode = Convert.ToString(AndroidInterop.GetJavaField<int>(androidJavaObject2, "versionCode"));

And AndroidInterop鈥檚 GetJavaField:

public static T GetJavaField<T>(object androidJavaObject, string methodName)
{
  return (T) ((IEnumerable<MethodInfo>) androidJavaObject.GetType().GetMethods()).Where<MethodInfo>((Func<MethodInfo, bool>) (x => x.Name == "Get")).First<MethodInfo>((Func<MethodInfo, bool>) (x => x.ContainsGenericParameters)).MakeGenericMethod(typeof (T)).Invoke(androidJavaObject, new object[1]
  {
    (object) methodName
  });
}

It seems we are in the case described in https://docs.unity3d.com/Manual/ScriptingRestrictions.html#AOT with class AOTProblemExample.

The suggested fix is to force the compiler to generate the code by calling the wanted function with explicit type. Unfortunately, It's not particularly obvious in our case for what Type a Get should be generated AOT, and I鈥檓 not sure (not tried it yet) if it can be done outside of AWSSDK.Core.dll

It鈥檚 worth noting that the iOS version doesn鈥檛 do that kind of trickery and works in IL2CPP, and that AWS should make sure the sdk works on android/IL2CPP

Cheers!

Here is a workaround that I use works for my project.

Put below method in one of your GameObject, preferably with one that loads quite early on and in every scene.

    #if UNITY_ANDROID
    public void UsedOnlyForAOTCodeGeneration() {
        //Bug reported on github https://github.com/aws/aws-sdk-net/issues/477
        //IL2CPP restrictions: https://docs.unity3d.com/Manual/ScriptingRestrictions.html
        //Inspired workaround: https://docs.unity3d.com/ScriptReference/AndroidJavaObject.Get.html

        AndroidJavaObject jo = new AndroidJavaObject("android.os.Message");
        int valueString = jo.Get<int>("what");
    }
    #endif

Reopening as we want to fix this in the sdk

Thanks, it worked!

Thanks, the workaround is working for me.

Working for me too. Thanks!

The workaround also work for me too. (It still happening in the latest SDK 3.3.158.0)
Thanks.

Workaround valid still in Unity 2017.1.1f1 in SDK v3.3.1730

2yrs passed since reporting, never fixed.

bug is still around

Unity 2017.4 and SDK 3.3.423.0

Needed to add jo.Get<string> to workaround. (Atleast I think so)

Hi!

We're having issues with Unity 2019, the first one was this #1286 and a now we fix this current one, thank you for the workaround, I hope AWS fix the problem because is still happening.

Thank you!

Hello!

I tried your work around, i created a new script and then executed the function in the Awake(), i also set the script execution order to happen before the AWS initialization code. Now I'm getting this error.

07-22 08:54:44.939: E/Unity(23138): NullReferenceException: Object reference not set to an instance of an object. 07-22 08:54:44.939: E/Unity(23138): at Amazon.Runtime.Internal.UnityWebRequestWrapper..cctor () [0x00000] in <00000000000000000000000000000000>:0 07-22 08:54:44.939: E/Unity(23138): at Amazon.AWSConfigs.set_HttpClient (Amazon.AWSConfigs+HttpClientOption value) [0x00000] in <00000000000000000000000000000000>:0 07-22 08:54:44.939: E/Unity(23138): at AWSInterface.Start () [0x00000] in <00000000000000000000000000000000>:0 07-22 08:54:44.939: E/Unity(23138): Rethrow as TypeInitializationException: The type initializer for 'Amazon.Runtime.Internal.UnityWebRequestWrapper' threw an exception. 07-22 08:54:44.939: E/Unity(23138): at Amazon.AWSConfigs.set_HttpClient (Amazon.AWSConfigs+HttpClientOption value) [0x00000] in <00000000000000000000000000000000>:0 07-22 08:54:44.939: E/Unity(23138): at AWSInterface.Start () [0x00000] in <00000000000000000000000000000000>:0 07-22 08:54:44.939: E/Unity(23138): 07-22 08:54:44.939: E/Unity(23138): (Filename: currently not available on il2cpp Line: -1) 07-22 08:54:44.944: E/Unity(23138): Unable to find FirebaseCppApp-6.1.1 07-22 08:54:44.973: E/Unity(23138): DllNotFoundException: Unable to load DLL 'FirebaseCppApp-6.1.1': The specified module could not be found. 07-22 08:54:44.973: E/Unity(23138): at Firebase.AppUtilPINVOKE+SWIGExceptionHelper.SWIGRegisterExceptionCallbacks_AppUtil (Firebase.AppUtilPINVOKE+SWIGExceptionHelper+ExceptionDelegate applicationDelegate, Firebase.AppUtilPINVOKE

I guess the Firebase one is a consequence of the AWS error because in the editor i get no errors. Any help would be appreciated.

Note that you should not execute that method. Just create it and leave it there. And it should be only on android platform so that's why #if UNITY_ANDROID.

We needed both get and get it might be related to what features is used.

So current fix which works for us looks like this.

#if UNITY_ANDROID
    public void UsedOnlyForAOTCodeGeneration() {
        //Bug reported on github https://github.com/aws/aws-sdk-net/issues/477
        //IL2CPP restrictions: https://docs.unity3d.com/Manual/ScriptingRestrictions.html
        //Inspired workaround: https://docs.unity3d.com/ScriptReference/AndroidJavaObject.Get.html

        AndroidJavaObject jo = new AndroidJavaObject("android.os.Message");
        int valueString = jo.Get<int>("what");
                string stringValue = jo.Get<string>("what");
    }
    #endif

@Samhay Thanks for the quick replay. The workaround is still not working for me. I've been looking for more information about the error and according to this link: https://github.com/aws/aws-sdk-net/issues/701 the problem is with the dll. and since we have to build in 64 bits i think my only solution would be to modify the dll.

Confirming that this workaround still works in Unity 2018.4.4f1.

And, @mono26, in case you're still stuck, the AWSSDK.Core.dll currently presented for download in the is definitely still broken on Unity 2019.1 and later 2018.x builds (including LTS). The cause, as far as I can tell, is the addition of some Unity-side methods combined with this AWS SDK's dependence on reflection. (Boooo.)

The do-it-yourself recompiling fixes are outlined in the above-linked issue (#1286) and a pull request (#1295), but with any luck you can still use the DLL that @Roiw heroically uploaded right here.

The fixed DLL AND the IL2CPP fix in this thread seem to both be required right now to successfully build 64-bit Unity 2018+/AWS Android apps per Google's demands.

Hi all, I finally got it working. Just to be sure to prevent it from happening again soon, I upgraded my project to 2019.2.13f1 (from 2018.3) I built the latest AWSSDK (aws-sdk-net-3.3.637.0) (btw I had to change the default Unity path in GeneratorOptions.cs, compile and run the generator so it gets the good UnityEngine.dll there might be a better way, NuGet?, but still it worked) with the linq reflection fixes (https://github.com/aws/aws-sdk-net/pull/1295), and added UsedOnlyForAOTCodeGeneration (required). On my side I was also missing the link.xml file that is required when using IL2CPP. If anyone is interested in details I can help if needed, just contact me. Thank you everyone for your help here. I was starting to loose hope in publishing soon. Cheers!

Hi all, I finally got it working. Just to be sure to prevent it from happening again soon, I upgraded my project to 2019.2.13f1 (from 2018.3) I built the latest AWSSDK (aws-sdk-net-3.3.637.0) (btw I had to change the default Unity path in GeneratorOptions.cs, compile and run the generator so it gets the good UnityEngine.dll there might be a better way, NuGet?, but still it worked) with the linq reflection fixes (#1295), and added UsedOnlyForAOTCodeGeneration (required). On my side I was also missing the link.xml file that is required when using IL2CPP. If anyone is interested in details I can help if needed, just contact me. Thank you everyone for your help here. I was starting to loose hope in publishing soon. Cheers!

Hi
@SimonStHilaire there is no dll files created under bin folder.
I updated unity path as your answer.
GeneratorOptions.cs:
UnityPath = Path.Combine("C:\\", "Program Files", "Unity","Hub", "Editor", "2019.2.6f1");
And I followed these steps to build sdk:
https://forum.unity.com/threads/aws-works-in-unity-editor-but-not-after-built-on-android-phone.737141/#post-4922597

At the code generation step, program runs and exited normally but too many exception logs adding on VS console:

....
Exception thrown: 'System.ArgumentException' in System.dll
Exception thrown: 'System.ArgumentException' in System.dll
Exception thrown: 'System.ArgumentException' in System.dll
Exception thrown: 'System.ArgumentException' in System.dll
Exception thrown: 'System.ArgumentException' in System.dll
Exception thrown: 'System.ArgumentException' in System.dll
....

after that I've opened AWSSDK.Unity solution and build solution. It builds fine but there is no dll files created under bin directories.

VS output:
========== Build: 15 succeeded or up-to-date, 0 failed, 0 skipped ==========

Do you have any idea about that? Can something be wrong in the generation step?
I am using
Visual Studio Community 2019, Version 16.4.0

If you look at the build's output it should tell you where it generated the files. You might try to set the verbosity to Diagnostic.

thank you for quick reply. I changed MsBuild project build output verbosity to Diagnostic, unfortunately it does not write information about the file to be generated. Are you sure about it writes output files?

Have you compiled and run the generator? I had to do this prior to build so the files where copied at the right location.

I finally succeed!
dll files created when using the old version of Visual Studio. I used the Visual Studio 2017 for building AWSSDK.Unity solution. I hope it helps anyone.

@sefiktemel @SimonStHilaire
The AWS unity sdk is not working, is there a way to fix it, or link to a new sdk with instructions on how to impalement it?

I got the sdk from here
And get errors as seen here

I also replaced the AWSSDK.Core.DLL file, and it still wont work.

Please help, thank you very much.

@mono26 problem may exists in Assets/Resources/link.xml file....

compare your link.xml with this screenshot below...
basically i remove '.Experimental' from line (4) to (8) and it works for me....

full discussion at: https://github.com/aws/aws-sdk-net/issues/701

THANKS TO @lakrsv for tis solution

image

鈿狅笍COMMENT VISIBILITY WARNING鈿狅笍

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Was this page helpful?
0 / 5 - 0 ratings