¿Cómo puedo evitar que log4net siga cambiando publickeytoken?


99

Tenemos un proyecto asp.net 4.0 que utiliza un par de marcos que dependen de la versión 1.2.10.0 de log4net. Hoy traté de incluir un nuevo marco que depende de log4net versión 1.2.11.0, me he quedado atascado desde entonces:

log4net 1.2.10.0 tiene publickeytoken = 1b44e1d426115821

log4net 1.2.11.0 tiene publickeytoken = 669e0ddf0bb1aa2a

Dado que estos son diferentes, no puedo usar redirecciones de ensamblaje (para que todos los marcos usen la misma versión de log4net) o base de código (para que solo el nuevo marco use la versión 1.2.11.0) a través del elemento de tiempo de ejecución en web.config.

¿Cuáles son mis opciones aquí?

(y por qué diablos log4net sigue cambiando publickeytokens entre versiones, según tengo entendido, una clave perdida fue la razón del cambio entre la versión 1.2.9.0 y 1.2.10.0, ¿perdieron la clave una vez más? para mantenerlo seguro si lo necesitan ...)

Editar: Ok, entonces los chicos de log4net aparentemente tenían la idea de que liberar con dos claves era una buena idea, pero eso significa que cada marco que utiliza debe acordar cuál de los dos sabores prefieren, o esos marcos no pueden funcionar al lado uno al lado del otro en el mismo dominio de aplicación. ¿Soy el único que encuentra esto como una idea horrible? Si todos hicieran esto, entonces todo se derrumbaría, ¿verdad?

Edit2: como dije, no estoy usando log4net en mi código comercial, pero uso varios marcos que dependen de 1.2.10.0, y el problema surgió cuando intenté usar un nuevo marco que dependía de 1.2.11.0 (nueva clave ), por lo que la respuesta de Stefan no se aplica, porque el nuevo marco esperará la nueva clave, no la anterior


1
En mi humilde opinión, el primer error de apache aquí es proporcionar los binarios firmados con una nueva clave: la nueva clave está destinada a la versión de código abierto parcheada / mejorada y no debe usarse como está. El segundo error es que el marco del que está hablando se ha lanzado solo con la nueva firma log4net: debería existir una versión con la firma anterior.
JoeBilly

6
En realidad, está viendo el tercer sabor: el que los genios de SAP recompilaron con su propio nombre fuerte, como parte del paquete Crystal Reports para Visual Studio, y para empeorar las cosas, lo metieron en el GAC, lo que hará que sus dependencias entre máquinas una pesadilla.
Jeremy Holovacs

Respuestas:


65

Así es como hice funcionar las cosas con la versión 1.2.11.0.

  1. Maldice a apache por cambiar la clave en primer lugar :)
  2. Descargar la versión 1.2.11.0 firmada con la clave anterior.
  3. Ordene su propio código eliminando cualquier referencia directa a log4net (clave nueva) y reemplácelo con una referencia al ensamblado firmado con la clave anterior.
  4. Ordene cualquier ensamblado dependiente que pueda tener al incluir este segmento en su 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
Es necesario descargar la versión firmada con la clave pública anterior ya que, lamentablemente, no es posible realizar un redireccionamiento vinculante a un ensamblado con una clave pública diferente.
David Christiansen

2
Esto parece fallar debido a un cambio importante en 1.2.11.0: netpl.blogspot.com/2012/03/…
sydneyos

¿Alguien ha encontrado una solución a los problemas descritos en el enlace mencionado por @sydneyos que causa la siguiente excepción:Method not found: 'Void log4net.Config.BasicConfigurator.Configure()'
Neo

Desafortunadamente, no hay otra solución que degradar a 1.2.10. (o recompilar cada ensamblado dependiente que use).
bk0

1
Coloque el ensamblado 1.2.10 en un directorio diferente y use esta configuración: '<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

Estoy usando la última versión de log4net que descargué a través de nuget. Sin embargo, una de las bibliotecas que estoy usando requiere la versión anterior. Mis problemas me llevaron a esta pregunta.

El problema con las otras respuestas es que están usando la misma versión dll para todos los enlaces. Quiero usar las funciones de la nueva versión para todo lo demás menos la dependencia heredada.

Para poder hacer eso, debe hacer lo siguiente:

  1. Empiece por descargar la versión anterior (versión 1.2.11.0).
  2. Cambie el nombre del binario descargado a log4net.1.2.10.dll. Inclúyalo en su proyecto de inicio con la acción de compilación configurada en Noney "Copiar si es más reciente" ingrese la descripción de la imagen aquí
  3. Dígale a .NET dónde puede encontrar la versión anterior:

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>

Los hrefatributos identifican dónde está la versión anterior. Por lo tanto, todas las demás solicitudes de log4net apuntarán a la nueva versión.


4
Esta es una gran solución porque le permite mantener ambas versiones para bibliotecas que hacen referencia a cualquiera de ellas.
SouthShoreAK

2
¡GRACIAS! Esto me salvó. Tuve que cambiar "Copiar al directorio de salida" a "No copiar", ¡pero por lo demás funcionó a la perfección!
Daniel Hedenström

3

Puede descargar una versión de log4net 1.2.11.0 que está firmada con la clave anterior. La razón por la que se cambió a una nueva clave se explica en sus preguntas frecuentes:

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

(Básicamente, la nueva clave está disponible públicamente y, por alguna razón, no querían incluir la clave anterior en la distribución. Sin embargo, no me queda claro por qué no solo pusieron la clave anterior a disposición del público)


10
Pero cuando uso una biblioteca de terceros que está vinculada a la nueva clave, todavía estoy atascado (¿verdad?). No es mi elección utilizar el nuevo log4net, es el marco de terceros. No puedo ver cómo estas cosas no van a explotar en la cara de todos a medida que más y más marcos comienzan a usar log4net con la nueva clave
AndreasKnudsen

Desafortunadamente, eso es correcto. Supongo que debe considerar que no todos los componentes usen la misma versión de log4net ...
Stefan Egli

1
.... y ¿cómo lo haría? ¿Existe algún mecanismo en .net para manejar este problema?
AndreasKnudsen


1

No sé si es adecuado para su caso particular o no, pero puede volver a compilar uno de los marcos, por lo que usarán log4net con la misma clave pública. En mi caso fue FluentNHibernate que usa log4net 1.2.10 y Combres con log4net 1.2.11 con nueva clave. Descargué log4net 1.2.11 firmado con la clave anterior y volví a compilar Combress con él. Después de eso, el enlace de ensamblaje agregado se redirige de 1.2.10 a 1.2.11 y comienza a funcionar.


0

Esto no funcionará necesariamente en todos los casos, pero debido a que el proyecto que estaba usando log4net era OSS, descargué la fuente, reemplacé la versión conflictiva de log4net con la versión que estaba usando y reconstruí el proyecto. En mi caso fue Topshelf, por lo que ahora tengo una versión del ensamblaje Topshelf que se creó con la misma versión de log4net que estoy usando y ahora puedo hacer referencia a ambos sin problemas.


0

Intenté ir a los enlaces proporcionados anteriormente, pero parece que todos los enlaces del sitio de Apache no funcionan. Entonces esto es lo que hice para resolver el problema:

Desde su Visual Studio, use Nuget para descargar e instalar la última versión de log4net (1.2.13.0). El administrador de paquetes NuGet descargará y actualizará automáticamente todo el log4net (1.2.11.0) a la última versión.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.