comment contourner log4net en continuant à changer publickeytoken

99

Nous avons un projet asp.net 4.0 qui utilise quelques frameworks qui dépendent de la version 1.2.10.0 de log4net. Aujourd'hui, j'ai essayé d'inclure un nouveau framework qui dépend de la version 1.2.11.0 de log4net, je suis bloqué depuis:

log4net 1.2.10.0 a publickeytoken = 1b44e1d426115821

log4net 1.2.11.0 a publickeytoken = 669e0ddf0bb1aa2a

Comme ils sont différents, je ne peux utiliser ni les redirections d'assembly (pour que tous les frameworks utilisent la même version de log4net) ou codebase (pour que le nouveau framework utilise uniquement la version 1.2.11.0) via l'élément d'exécution dans web.config.

Quelles sont mes options ici?

(et pourquoi le bip est-ce que log4net continue de changer publickeytokens entre les versions, si je comprends bien, une clé perdue était la raison du passage de la version 1.2.9.0 à 1.2.10.0, ont-ils encore perdu la clé? pour le garder en sécurité s'ils en ont besoin ...)

Edit: Ok, donc les gars de log4net ont apparemment eu l'idée que la libération avec deux clés était une bonne idée, mais cela signifie que chaque framework que vous utilisez doit se mettre d'accord sur laquelle des deux saveurs ils préfèrent, ou ces frameworks ne peuvent pas fonctionner de côté côte à côte dans le même domaine d'application. Suis-je le seul à trouver cette idée horrible? si tout le monde faisait cela, tout s'effondrerait, non?

Edit2: Comme je l'ai dit, je n'utilise pas log4net dans mon code métier, mais j'utilise plusieurs frameworks qui dépendent de 1.2.10.0, et le problème est survenu lorsque j'ai essayé d'utiliser un nouveau framework qui dépendait de 1.2.11.0 (nouvelle clé ), donc la réponse de Stefans ne s'applique pas, car le nouveau framework attendra la nouvelle clé, pas l'ancienne

AndreasKnudsen
la source
1
À mon humble avis, la première erreur d'apache ici est de fournir les binaires signés avec une nouvelle clé: la nouvelle clé est destinée à la version open source corrigée / améliorée et ne doit pas être utilisée telle quelle. La deuxième erreur est que le framework dont vous parlez a été publié avec la nouvelle signature log4net uniquement: une version avec l'ancienne signature devrait exister.
JoeBilly
6
En fait, vous regardez la troisième saveur: celle que les génies de SAP ont recompilée avec leur propre nom fort, dans le cadre du package Crystal Reports pour Visual Studio, et pour aggraver les choses, ils l'ont collé dans le GAC, ce qui rendra vos dépendances à travers les machines un cauchemar.
Jeremy Holovacs

Réponses:

65

C'est ainsi que j'ai fait fonctionner les choses avec la version 1.2.11.0.

  1. Maudit apache pour avoir changé la clé en premier lieu :)
  2. Téléchargez la version 1.2.11.0 signée avec l'ancienne clé.
  3. Triez votre propre code en supprimant toutes les références directes à log4net (nouvelle clé) et remplacez-les par une référence à l'assembly signé avec l'ancienne clé.
  4. Triez tous les assemblys dépendants que vous pouvez avoir en incluant ce segment dans votre web / app.config
   <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" culture="neutral" />
                <bindingRedirect oldVersion="0.0.0.0-1.2.10.0"
                                 newVersion="1.2.11.0"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
David Christiansen
la source
9
Le téléchargement de la version signée avec l'ancienne clé publique est nécessaire car il n'est malheureusement pas possible d'effectuer une redirection de liaison vers un assembly avec une clé publique différente.
David Christiansen
2
Cela semble échouer en raison d'un changement radical dans la version 1.2.11.0: netpl.blogspot.com/2012/03/…
sydneyos
Quelqu'un at-il trouvé une solution aux problèmes décrits sur le lien mentionné par @sydneyos qui provoque l'exception suivante:Method not found: 'Void log4net.Config.BasicConfigurator.Configure()'
Neo
Il n'y a malheureusement pas d'autre solution que de passer à la version 1.2.10. (ou recompiler chaque assembly dépendant que vous utilisez).
bk0
1
Placez l'assembly 1.2.10 dans un répertoire différent et utilisez cette configuration: '<dependentAssembly> <assemblyIdentity name = "log4net" publicKeyToken = "1b44e1d426115821" culture = "neutral" /> <bindingRedirect oldVersion = "0.0.0.0-1.2.9.0 "newVersion =" 1.2.10.0 "/> <codeBase version =" 1.2.10.0 "href =" Resources \ log4net-oldkey \ log4net.dll "/> </dependentAssembly> '
Agile Jedi
27

