Aws-sdk-net: UnityWebRequest failing on IL2CPP Android in Unity 2017.1.0f3

Created on 18 Jul 2017  路  20Comments  路  Source: aws/aws-sdk-net

Expected Behavior


UnityWebRequest static constructor should not throw exceptions.

Current Behavior





UnityWebRequest throws a null reference exception.

E/Unity: System.TypeInitializationException: The type initializer for 'Amazon.Runtime.Internal.UnityWebRequestWrapper' threw an exception. ---> System.NullReferenceException: A null value was found where an object instance was required. at Amazon.Runtime.Internal.UnityWebRequestWrapper..cctor () [0x00000] in <filename unknown>:0 at Amazon.AWSConfigs.set_HttpClient (HttpClientOption value) [0x00000] in <filename unknown>:0

The error is non-descriptive so I investigated. The error is thrown in the static constructor of UnityWebRequestWrapper at the line
PropertyInfo isErrorProperty = unityWebRequestType.GetProperty("isError");

The isError property is obsolete in Unity2017 and has been replaced with isNetworkError
https://docs.unity3d.com/2017.1/Documentation/ScriptReference/Networking.UnityWebRequest-isNetworkError.html

Possible Solution


In my own project I changed isError to isNetworkError in the UnityWebRequestWrapper, rebuilt the Core.dll and that resolved the issue. You could do something similar while also taking care of backwards compatibility.

Steps to Reproduce (for bugs)




In Unity 2017.1.0f3, create a Start() method with this content
UnityInitializer.AttachToGameObject(gameObject);
AWSConfigs.HttpClient = AWSConfigs.HttpClientOption.UnityWebRequest;

The AWSConfigs.HttpClient setter will call the static constructor of UnityWebRequestWrapper and you will get an exception if you're running IL2CPP Android.

Context


I was trying to upload data to an S3 bucket.

Your Environment

  • AWSSDK.Core version used: 3.3.124.0
  • Service assembly and version used:
  • Operating System and version: Windows 10 Home 64-Bit
  • Visual Studio version: Visual Studio Community 2017
  • Targeted .NET platform: 3.5
Unity bug modulunity

All 20 comments

I have the same problem, can you send me your dll with that fix ?

Yeah sure, I uploaded it here.
https://ufile.io/1gz8i

Just want to add that in general you should be wary of accepting .dll files compiled by strangers, you could easily download the project, apply the fix and build it yourself.

This is also not just and issue for Android but also iOS, basically anything using IL2CPP

@lakrsv Quick question, how did you rebuild your core dll? I'm trying to apply the fix to my project but VS won't build the solution.

@haswalt When you've downloaded the project, open sdk/AWSSDK.Unity.sln, in WebRequestWrapper, in the static constructor, change the line PropertyInfo isErrorProperty = unityWebRequestType.GetProperty("isError"); to PropertyInfo isErrorProperty = unityWebRequestType.GetProperty("isNetworkError");,

Change your solution to the release variant, right-click the project folder in the solution explorer and build it.

You'll find the AWSSDK.Core.dll in the build folder

Cheers!

@lakrsv Thank you for running with the application built with macOS + Unity 20171.0.f3.

@lakrsv The bugfix works for Android but it seems that replacing DLL did not work for iOS. Same problem persists

@infernova What error are you getting? Did you verify that it does indeed work correctly on Android, but not on iOS?

@lakrsv Apologies for the false alarm. It worked for Android on Mono but it still didn't work for Android IL2CPP. Will look into what's going wrong on the DLL side as it seems that replacing the DLL isn't fixing it

@infernova It works fine for me with both Mono and IL2CPP, so if you made the same changes to the DLL as I have listed above, your problem shouldn't be related to the DLL.

Do you have an error message?

@lakrsv On Android IL2CPP

NullReferenceException: A null value was found where an object instance was required.
08-23 15:08:26.821 25445 25473 I Unity : at Amazon.Runtime.Internal.UnityWebRequestWrapper..cctor () [0x00000] in :0
08-23 15:08:26.821 25445 25473 I Unity : at Amazon.AWSConfigs.set_HttpClient (HttpClientOption value) [0x00000] in :0
08-23 15:08:26.821 25445 25473 I Unity : at AwsMgr.Init () [0x00000] in :0
08-23 15:08:26.821 25445 25473 I Unity : Rethrow as TypeInitializationException: The type initializer for 'Amazon.Runtime.Internal.UnityWebRequestWrapper' threw an exception.
08-23 15:08:26.821 25445 25473 I Unity : at Amazon.AWSConfigs.set_HttpClient (HttpClientOption value) [0x00000] in :0
08-23 15:08:26.821 25445 25473 I Unity : at AwsMgr.Init () [0x00000] in :0
08-23 15:08:26.821 25445 25473 I Unity : at
08-23 15:08:28.004 25445 25514 E Unity : java.io.EOFException
08-23 15:08:28.004 25445 25514 E Unity :
08-23 15:08:28.004 25445 25514 E Unity : (Filename: Line: 393)

