Deployment: NHibernate XML serializer assembly
I have a C# 3.5 application that is using Fluent NHibernate 1.1 which runs perfectly on a development machine. As the application starts, in the output window I can see a number of dynamically generated assemblies loaded to support the XmlSerializer. When this application is deployed to a production environment however the fusion log indicates that there is a missing assembly: NHibernate.XmlSerializers.dll. Assigning an event handler to the AssemblyResolve event on the AppDomain instance, I see the call stack for this assembly load originating in the configuration of Fluent, which calls methods in the NHibernate assembly which in turn requires the deserialization of an XML persisted object. I was under the impression that using Fluent eliminated the need for XML configuration files so why would the library still be attempting to load such configuration file?
I've tried a number of things to resolve this including (1) using sgen.exe to precompile the missing library however this results in type errors and/or strong name issues, (2) manually creating an assembly that contains the required classes (which can be obtained by changing the XML serialization diagnostics settings in the app.config) however this results in a public key mismatch between the assemblies, presumably because NHibernate.dll has a strong name and the new assembly doesn't (or won't have one that matches the one that is referenced) and finally (3) obtaining the dynamically compiled assembly (again using the XML serialization diagnostics settings) and manually referencing it. Unfortunately the last attempt is the only one that might work (I still have to verify it) however I'm unable to give the assembly a more descriptive name (you can't just rename an assembly) so I will have to reference one called something like "eu3fm4nx.dll" which is most certainly not ideal.
The bottom line is: how do you actually deploy Fluent NHibernate without running into these XmlSerializer issues?
Support Staff 2 Posted by James Gregory on 29 Jun, 2010 10:43 AM
No, fluent eliminates the need for you to write XML configuration.
That missing XML serializer assembly you're seeing is normal NHibernate behaviour. It's caught internally in the NH stack and handled. There is no issue, as far as I know; just ignore it.
3 Posted by Steven on 29 Jun, 2010 10:47 AM
I've read in a number of places that this is "normal behaviour" however an application that doesn't start when deployed to production isn't normal.
Is there a way that I don't know of to run an application that has missing assemblies?
4 Posted by mirapalheta on 29 Jun, 2010 10:53 AM
I think there is no way to configure a session without the xml files (I may
be wrong). In fact what Fluent NHibernate does is generate the hbm files for
you and pass it to nhibernate to build the session factory.
Best regards,
Daniel Mirapalheta
2010/6/29 Steven Visagie <
tender+dec05ceb168c8ba45ea2ef75fbf35128aefd333ec@tenderapp.com<tender%2Bdec05ceb168c8ba45ea2ef75fbf35128aefd333ec@tenderapp.com>
>
Support Staff 5 Posted by James Gregory on 29 Jun, 2010 10:58 AM
I suspect you may have other issues then. The assembly isn't missing in the traditional sense of an unresolved reference. The XML serializers assembly is loaded dynamically by NHibernate, it isn't a hard assembly reference, and if it isn't found NHibernate continues without it. This is how NHibernate has worked for a very long time.
6 Posted by Steven on 29 Jun, 2010 11:12 AM
Fair enough. I have also encountered this issue with other XML serialization I'm performing of one of my own classes (unrelated to the NHibernate implementation) which I resolved by using sgen against the assembly that contained the persisted class. The output of this process was an *.XmlSerializers.dll which I then deploy to resolve the assembly load issue when attempting to deserialize my own class. This particular fix however doesn't work for NHibernate.dll (due to previously mentioned type issue). From the way I understand the XmlSerializer works internally, it requires dynamically generated serialization classes which are generated either by Visual Studio or by using the sgen utility. If these classes are not precompiled (using sgen or provided as part of the library assembles) and then deployed by the application, how can the XmlSerializer possibly function in that environment?
7 Posted by Steven on 29 Jun, 2010 02:47 PM
Any more suggestions on this issue? Has anyone taken a Fluent NHibernate application onto a production system and run it without problems? The only way I see this happening is if the serialization assembly can get generated at runtime without the SDK or Visual Studio installed. I would imagine most production environments would have such constraints.
8 Posted by mirapalheta on 29 Jun, 2010 02:56 PM
Steven,
I have never got that problem and I agree with James, that shouldn't be a
problem and you may have another issues.
Daniel Mirapalheta
Support Staff 9 Posted by James Gregory on 29 Jun, 2010 03:21 PM
Steven,
I don't know how to put this much clearer than how I already have, that exception is expected behaviour. NHibernate functions perfectly fine without it. It's handled internally in the NHibernate serialization infrastructure, as mentioned here by one of the lead NHibernate contributors.
Are you actually seeing any failures or are you just picking up on these messages in the logs? If your application isn't starting, please show us the exception you're seeing.
Yes, they have.
10 Posted by Steven on 29 Jun, 2010 03:45 PM
Firstly let me say thank you for your contributions to this thread, often one posts in an online forum and receives no replies.
I don't want to seem arrogant about this issue but it is very perplexing to me. I have two development machines with Visual Studio 2008 installed and the application runs perfectly, either within or outside of the IDE. As soon as I deploy the application to a production environment I run into assembly load failures when configuring NHibernate (using Fluent). I determined this by monitoring the AssemblyResolve AppDomain event which attempts to load NHibernate.XmlSerializers.dll. I have encountered this problem on two seperate production systems, both running Windows XP Professional and .NET Framework 3.5 (SP1) and both without Visual Studio or the SDK. On both systems I am logged in as a local administrator and what I see is a normal Windows error dialog when the application is run. Checking in the event viewer there is a ".NET Framework 2.0 Error" which provides no indication as to what went wrong. Checking the fusion log (using fuslogvw) I find that the application could not load the aforementioned assembly.
From my understanding, the XmlSerializer dynamically generates these serialization assemblies. This can be seen when running inside Visual Studio and the output window shows the loading of some randomly named assembly. Why this is not happening in the production environment is beyond my current understanding. I will continue my investigation into this issue later and provide more feedback when possible.
Steven
11 Posted by Steven on 29 Jun, 2010 07:13 PM
This issue is resolved. For some strange reason this particular serialization assembly load problem was actually masquerading the real problem which was missing database drivers for SQL Server Compact Edition. On the development machines it was installed as part of Visual Studio however in production the SQLCE runtime had not been installed and doing so resolves the problem on at least one system. Don't ask me why an unrelated exception was being raised instead of one that identified the real problem. Creating a test console application, loading the Fluent NHibernate configuration within a global try-catch and printing out the inner exception hierarchy identified the database driver issue. Many thanks for the responses to my query and apologies for thinking that Fluent NHibernate was at fault, although it did seem to indicate as such!
Steven
12 Posted by Tom Bushell on 01 Jul, 2010 10:14 PM
For what it's worth, I too have been somewhat perturbed to see these exceptions.
It's especially worrisome when you've just started using NH / FNH, it's not working, and you don't know why - you tend to think that these exceptions might be part of the problem.
For my own peace of mind, and for the developers who may come after me, I added the following comment below the code that throws the exceptions
( _sessionFactory = Fluently.Configure()... in my case):
// Note: If "break on all CLR exceptions" is enabled in the debugger, // the code above will throw a FileNotFoundException // "Could not load file or assembly 'NHibernate.XmlSerializers..." // // If not enabled, "A first chance exception of type 'System.IO.FileNotFoundException' // occurred in mscorlib.dll" is shown in the Output window. // // This is normal behavior for NHibernate, and not any cause for concern.
-Tom