J'utilise la dernière version de log4net que j'ai téléchargée via nuget. Cependant, l'une des bibliothèques que j'utilise nécessite l'ancienne version. Mes ennuis m'ont conduit à cette question.

Le problème avec les autres réponses est qu'elles utilisent la même version de DLL pour toutes les liaisons. Je souhaite utiliser les fonctionnalités de la nouvelle version pour tout le reste, sauf la dépendance héritée.

Pour pouvoir le faire, vous devez procéder comme suit:

  1. Commencez par télécharger l'ancienne version (version 1.2.11.0).
  2. Renommez le binaire téléchargé en log4net.1.2.10.dll. Incluez-le dans votre projet de démarrage avec l' action Construire définie sur Noneet "Copier si plus récent" entrez la description de l'image ici
  3. Dites à .NET où il peut trouver l'ancienne version:

App.config

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" />
            <codeBase version="1.2.10.0" href="log4net.1.2.10.dll" />
        </dependentAssembly>
    </assemblyBinding>
</runtime>

Les hrefattributs identifient où se trouve l'ancienne version. Par conséquent, toutes les autres demandes de log4net pointeront sur la nouvelle version.

Jgauffin
la source
4
C'est une excellente solution car elle vous permet de conserver les deux versions pour les bibliothèques qui référencent l'une ou l'autre.
SouthShoreAK
2
MERCI! Cela m'a sauvé. J'ai dû changer le "Copier dans le répertoire de sortie" en "Ne pas copier", mais sinon cela fonctionnait comme un charme!
Daniel Hedenström
3

Vous pouvez télécharger une version de log4net 1.2.11.0 qui est signée avec l'ancienne clé. La raison pour laquelle la nouvelle clé est modifiée est expliquée dans leur FAQ:

http://logging.apache.org/log4net/release/faq.html#two-snks

(Fondamentalement, la nouvelle clé est accessible au public et pour une raison quelconque, ils ne voulaient pas inclure l'ancienne clé dans la distribution. Je ne vois pas pourquoi ils n'ont pas simplement rendu l'ancienne clé accessible au public)

Stefan Egli
la source
10
Mais lorsque j'utilise une bibliothèque tierce qui est liée à la nouvelle clé, je suis toujours bloqué (non?). Ce n'est pas mon choix d'utiliser le nouveau log4net, c'est le framework tiers. Je ne peux pas voir comment cela ne va pas exploser dans le visage de tout le monde alors que de plus en plus de frameworks commencent à utiliser log4net avec la nouvelle clé
AndreasKnudsen
C'est malheureusement correct. Je suppose que vous devez envisager de ne pas avoir tous les composants utilisent la même version de log4net ...
Stefan Egli
1
.... et comment pourrais-je procéder? Existe-t-il un mécanisme dans .net pour gérer ce problème?
AndreasKnudsen
1

Je ne sais pas si cela convient ou non à votre cas particulier, mais vous pouvez recompiler l'un des frameworks, afin qu'ils utilisent log4net avec la même clé publique. Dans mon cas, c'était FluentNHibernate qui utilise log4net 1.2.10 et Combres avec log4net 1.2.11 avec une nouvelle clé. J'ai téléchargé log4net 1.2.11 signé avec l'ancienne clé et recompilé Combress avec. Après cette redirection de liaison d'assembly ajoutée de 1.2.10 à 1.2.11 et cela commence à fonctionner.

Alex
la source
0

Cela ne fonctionnera pas nécessairement dans tous les cas, mais comme le projet qui utilisait log4net était OSS, j'ai téléchargé la source, remplacé la version en conflit de log4net par la version que j'utilisais et reconstruit le projet. Dans mon cas, c'était Topshelf, donc j'ai maintenant une version de l'assembly Topshelf qui a été construite avec la même version de log4net que j'utilise et maintenant je peux référencer les deux sans problème.

Mark J Miller
la source
0

J'ai essayé d'accéder aux liens fournis ci-dessus, mais il semble que tous les liens du site Apache ne fonctionnent pas. Ensuite, voici ce que j'ai fait pour résoudre le problème:

À partir de votre Visual Studio, utilisez Nuget pour télécharger et installer la dernière version de log4net (1.2.13.0). Le gestionnaire de packages NuGet téléchargera et mettra à niveau automatiquement tous les log4net (1.2.11.0) vers la dernière version.

George Huang
la source