I have an application that was built in UWP. When I test the app on Debug mode, it works very well, but when I change to Release, the app stop working.
The error is:
**System.Reflection.MissingMetadataException:** 'This operation cannot be carried out because metadata for the following object was removed for performance reasons:\n\n EETypeRva:0x000AF350\n\nNo further information is available. Rebuild in debug mode for better information.\n\n'
It says that I have to run it in the Debug mode. But in Debug mode, everything is working.
@albertomandlate can you share a repro or call stack of the failure here?
I suspect you are using the serializer and it鈥檚 failing to do runtime reflection or code generation. /cc @steveharter
@albertomandlate sorry to hear it's causing you issues. As Eric mentioned, getting more information will be quite helpful for getting to a resolution (workaround/compiler fix etc).
If you're able to share an ilcRepro file with me, that's the most robust way to make sure I'm investigating exactly the issue you're reporting.
This is the error message:
System.Reflection.MissingMetadataException: 'This operation cannot be carried out because metadata for the following object was removed for performance reasons:\n\n EETypeRva:0x000AF350\n\nNo further information is available. Rebuild in debug mode for better information.\n\n'
Ah, that's the .NET Native runtime trying to inform you that some types/properties etc have been incorrectly optimized away. You should get a better diagnostic message if you put the project in DEBUG config but turn on .NET Native (project properties > build > Enable .NET Native). I would expect the exception to have much more actionable type information in that configuration.
Once we know what's being optimized away it's relatively straight forward to write hints to the compiler that those members shouldn't be eliminated. You can do this by adding info into your Properties\Default.rd.xml file.
Something like:
<Type Name="Some.Type.We.Want.To.Save" Dynamic="Required All />
It may require a few iterations and can be helped if you know things about how System.Text.Json but it's also possible that it's completely straight forward. Either way, it would be great to know what tweaks get you back to running, it's entirely possible we should be adding some of that info to the library directly.
Always happy to take a look if you have a project or ilcRepro to share but hopefully you'll be able to make some progress.
Docs worth at least skimming to get the idea:
Yes, it worked.
I need to put every JsonConverter type that I use. In my case:
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterString" Dynamic="Required All" />
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterUri" Dynamic="Required All" />
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterBoolean" Dynamic="Required All" />
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterInt32" Dynamic="Required All" />
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterInt16" Dynamic="Required All" />
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterByte" Dynamic="Required All" />
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterDecimal" Dynamic="Required All" />
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterGuid" Dynamic="Required All" />
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterEnum" Dynamic="Required All" />
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterDateTime" Dynamic="Required All" />
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterDateTimeOffset" Dynamic="Required All" />
In the future, are we going to have .NET Native support? I'm asking that, because it worked in the old version.
@MattWhilden are the runtime directives needed if the [PreserveDependency] attribute is used for those types? That way the framework can declare to keep the metadata instead of consumers having to add to the rd.xml.
@steveharter The .NET Native tools predate that attribute so have no knowledge of it. However, I suspect it would be pretty straight forward to add this functionality (see: AttributeImplies in the rd.xml spec). Let me poke around and see if it's as easy as I suspect.
@albertomandlate Glad you're back on track. Can you help me understand what you mean by "old version"? Also, it may future proof things a bit better if you modify your directives to be for the entire namespace but if you're happy with what you've got then that's good too. Something like:
<Namespace Name="System.Text.Json.Serialization.Converters" Dynamic="Required All"/>
Ok. Modifying the rd file, it work fine. But you have to discover each time the one of the classes are used in your project.
For example, in my project, there are places that I use just string. So the first time when I see the error message, shows me that the problem was with the System.Text.Json.Serialization.Converters.JsonConverterString
class.
But you can imagine that I don't use just string on my objects all over the project. So it gives me that message each for each different type object. + time VS Compiling in .NET Native, I took about a hour to solve this problem.
Sorry, and then I discover that in some places of my project I need to change from Windows.Web... HttpClient to System.Net..... HttpClient, because I was getting error when calling the PutAsync method of Windows.Web... namespaces...
My problem is, if I test something on Debug mode, it must work on Release, because I really don't have time to test (without using Test project) everything in my project, because I can have a problem with .NET Native option, etc. etc.
I don't know if you get me?
@steveharter The .NET Native tools predate that attribute so have no knowledge of it. However, I suspect it would be pretty straight forward to add this functionality (see: AttributeImplies in the rd.xml spec). Let me poke around and see if it's as easy as I suspect.
@albertomandlate Glad you're back on track. Can you help me understand what you mean by "old version"? Also, it may future proof things a bit better if you modify your directives to be for the entire namespace but if you're happy with what you've got then that's good too. Something like:
<Namespace Name="System.Text.Json.Serialization.Converters" Dynamic="Required All"/>
So, old version I mean 4.6.0 of System.Text.Json, Release was working without needing any change.
Got it. Breaks between RELEASE and DEBUG are super painful which is why we try to address them quickly. Unfortunately, there's hard trade offs between guaranteeing functionality, compile time, size of resulting artifacts etc. That said, this should be a pretty easy library fix on our side to get everyone patched back up.
I'm not familiar enough with the happenings in that namespace between 4.6 and now to comment about which things caused us to no longer be able to track what's going on. Perhaps @steveharter has more clarity.
@steveharter it seems like that attribute is still in design flux. We may wish to have a "belt and suspenders" approach where we add a library directive for this namespace AND tell the .NET Native compiler about the attribute in question. Hmmm.
Returning to this. We should figure out what a better out of box experience here would be. I see two options:
I don't have a strong preference but we're locking down the next .NET Native version in a few weeks. I suspect the first bullet is the more general/complete solution but adding library rd.xml files to the compiler is likely the fastest way for customers to get patched up.
Returning to this. We should figure out what a better out of box experience here would be. I see two options:
- Teach the .NET Native compiler about dependency attribute and use that here
- Add rd.xml files for Json types to the library package or the compiler
I don't have a strong preference but we're locking down the next .NET Native version in a few weeks. I suspect the first bullet is the more general/complete solution but adding library rd.xml files to the compiler is likely the fastest way for customers to get patched up.
I prefer the 1st one.
@stephentoub Do you know what the current story around DependencyAttribute is?
@MattWhilden, you mean PreserveDependencyAttribute? The current story is that it's recognized by the linker but it's still a work-in-progress. We've been using it successfully in dotnet/runtime now, but it also has limitations. My expectation is we'll flesh out the design for .NET 5 and expose one or more attributes to help enable these scenarios, and I expect PreserveDependencyAttribute to be part of that, though hopefully with a different name.
cc: @marek-safar
@MattWhilden to clarify, is there a current work-around to this issue to let UWP apps ship in the store with a reference to System.Text.Json
or is this scenario currently blocked?
You can use an rd.xml file to keep whatever type metadata you need. @MattWhilden gave a minimal sample here: https://github.com/dotnet/runtime/issues/978#issuecomment-567607904.
Yep I expect that to work well. Previously even RD.xml didn't wouldn't work as they were marked with ReflectionBlock attribute.
@MattWhilden assume as this is still open and it wasn't called out in release notes, that there's no fix in the latest .NET Native release?
Cool, looks like this was added to a release milestone. 馃帀 When is 5.0 scheduled, is there an ETA now? Thanks!
Most helpful comment
Yes, it worked.
I need to put every JsonConverter type that I use. In my case:
In the future, are we going to have .NET Native support? I'm asking that, because it worked in the old version.