come aggirare log4net continuando a cambiare publickeytoken


99

Abbiamo un progetto asp.net 4.0 che utilizza un paio di framework che dipendono dalla versione 1.2.10.0 di log4net. Oggi ho provato a includere un nuovo framework che dipende dalla versione 1.2.11.0 di log4net, da allora sono rimasto bloccato:

log4net 1.2.10.0 ha publickeytoken = 1b44e1d426115821

log4net 1.2.11.0 ha publickeytoken = 669e0ddf0bb1aa2a

Poiché sono diversi, non posso utilizzare né reindirizzamenti di assembly (per fare in modo che tutti i framework utilizzino la stessa versione di log4net) o codebase (per fare in modo che solo il nuovo framework utilizzi la versione 1.2.11.0) tramite l'elemento runtime in web.config.

Quali sono le mie opzioni ?

(e perché il segnale acustico log4net continua a cambiare i token di chiave pubblica tra le versioni, poiché ho capito che una chiave persa è stata la ragione del passaggio tra la versione 1.2.9.0 e 1.2.10.0, hanno perso la chiave ancora una volta? Offro volontariamente la mia casella personale per tenerlo al sicuro se ne hanno bisogno ...)

Modifica: Ok, quindi i ragazzi di log4net hanno apparentemente l'idea che il rilascio con due chiavi fosse una buona idea, ma ciò significa che ogni framework che usi deve concordare su quale dei due gusti preferiscono, o quei framework non possono funzionare lateralmente a fianco nello stesso appdomain. Sono l'unico che trova questa un'idea orribile? se tutti lo facessero, tutto si guasterebbe, giusto?

Edit2: come ho affermato, non sto utilizzando log4net nel mio codice aziendale, ma utilizzo diversi framework che dipendono da 1.2.10.0 e il problema è sorto quando ho provato a utilizzare un nuovo framework che dipendeva da 1.2.11.0 (nuova chiave ), quindi la risposta di Stefans non si applica, perché il nuovo framework si aspetterà la nuova chiave, non quella vecchia


1
IMHO, il primo errore di apache qui è fornire i binari firmati con una nuova chiave: la nuova chiave è intesa per la versione open source patchata / migliorata e non dovrebbe essere usata così com'è. Il secondo errore è che il framework di cui parli è stato rilasciato solo con la nuova firma log4net: dovrebbe esistere una versione con la vecchia firma.
JoeBilly

6
In realtà, stai guardando il terzo sapore: quello che i geni di SAP hanno ricompilato con il proprio nome forte, come parte del pacchetto Crystal Reports per Visual Studio, e come se non bastasse, l'hanno inserito nel GAC che renderà le tue dipendenze tra le macchine un incubo.
Jeremy Holovacs

Risposte:


65

È così che le cose funzionano con la versione 1.2.11.0.

  1. Maledizione apache per aver cambiato la chiave in primo luogo :)
  2. Scarica la versione 1.2.11.0 firmata con la vecchia chiave.
  3. Ordina il tuo codice rimuovendo qualsiasi riferimento diretto a log4net (nuova chiave) e sostituiscilo con un riferimento all'assembly firmato con la vecchia chiave.
  4. Ordina eventuali assembly dipendenti che potresti avere includendo questo segmento nel tuo 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>

9
Il download della versione firmata con la vecchia chiave pubblica è necessario in quanto purtroppo non è possibile eseguire un binding redirect ad un assembly con una chiave pubblica diversa.
David Christiansen

2
Questo sembra fallire a causa di una modifica sostanziale nella 1.2.11.0: netpl.blogspot.com/2012/03/…
sydneyos

Qualcuno ha trovato una soluzione ai problemi descritti al link menzionato da @sydneyos che causa la seguente eccezione:Method not found: 'Void log4net.Config.BasicConfigurator.Configure()'
Neo

Sfortunatamente, non c'è altra soluzione oltre al downgrade a 1.2.10. (o ricompilare ogni assembly dipendente che usi).
bk0

