81

I'm using NHibernate 2.1.2.400 that is referencing log4net 1.2.10.0. In the same project, I also use the simply accounting SDK, sadly it is still using log4net 1.2.9.0.

So I can get NHibernate to work if I reference log4net 1.2.10.0 but the simplySDK don't work. And vice versa...

I'm guessing most of the problems come from the fact that log4net has changed its assembly key. I tried using a binding redirection without success: the 2 DLLs do not have the same key.

I'm considering recompiling NHibernate to use log4net 1.2.9.0 but it seems like the wrong thing to do and my feeling is that Simply Accounting won't be updating their SDK to use log4net 1.2.10.0 anytime soon.

What is the best way to handle this? Is it possible to resolve at all?

Daniel Williams
  • 8,912
  • 15
  • 68
  • 107
Joel Gauvreau
  • 3,586
  • 4
  • 29
  • 32
  • 2
    I have a very similar question at http://stackoverflow.com/questions/1744543/reference-two-equal-assemblies-only-public-keys-differ I resorted to recompilation. I guess this is the advent of dll-hell v2.0. – Sandor Drieënhuizen Jul 01 '10 at 17:34
  • 2
    while checking your question I found http://stackoverflow.com/questions/2460542/2461746#2461746 that fixed my problem. – Joel Gauvreau Jul 01 '10 at 18:01
  • 1
    Great! I had been wondering about making the CLR look in different locations and the `href` attribute seems to do the trick. Thanks for pointing that out! – Sandor Drieënhuizen Jul 01 '10 at 19:36

3 Answers3

153

I found the solution by using this answer to a similar question

You create 2 folders in your project one for each version of log4net. Place each log4net.dll in its corresponding folder by adding an the file to the solution (not with add reference). You can set the copy to output directory property to copy always so that it is automatically copied to the output folder when you build.

Then you modifiy the app.config file by adding something like this:

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="681549d62126b7b8" />
        <codeBase version="1.2.9.0" href="log4netv1.2.9.0\log4net.dll" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" />
        <codeBase version="1.2.10.0" href="log4netv1.2.10.0\log4net.dll" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" />
        <codeBase version="1.2.11.0" href="log4net.dll" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

you can get the public key token of an assembly by using sn -T [assemblyName]

Community
  • 1
  • 1
Joel Gauvreau
  • 3,586
  • 4
  • 29
  • 32
  • 2
    This seems to work for me as well. I removed log4net from my References list for the project where the conflict was occuring. Also, since log4net.dll is not in my bin folders, my href paths looked more like "..\..\..\..\Lib\NHibernate-2.0.1.GA\log4net.dll"--just a relative path to where log4net will be on every dev's machine with our build system. – jyoungdev Oct 13 '10 at 19:34
  • 12
    I'm not sure I get this: how do you not get compiling errors if log4net is not referenced? – guidupuy Aug 29 '12 at 15:10
  • 1
    @guidupuy I think it may just be a dependency of a reference. That's why it may compile without the reference and still work at runtime. – cdpnet Aug 05 '13 at 01:11
  • 2
    This is awesome, it would fix other cases where a simple binding redirect would break things due to API changes too! – Rhys Bevilaqua Apr 29 '14 at 06:39
  • 5
    @guidupy you can reference the log4net your code uses, but turn off the copyLocal in the properties. – Jeff Martin May 20 '14 at 18:14
  • Can any PC configurations cause this to not work? I find it's working fine for me, but not when deployed to my customer's pc. – Inrego Jan 26 '15 at 06:49
  • This is the best way after trying so many suggesstion and speand afew hours.Now it works perfectly.Thanks – YeeKhin Feb 23 '15 at 15:51
  • great, works like a charm, with only one modification, for the project to build, I added the correct reference but set its property Copy Local = False – Sameh Deabes Mar 15 '15 at 19:54
  • also I for the dlls included in the project, set properties to 'Copy if newer' – Sameh Deabes Mar 15 '15 at 20:30
  • 1
    How do you handle the config section declaration in this case? Does it matter which assembly you map it to? It won't log if you don't specify the full type in the section declaration; but you can only have one section declaration. – Tomas Jul 13 '15 at 22:14
  • Excellent solution, but there is a trick. Due to a bug, codeBase in web.config may not take unless there is also bindingRedirect present! – LB2 Oct 23 '15 at 18:11
  • And it's a damning indictment of Apache's choices here that we're still wasting time attempting to solve this problem. For anyone who's coming to this problem again -- note that this fix will only work for projects that will actually use an app.config, not for class libraries, for example. – Tim Barrass Oct 24 '17 at 09:25
  • 4
    for future readers (a hint I found from another answer, but prudent to post here)... for web-applications (asp.net), the reference has a tweak: – granadaCoder Mar 27 '18 at 00:54
  • Please note that if you want to get the assembly key token, make sure to pass capital T to the sn tool, otherwise it will fail: sn -T "assembly full path" – Anas Ghanem Nov 04 '18 at 07:24
  • How are the appenders setup when using this solution. Can the logs from codebase using different log4net versions write to the same file? – Rahul Misra Jun 17 '20 at 15:02
7

You can add an exclusion to the registry. Just add these keys:

HKEY_LOCAL_MACHINE\Software\Microsoft\StrongName\Verification\log4net,681549d62126b7b8
HKEY_LOCAL_MACHINE\Software\Microsoft\StrongName\Verification\log4net,1b44e1d426115821
HKEY_LOCAL_MACHINE\Software\Microsoft\StrongName\Verification\log4net,669e0ddf0bb1aa2a

This will make the .net runtime skip validation for the listed assemblies. In theory this is a security issue, but since the private key is out in the open anyway, there's hardly any impact.

Joep Beusenberg
  • 517
  • 6
  • 15
  • As you said, this is a security issue. Also, this woud imply that you must make those change on every workstation that runs the software. In a complex enterprise network those kind of things adds up to make a huge mess. I'd rather avoid it as much as possible. The others solutions are self-contained and portable. – Joel Gauvreau Feb 24 '16 at 17:44
  • As i said, because the private keys are publicly available anyway, there is no real security issue at all. Especially in an enterprise network it would be more easy to configure a single Group Policy Object, than to configure this for every LOB application in use. You can configure it once at a domain level and never have to think about it again. – Joep Beusenberg Feb 25 '16 at 14:50
3

If binding redirection doesn't work and the simply accounting SDK is closed source, a possible solution is recompiling NHibernate to use log4net 1.2.9.0.

Diego Mijelshon
  • 52,548
  • 16
  • 116
  • 154
  • 4
    That would work, but having to build a special version of nhibernate would be harder to support down the line... thanks. – Joel Gauvreau Jul 01 '10 at 18:07