12

After adding Lucene.net and Lucene.net Contrib to a C# MVC3, I get the message below after the first successful run. After receiving this error, I need to completely wipe C:\Users\Me\AppData\Local\Temp\Temporary ASP.NET Files before I can run the project again.

I've tried removing the Lucene files manually (including references in my project), and reinstalling them - both with NuGet and manually - but it's always the same situation; after the project has been run once, I start getting the following errors:

Note: Contrib.Regex is part of Lucene.net Contrib.

Server Error in '/' Application.

Could not load types from assembly Contrib.Regex, Version=2.9.4.0, Culture=neutral, PublicKeyToken=85089178b9ac3181, errors:
Exception: System.IO.FileLoadException: Could not load file or assembly 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181'

=== Pre-bind state information ===
LOG: User = rcw7\Me
LOG: DisplayName = Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181
(Fully-specified)
LOG: Appbase = file:///C:/Development/Projects/Foobar/Foobar/
LOG: Initial PrivatePath = C:\Development\Projects\Foobar\Foobar\bin
Calling assembly : Contrib.Regex, Version=2.9.4.0, Culture=neutral, PublicKeyToken=85089178b9ac3181.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Development\Projects\Foobar\Foobar\web.config
LOG: Using host configuration file: C:\Users\Me\Documents\IISExpress\config\aspnet.config
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181
LOG: Attempting download of new URL file:///C:/Users/Me/AppData/Local/Temp/Temporary ASP.NET Files/root/e9b4cfa4/edfa73f8/Lucene.Net.DLL.
WRN: Comparing the assembly name resulted in the mismatch: Revision Number
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
Exception: System.IO.FileLoadException: Could not load file or assembly 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Lucene.Net, Version=2.9.4.1, Culture=neutral, PublicKeyToken=85089178b9ac3181'

Full output here: http://pastebin.com/Vbu4VK7B

Initially I thought this was a problem local to my development environment, but after rebuilding and copying the project to our server, I get the same errors.

Any suggestions as how to overcome this? :-)

Saustrup
  • 678
  • 1
  • 7
  • 18

4 Answers4

7

As it turns out, the DLL hell wasn't caused by my own meddling in configurations and compiled libraries. It was in fact caused by a collision between my newly downloaded version of Lucene.NET and a somewhat dated version bundled with Examine, which in turn was bundled with Umbraco 5.

Apparently the outdated, bundled Lucene.NET ended up in the shadow cache (Temporary ASP.NET Files), so after the next compile or IIS restart, execution would break. Clearing the shadow cache would allow for one success execution.

The weird thing was, that I was unable to find any reference anywhere in the debug output that hinted to the outdated version of Lucene.NET, either with a directory path or version number. The problem was spotted by comparing the file sizes of the shadow copied version of Lucene.NET and the version I intended to use. They were off, so I did a search for Lucene.NET.dll and found the one bundled with Examine in the Umbraco tree (under \App_Plugins\Examine)

The fast solution was to simply zip the Examine plugin, so Umbraco wouldn't see it. That leaves me without the Examine plugin, but I wasn't using it anyway.

The right solution would probably be to tell the app that it should ignore previous versions of Lucene.NET, but I haven't had any luck with that so far. This is what I added to web.config:

<dependentAssembly>
    <assemblyIdentity name="Lucene.Net" publicKeyToken="85089178b9ac3181" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-2.9.4.1" newVersion="2.9.4.1" />
</dependentAssembly>

This didn't seem to have any effect, and the outdated version still ended up in the shadow cache. I've moved this question here: How do I make Umbraco 5 ignore the bundled (with Examine) Lucene.NET

Thanks for your help and suggestions - it pointed me in the right direction! :-)

Community
  • 1
  • 1
Saustrup
  • 678
  • 1
  • 7
  • 18
3

This normally means that you have the files in the GAC which are a different version and the ones in your bin are another version. So your application is pointing to a version and it is finding another. It is getting confused. What you want to do is uninstall Lucene.net. After you uninstall, look in the c:\windows\assembly folder and make sure there are no Lucene files in there. If there are, right click and uninstall. Then you can install again.

Alex Mendez
  • 4,900
  • 1
  • 22
  • 22
  • What's the priority for looking in c:\windows\assemblies, compared to the app's bin directory and the GAC? I'd expect the system directory to be the last resort? – Saustrup Apr 24 '12 at 18:49
  • I think the GAC overrides any other location. – Alex Mendez Apr 24 '12 at 20:41
  • 1
    C:\windows\assemblies *is* the GAC. It only overrides when a reference doesn't require a specific version, in which case the newer of the two is used. – Jim Schubert Apr 25 '12 at 00:40
  • Ah, sorry, I meant the priorities of the GAC (c:\windows\assemblies), my local shadow copy (ASP.NET Temporary Files) and the app's bin directory. – Saustrup Apr 25 '12 at 09:26
3

The manifest definition does not match means there is an issue with the resolution of the assembly. see this SO question

[edit]

Assemblies are loaded from GAC, then lib/bin directories within your application, then directories specified via <HintPath> in your project. Check that you have

Specific Version = True and Copy Local = True

in the reference's properties window.

Assemblies from the private paths within your application (lib/bin directories) are the only ones that get shadow-copied. It's possible Contrib.Regex is being shadow-copied while Lucene.NET core is not.

[/edit]

The directory under ASP.NET Temporary Files that you are wiping is the shadow-copy directory. There may be an issue with how this assembly is being copied, which may be permissions for your domain account. You can test this theory by changing the shadowcopy directory or turning off shadowcopying completely as described here:

You can change this directory in Application_Start as explained at https://stackoverflow.com/a/2847495/151445

You can turn off shadow copying in the web.config:

<hostingEnvironment shadowCopyBinAssemblies="false" />

Community
  • 1
  • 1
Jim Schubert
  • 19,627
  • 5
  • 56
  • 67
  • I tried to turn off shadow copying by dropping the line in web.config under , but I still get DLLs in shadow-copy directory? – Saustrup Apr 24 '12 at 18:48
  • That should only happen if you have an existing AppDomain in the ApplicationPool once your files have been updated. This is because IIS caches the web.config per AppDomain and if one AppDomain's cached web.config has the older setting, your updated files would still be shadow-copied. The new AppDomain shouldn't be affected by this, though. I would restart Visual Studio and IIS to make sure there are no stale AppDomains and see if it still happens. – Jim Schubert Apr 24 '12 at 19:00
2

You can use the Fusion Log Viewer to diagnose this problems. It gives you full details of the types failed to load similar to the one you reported here. Hope this helps.

Cinchoo
  • 5,202
  • 2
  • 14
  • 30
  • I can't seem to get the Fusion Log Viewer to work - tried running it as administrator, but nothing seems to show up, even when my project is crashing. Should it make any difference that it's running under IIS Express? – Saustrup Apr 24 '12 at 17:17
  • Please make sure you enabled 'Enable all binds to disk' checkbox in 'Log Settings' via 'Settings...' button. Do 'Refresh', after you run your application. Let me know if this helps. – Cinchoo Apr 24 '12 at 17:41
  • Ah, got it working now - had to pick "Log all binds to disk" and specify a custom log path like C:\tmp - investigating now :-) – Saustrup Apr 24 '12 at 17:59