1
Metti l'assembly 1.2.10 in una directory diversa e usa questa configurazione: "<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

Sto usando l'ultima versione di log4net che ho scaricato tramite nuget. Tuttavia, una delle librerie che sto utilizzando richiede la vecchia versione. I miei guai mi hanno portato a questa domanda.

Il problema con le altre risposte è che stanno usando la stessa versione dll per tutte le associazioni. Voglio usare le funzionalità nella nuova versione per tutto il resto tranne la dipendenza legacy.

Per poterlo fare, devi fare quanto segue:

  1. Inizia scaricando la vecchia versione (versione 1.2.11.0).
  2. Rinomina il file binario scaricato in log4net.1.2.10.dll. Includilo nel tuo progetto di avvio con l' azione Build impostata su Nonee "Copia se più recente" inserisci qui la descrizione dell'immagine
  3. Indica a .NET dove può trovare la vecchia versione:

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>

Gli hrefattributi identificano dove si trova la vecchia versione. Quindi tutte le altre richieste per log4net punteranno sulla nuova versione.


4
Questa è un'ottima soluzione perché ti consente di mantenere entrambe le versioni per le librerie che fanno riferimento a entrambe.
SouthShoreAK

2
GRAZIE! Questo mi ha salvato. Ho dovuto cambiare "Copia nella directory di output" in "Non copiare", ma per il resto ha funzionato a meraviglia!
Daniel Hedenström

3

È possibile scaricare una versione di log4net 1.2.11.0 firmata con la vecchia chiave. Il motivo per cui la modifica a una nuova chiave è spiegato nelle loro FAQ:

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

(Fondamentalmente la nuova chiave è disponibile pubblicamente e per qualche motivo non hanno voluto includere la vecchia chiave nella distribuzione. Non mi è chiaro perché non abbiano semplicemente reso la vecchia chiave pubblicamente disponibile)


10
Ma quando utilizzo una libreria di terze parti che è collegata alla nuova chiave, sono ancora bloccato (giusto?). Non è mia scelta utilizzare il nuovo log4net, è il framework di terze parti. Non riesco a vedere come questa roba non esploderà in faccia a tutti poiché sempre più framework iniziano a utilizzare log4net con la nuova chiave
AndreasKnudsen

Purtroppo è corretto. Immagino sia necessario considerare di non avere tutti i componenti che utilizzano la stessa versione di log4net ...
Stefan Egli

1
.... e come potrei fare per farlo? Esiste un meccanismo in .net per gestire questo problema?
AndreasKnudsen


1

Non so se sia adatto o meno al tuo caso particolare, ma puoi ricompilare uno dei framework, in modo che utilizzino log4net con la stessa chiave pubblica. Nel mio caso è stato FluentNHibernate che utilizza log4net 1.2.10 e Combres con log4net 1.2.11 con nuova chiave. Ho scaricato log4net 1.2.11 firmato con la vecchia chiave e ho ricompilato Combress con esso. Dopo di ciò, è stato aggiunto il reindirizzamento dell'associazione dell'assembly da 1.2.10 a 1.2.11 e inizia a funzionare.


0

Questo non funzionerà necessariamente in tutti i casi, ma poiché il progetto che utilizzava log4net era OSS, ho scaricato il sorgente, ho sostituito la versione in conflitto di log4net con la versione che stavo usando e ho ricostruito il progetto. Nel mio caso era Topshelf, quindi ora ho una versione dell'assembly Topshelf che è stata costruita con la stessa versione di log4net che sto usando e ora posso fare riferimento a entrambi senza problemi.


0

Ho provato ad andare ai collegamenti forniti sopra, ma sembra che tutti i collegamenti nel sito Apache non funzionino. Quindi questo è quello che ho fatto per risolvere il problema:

Da Visual Studio, usa Nuget per scaricare e installare l'ultima versione di log4net (1.2.13.0). Il gestore dei pacchetti NuGet scaricherà e aggiornerà automaticamente tutto il log4net (1.2.11.0) alla versione più recente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.