Bug 17910 - System.Reflection.ReflectionTypeLoadException when trying to load Castle.Core
Summary: System.Reflection.ReflectionTypeLoadException when trying to load Castle.Core
Status: RESOLVED NORESPONSE
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 7.1.0.x
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-02-20 11:15 UTC by Stephen Shaw
Modified: 2017-02-07 10:53 UTC (History)
6 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Test Case solution/project (240.16 KB, application/zip)
2014-02-20 11:16 UTC, Stephen Shaw
Details
New Test Case Solution (6.07 MB, application/zip)
2014-02-24 18:28 UTC, Stephen Shaw
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED NORESPONSE

Description Stephen Shaw 2014-02-20 11:15:32 UTC
I'm trying to get the Moq testing framework to work with iOS. It restricts the unit testing to the simulator, but makes mocking on a legacy code base much easier. I've rebuilt the dlls as monotouch libraries but get an exception when trying to load Castle.Core:

(I've included a test case for this)


Starting iOS simulator 7.0
Launching application
Application launched. PID = 94436
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll [External]
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.Core.dll [External]
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.dll [External]
Thread started:  #2
Loaded assembly: /Users/sgshaw/Projects/MoqMobileTest/MoqMobileTest/bin/iPhoneSimulator/Debug/MoqMobileTest.exe
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/MonoTouch.NUnitLite.dll [External]
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.Xml.dll [External]
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/MonoTouch.Dialog-1.dll [External]
Loaded assembly: /Developer/MonoTouch/usr/lib/mono/2.1/System.Json.dll [External]
Loaded assembly: /Users/sgshaw/Projects/MoqMobileTest/libs/Moq.dll [External]
Loaded assembly: /Users/sgshaw/Projects/MoqMobileTest/libs/Castle.Core.dll [External]
2014-02-20 09:15:06.560 MoqMobileTest[94436:80b] Could not load 'Castle.Core' for registration: System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
  at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (System.Reflection.Assembly,bool)
  at System.Reflection.Assembly.GetTypes () [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/Assembly.cs:351 
  at MonoTouch.Registrar.OldDynamicRegistrar.RegisterAssembly (System.Reflection.Assembly a) [0x00000] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/OldDynamicRegistrar.cs:67 
2014-02-20 09:15:06.563 MoqMobileTest[94436:80b] This could be due to an outdated assembly kept by the simulator, location: /Users/sgshaw/Projects/MoqMobileTest/libs/Castle.Core.dll
Thread started: <Thread Pool> #3
Thread started: <Thread Pool> #4
2014-02-20 09:15:08.129 MoqMobileTest[94436:80b] [Runner executing:	Run Everything]
2014-02-20 09:15:08.130 MoqMobileTest[94436:80b] [MonoTouch Version:	7.0.7]
2014-02-20 09:15:08.131 MoqMobileTest[94436:80b] [iPad Simulator:	iPhone OS v7.0.3]
2014-02-20 09:15:08.132 MoqMobileTest[94436:80b] [Device Name:	iPad Simulator]
2014-02-20 09:15:08.133 MoqMobileTest[94436:80b] [Device UDID:	FFFFFFFF3D806BE653994F3FB3636DFD9FFA5AD2]
2014-02-20 09:15:08.135 MoqMobileTest[94436:80b] [Device Locale:	en_US]
2014-02-20 09:15:08.142 MoqMobileTest[94436:80b] [Device Date/Time:	2/20/2014 9:15:08 AM]
2014-02-20 09:15:08.142 MoqMobileTest[94436:80b] [Bundle:	com.your-company.MoqMobileTest]
2014-02-20 09:15:08.150 MoqMobileTest[94436:80b] MoqMobileTest
2014-02-20 09:15:08.150 MoqMobileTest[94436:80b] Tests
2014-02-20 09:15:08.165 MoqMobileTest[94436:80b] 	[FAIL] CreateMyClass : System.TypeInitializationException : An exception was thrown by the type initializer for Moq.Mock`1
  ----> System.TypeInitializationException : An exception was thrown by the type initializer for Moq.Proxy.CastleProxyFactory
  ----> System.TypeLoadException : Could not load type 'Castle.DynamicProxy.ModuleScope' from assembly 'Castle.Core, Version=3.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc'.
2014-02-20 09:15:08.166 MoqMobileTest[94436:80b] 		  at MoqMobileTest.Tests.CreateMyClass () [0x00016] in /Users/sgshaw/Projects/MoqMobileTest/MoqMobileTest/Tests.cs:33 
2014-02-20 09:15:08.166 MoqMobileTest[94436:80b] 		  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
2014-02-20 09:15:08.167 MoqMobileTest[94436:80b] 		  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00044] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:230 
2014-02-20 09:15:08.167 MoqMobileTest[94436:80b] 		--TypeInitializationException
2014-02-20 09:15:08.167 MoqMobileTest[94436:80b] 		  at Moq.Mock`1[MoqMobileTest.MyClass]..cctor () [0x00000] in <filename unknown>:0 
2014-02-20 09:15:08.168 MoqMobileTest[94436:80b] 		--TypeLoadException
2014-02-20 09:15:08.168 MoqMobileTest[94436:80b] 		  at Castle.DynamicProxy.ProxyGenerator..ctor () [0x00000] in <filename unknown>:0 
2014-02-20 09:15:08.169 MoqMobileTest[94436:80b] 		  at Moq.Proxy.CastleProxyFactory.CreateProxyGenerator () [0x00000] in <filename unknown>:0 
2014-02-20 09:15:08.169 MoqMobileTest[94436:80b] 		  at Moq.Proxy.CastleProxyFactory..cctor () [0x00000] in <filename unknown>:0 
2014-02-20 09:15:08.175 MoqMobileTest[94436:80b] 	[FAIL] Fail :   Expected: False
  But was:  True
2014-02-20 09:15:08.176 MoqMobileTest[94436:80b] 		  at MoqMobileTest.Tests.Fail () [0x00002] in /Users/sgshaw/Projects/MoqMobileTest/MoqMobileTest/Tests.cs:20 
2014-02-20 09:15:08.176 MoqMobileTest[94436:80b] 		  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
2014-02-20 09:15:08.176 MoqMobileTest[94436:80b] 		  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00044] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:230 
2014-02-20 09:15:08.178 MoqMobileTest[94436:80b] 	[IGNORED] Ignore : another time
2014-02-20 09:15:08.181 MoqMobileTest[94436:80b] 	[PASS] Pass
2014-02-20 09:15:08.182 MoqMobileTest[94436:80b] Tests : 31 ms
2014-02-20 09:15:08.185 MoqMobileTest[94436:80b] MoqMobileTest : 32 ms
2014-02-20 09:15:08.185 MoqMobileTest[94436:80b] Tests run: 3 Passed: 1 Inconclusive: 0 Failed: 2 Ignored: 1
2014-02-20 09:15:10.935 MoqMobileTest[94436:80b] [Runner executing:	MoqMobileTest.Tests.CreateMyClass]
2014-02-20 09:15:10.935 MoqMobileTest[94436:80b] [MonoTouch Version:	7.0.7]
2014-02-20 09:15:10.936 MoqMobileTest[94436:80b] [iPad Simulator:	iPhone OS v7.0.3]
2014-02-20 09:15:10.936 MoqMobileTest[94436:80b] [Device Name:	iPad Simulator]
2014-02-20 09:15:10.937 MoqMobileTest[94436:80b] [Device UDID:	FFFFFFFF3D806BE653994F3FB3636DFD9FFA5AD2]
2014-02-20 09:15:10.937 MoqMobileTest[94436:80b] [Device Locale:	en_US]
2014-02-20 09:15:10.938 MoqMobileTest[94436:80b] [Device Date/Time:	2/20/2014 9:15:10 AM]
2014-02-20 09:15:10.938 MoqMobileTest[94436:80b] [Bundle:	com.your-company.MoqMobileTest]
2014-02-20 09:15:10.942 MoqMobileTest[94436:80b] 	[FAIL] CreateMyClass : System.TypeInitializationException : An exception was thrown by the type initializer for Moq.Mock`1
  ----> System.TypeInitializationException : An exception was thrown by the type initializer for Moq.Proxy.CastleProxyFactory
  ----> System.TypeLoadException : Could not load type 'Castle.DynamicProxy.ModuleScope' from assembly 'Castle.Core, Version=3.2.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc'.
2014-02-20 09:15:10.943 MoqMobileTest[94436:80b] 		  at MoqMobileTest.Tests.CreateMyClass () [0x00016] in /Users/sgshaw/Projects/MoqMobileTest/MoqMobileTest/Tests.cs:33 
2014-02-20 09:15:10.943 MoqMobileTest[94436:80b] 		  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
2014-02-20 09:15:10.944 MoqMobileTest[94436:80b] 		  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00044] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:230 
2014-02-20 09:15:10.944 MoqMobileTest[94436:80b] 		--TypeInitializationException
2014-02-20 09:15:10.944 MoqMobileTest[94436:80b] 		  at Moq.Mock`1[MoqMobileTest.MyClass]..cctor () [0x00000] in <filename unknown>:0 
2014-02-20 09:15:10.945 MoqMobileTest[94436:80b] 		--TypeLoadException
2014-02-20 09:15:10.945 MoqMobileTest[94436:80b] 		  at Castle.DynamicProxy.ProxyGenerator..ctor () [0x00000] in <filename unknown>:0 
2014-02-20 09:15:10.946 MoqMobileTest[94436:80b] 		  at Moq.Proxy.CastleProxyFactory.CreateProxyGenerator () [0x00000] in <filename unknown>:0 
2014-02-20 09:15:10.946 MoqMobileTest[94436:80b] 		  at Moq.Proxy.CastleProxyFactory..cctor () [0x00000] in <filename unknown>:0 
2014-02-20 09:15:10.949 MoqMobileTest[94436:80b] Tests run: 1 Passed: 0 Inconclusive: 0 Failed: 1 Ignored: 0
Comment 1 Stephen Shaw 2014-02-20 11:16:39 UTC
Created attachment 6100 [details]
Test Case solution/project
Comment 2 Stephen Shaw 2014-02-20 11:21:06 UTC
I built Castle.Core as a monotouch library using xbuild. The only code I changed in Castle.Core was removing 2 files that required System.Configuration.

https://github.com/castleproject/Core
https://github.com/Moq/moq4

I built off the latest tagged releases of both
Comment 3 Rolf Bjarne Kvinge [MSFT] 2014-02-20 16:47:40 UTC
Exactly how did you build Castle.Core as a monotouch library? In the solution in comment 1 both Castle.Core.dll and Moq.dll reference the desktop versions of mscorlib.dll, System.dll and System.Core.dll - this won't work because the API is different between the desktop versions and the mobile versions Xamarin.iOS use.
Comment 4 Stephen Shaw 2014-02-20 17:01:07 UTC
I tried to cheat the system and I think I messed up my build. I've been looking at it more throughout the day.

I try to copy some stuff into the csproj file, but that clearly causes problems. I'm working on recreating the projects from scratch.
Comment 5 Stephen Shaw 2014-02-20 17:01:15 UTC
I tried to cheat the system and I think I messed up my build. I've been looking at it more throughout the day.

I try to copy some stuff into the csproj file, but that clearly causes problems. I'm working on recreating the projects from scratch.
Comment 6 Stephen Shaw 2014-02-20 17:09:07 UTC
Rebuilding it with clean iOS library projects I'm running into the problem of System.Reflection.Emit missing.

Looking at the mono code, am I missing something? or is there a version out there that has reflection?

https://gist.github.com/decriptor/9121075
Comment 7 Stephen Shaw 2014-02-20 17:15:51 UTC
ok, looks like there are 2 mscorlib.dlls:

sgshaw@sgshaw_pro:/Developer/MonoTouch $ find . -iname mscorlib.dll*
./usr/lib/mono/2.1/mscorlib.dll
./usr/lib/mono/2.1/mscorlib.dll.mdb
./usr/lib/mono/2.1/repl/mscorlib.dll
./usr/lib/mono/2.1/repl/mscorlib.dll.mdb

the repl/mscorlib.dll has the System.Reflection.Emit in it. So, I just need to build against that version
Comment 8 Rolf Bjarne Kvinge [MSFT] 2014-02-20 17:20:34 UTC
There is no supported version of mscorlib for MonoTouch that has System.Reflection.Emit (System.Reflection.Emit is in fact on the list of MonoTouch limitations: http://docs.xamarin.com/guides/ios/advanced_topics/limitations/)

You may try to use the repl version, but it's not supposed to be used by users directly, so it might end up removed/renamed without warning in the future.
Comment 9 Stephen Shaw 2014-02-20 17:55:09 UTC
I've read the restrictions. The goal was to use some mocking framework to do unit testing. Since we are using calabash for our component/integration tests we decided it would be ok if our unit tests were restricted to the simulator.

What would be the best way to try and use the repl version of mscorlib in an iOS library project? I don't want to affect my apps build just these libraries (Moq and Castle.Core) and running my test project (which I can do that through --enable-repl)
Comment 10 Sebastien Pouliot 2014-02-20 19:38:12 UTC
[10:32:36]  <sshaw>	 I've rebuilt Castle.Core and Moq as monotouch libraries

unlike mentioned on IRC (but like Rolf mentioned above) the assemblies were not compiled as monotouch assemblies. E.g. Castle.Core even reference System.Configuration.dll

// mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

Now it's possible by (ab)using REPL support that you might be able to use* those assemblies.

* but that won't be supported feature

Your first step is to re-build those two assemblies to refer to XI supplied SDK assemblies (or a compatible PCL subset). That should not be too hard since Moq is compatible with Silverlight.

Once this is done we can have a quick look if there's any crash/exception (just attach an updated test case). Even unsupported this could prove useful for many people so I'd be happy to help.
Comment 11 Stephen Shaw 2014-02-20 19:43:07 UTC
I made several attempts and must of messed something up along the way.

So far I created a new iOS library project and told it to not build with mscorlib.dll and manually added a reference to the mscorlib.dll under the repl directory. After removing System.Configuration, removing a couple files that needed System.Configuration, and commenting out a line of code I was able to get Castle.Core.csproj to build. There are other projects in there that I'll pick up tomorrow.

Once I have that sorted out I'll test this again and post a test case.
Comment 12 Stephen Shaw 2014-02-21 11:18:58 UTC
ok, I've created a new dll for Castle.Core http://www.decriptor.com/dl/moq/Castle.Core.dll that should be correct now.

I've started on the Moq library, but ran into about 17 errors. Looks like they are largely in the System.Linq.Expression library (System.Core)?

Looking at the mono code it looks like there is a bunch of stuff commented out with #if !FULL_AOT_RUNTIME

sgshaw@sgshaw_pro:~/code/mono/mcs/class/System.Core/System.Linq.Expressions (git:master)$ grep -r FULL_AOT_RUNTIME *
BinaryExpression.cs:#if !FULL_AOT_RUNTIME
BinaryExpression.cs:#if !FULL_AOT_RUNTIME
ConditionalExpression.cs:#if !FULL_AOT_RUNTIME
ConditionalExpression.cs:#if !FULL_AOT_RUNTIME
ConstantExpression.cs:#if !FULL_AOT_RUNTIME
ConstantExpression.cs:#if !FULL_AOT_RUNTIME
ElementInit.cs:#if !FULL_AOT_RUNTIME
ElementInit.cs:#if !FULL_AOT_RUNTIME
EmitContext.cs:#if !FULL_AOT_RUNTIME
Expression.cs:#if !FULL_AOT_RUNTIME
Expression.cs:#if !FULL_AOT_RUNTIME
ExpressionVisitor.cs:#if FULL_AOT_RUNTIME
Extensions.cs:#if !FULL_AOT_RUNTIME
InvocationExpression.cs:#if !FULL_AOT_RUNTIME
LambdaExpression.cs:#if !FULL_AOT_RUNTIME
LambdaExpression.cs:#if !FULL_AOT_RUNTIME
LambdaExpression.cs:#if FULL_AOT_RUNTIME
LambdaExpression.cs:#if FULL_AOT_RUNTIME
ListInitExpression.cs:#if !FULL_AOT_RUNTIME
MemberAssignment.cs:#if !FULL_AOT_RUNTIME
MemberAssignment.cs:#if !FULL_AOT_RUNTIME
MemberBinding.cs:#if !FULL_AOT_RUNTIME
MemberBinding.cs:#if !FULL_AOT_RUNTIME
MemberExpression.cs:#if !FULL_AOT_RUNTIME
MemberExpression.cs:#if !FULL_AOT_RUNTIME
MemberInitExpression.cs:#if !FULL_AOT_RUNTIME
MemberListBinding.cs:#if !FULL_AOT_RUNTIME
MemberListBinding.cs:#if !FULL_AOT_RUNTIME
MemberMemberBinding.cs:#if !FULL_AOT_RUNTIME
MemberMemberBinding.cs:#if !FULL_AOT_RUNTIME
MethodCallExpression.cs:#if !FULL_AOT_RUNTIME
MethodCallExpression.cs:#if !FULL_AOT_RUNTIME
NewArrayExpression.cs:#if !FULL_AOT_RUNTIME
NewArrayExpression.cs:#if !FULL_AOT_RUNTIME
NewExpression.cs:#if !FULL_AOT_RUNTIME
NewExpression.cs:#if !FULL_AOT_RUNTIME
ParameterExpression.cs:#if !FULL_AOT_RUNTIME
ParameterExpression.cs:#if !FULL_AOT_RUNTIME
TypeBinaryExpression.cs:#if !FULL_AOT_RUNTIME
TypeBinaryExpression.cs:#if !FULL_AOT_RUNTIME
UnaryExpression.cs:#if !FULL_AOT_RUNTIME
UnaryExpression.cs:#if !FULL_AOT_RUNTIME


I'm wondering if something as simple as adding something like #if !FULL_AOT_RUNTIME || IOS_REFLECTION (System.Reflection.Emit) would fix this.

Since this is in System.Core and not mscorlib I'm not sure the best way to do this. If simply adding IOS_REFLECTION to the list of files above I can do that and do a pull request, but since the install puts the mscorlib.dll in the repl folder is there extra magic that I'm missing?
Comment 13 Sebastien Pouliot 2014-02-24 09:08:16 UTC
The version of SLE shipped with XI will be updated soon (and the API will be closer to the regular FX). That might help you with the compile time errors you're seeing.

However it's still a special version of SLE that works without code generation. IOW we won't be shipping a version that does code generation (that would only cause trouble when people move their code to devices). The goal of "repl" is REPL, not reduced compatibility

The alternative is for you to modify Moq to use the existing API. It's hard to say how much work that would be (but 17 errors does not look so bad). Still you might want to wait for the updated version to decide.
Comment 14 Stephen Shaw 2014-02-24 11:44:04 UTC
I'm not sure I understand the repl stuff. Just by added SRE doesn't that mean you can't run it on a physical device?

Looking at these errors they are all caused by the lack of SLE (https://gist.github.com/decriptor/9191845). I changed the build action on them to 'None', but just found more errors. It looks like SLE is referenced in 34 files. I'm not sure I could redo this to avoid using SLE.

When is the update supposed to come out? Is it tied to iOS 7.1? Or something I can maybe get a couple of now to try out?
Comment 23 Stephen Shaw 2014-02-24 18:25:59 UTC
Ok, I've created a newer test case solution that includes my Castle.Core and Moq4 projects. I copied the mscorlib.dll from the repl directory and manually included it in everything and told the projects to not reference it (Properties -> Build -> General).


Here is my output -> https://gist.github.com/decriptor/9199409

This is also without --enable-repl which I seems to crash (comment 22), so I was trying to get around that by including the repl/mscorlib.dll assembly.
Comment 29 Sebastien Pouliot 2017-01-05 15:10:57 UTC
@Stephen a lot of the BCL changed since then, do you still have that code (and are you interested in getting it to work) ?
Comment 30 Manuel de la Peña [MSFT] 2017-02-07 10:53:24 UTC
@Stephen if you are still experiencing this issue please let us know and re-open the bug report. Thanks!