And on iOS IL2CPP

NullReferenceException: A null value was found where an object instance was required.
at Amazon.Runtime.Internal.UnityWebRequestWrapper..ctor () [0x00000] in :0
at Amazon.AWSConfigs.set_HttpClient (HttpClientOption value) [0x00000] in :0
at AwsMgr.Init () [0x00000] in :0
Rethrow as TypeInitializationException: The type initializer for 'Amazon.Runtime.Internal.UnityWebRequestWrapper' threw an exception.
at Amazon.AWSConfigs.set_HttpClient (HttpClientOption value) [0x00000] in :0
at AwsMgr.Init () [0x00000] in :0

I tried both generating my own DLL using VS based on the instruction you provided as well as directly using the zipped DLL provided and neither worked. Adding a backwards compatibility bracket to fall back on using PropertyInfo isErrorProperty = unityWebRequestType.GetProperty("isError"); if PropertyInfo isErrorProperty = unityWebRequestType.GetProperty("isNetworkError"); is null also failed to produce any successful results.

To also make it extra clear, I replaced the DLL found in the default location which is at Assets/AWSSDK/AWSSDK.Core.dll so unless there is some other location which the DLL is sitting/getting cached, I'm rather stumped at what seems to be going wrong.

@infernova Thanks for the details. Can you provide me with a sample of the code that produces this issue?

@infernova Can you put below couple lines of debug in UnityWebRequestWrapper to check whether some of the method is missing in UnityWebRequest. In my case for 2017.1.0f3 the AWS code has trouble getting the property downloadProgress from UnityWebRequest.

Debug.Log ("downloadHandlerProperty is null=" + (downloadHandlerProperty == null));
Debug.Log ("downloadProgressProperty is null=" + (downloadProgressProperty == null));

If this is not the case, you may have to put more debug in to see which property is missing.

This affects my Android IL2CPP build but not mono.
It seems the IL2CPP build process stripped out too much code.
I "guess" the downloadProgress method is missing/stripped in the generated dll
...\Temp\StagingArea\Il2Cpp\Managed\UnityEngine.dll

There are two workarounds:

1) commented out all code in UnityWebRequestWrapper that reference downloadProgress. This include the call to
GetProperty("downloadProgress")
downloadProgressGetMethod = downloadProgressProperty.GetGetMethod();
The entire public float DownloadProgress

2) Option two is to reference the UnityWebRequest.downloadProgress to trick whatever stripping the code to think it is still needed. I cannot see an option in Player Settings as Managed code stripping is always on for IL2Cpp

I am not sure how this can be fixed properly as AWS Core use reflection to wrap UnityWebRequest. Option 2 is nicer when the isError problem is fixed

Check the link.xml file to see if it is using the wrong assemblies. See @infernov and @lakrsv comments below

@lakrsv the code I'm using is pretty much

public void Init ()
{
   UnityInitializer.AttachToGameObject(this.gameObject);
   Amazon.AWSConfigs.HttpClient = Amazon.AWSConfigs.HttpClientOption.UnityWebRequest;
   AssignUserId();
   CheckGifts();
   CheckTime();
}

The last three helper fuctions don't really matter because the function crashes out at the second line.

@infernova

Can you create a file in Assets/Resources called link.xml and place this code in it: https://pastebin.com/HZn86hN6

Let me know how that works for you

@lakrsv Fixing the link.xml file worked. When I was editing the file, I realised that previously I had the "UnityEngine.Experimental.Networking.xxx" assemblies preserved instead of the "UnityEngine.Networking.xxx" assemblies which probably caused the stripping problem that @nzmkey highlighted above. Removing the "Experimental" bit helped tell Unity to preserve the correct assemblies.

@infernova That's what I suspected. Glad it's working for you now!

Looks like my link.xml has the wrong networking assembiles too. Updated the link.xml works without my dirty hack.

https://github.com/aws/aws-sdk-net/pull/709 pull request was accepted and pushed out that addresses the isError property issue.

Any chance someone could re-upload the fix? https://ufile.io/1gz8i is no longer open to free users.

Thanks!

@jbudning this has been fixed in the sdk now so you should be using the download from AWS.

Was this page helpful?
0 / 5 - 0 ratings