jak obejść log4net, ciągle zmieniając publickeytoken


99

Mamy projekt asp.net 4.0, który używa kilku struktur, który jest zależny od log4net w wersji 1.2.10.0. Dzisiaj próbowałem dołączyć nowy framework, który jest zależny od log4net w wersji 1.2.11.0, utknąłem od tego czasu:

log4net 1.2.10.0 ma publickeytoken = 1b44e1d426115821

log4net 1.2.11.0 ma publickeytoken = 669e0ddf0bb1aa2a

Ponieważ są one różne, nie mogę używać ani przekierowań do zestawu (aby wszystkie frameworki korzystały z tej samej wersji log4net), ani bazy kodu (aby mieć tylko nową wersję frameworka w wersji 1.2.11.0) za pośrednictwem elementu wykonawczego w pliku web.config.

Jakie mam opcje tutaj?

(i dlaczego sygnał dźwiękowy log4net ciągle zmienia publickeytokens między wersjami, jak rozumiem, zgubiony klucz był przyczyną przełączenia między wersjami 1.2.9.0 i 1.2.10.0, czy znowu zgubili klucz? Zgłoszę moją skrzynkę referencyjną aby był bezpieczny, gdyby tego potrzebowali ...)

Edycja: Ok, więc faceci z log4net najwyraźniej wpadli na pomysł, że wydanie z dwoma kluczami było dobrym pomysłem, ale oznacza to, że każdy framework, którego używasz, musi uzgodnić, który z dwóch preferuje, lub te ramy nie mogą działać po stronie obok siebie w tej samej domenie aplikacji. Czy tylko ja uważam, że to okropny pomysł? gdyby wszyscy to zrobili, wszystko by się zepsuło, prawda?

Edit2: Jak powiedziałem, nie używam log4net w moim kodzie biznesowym, ale używam kilku frameworków, które zależą od 1.2.10.0, a problem pojawił się, gdy próbowałem użyć nowego frameworka, który zależał od 1.2.11.0 (nowy klucz ), więc odpowiedź Stefansa nie ma zastosowania, ponieważ nowy framework będzie oczekiwał nowego klucza, a nie starego


1
IMHO, pierwszym błędem ze strony Apache jest dostarczenie plików binarnych podpisanych nowym kluczem: nowy klucz jest przeznaczony dla poprawionej / ulepszonej wersji open source i nie powinien być używany tak, jak jest. Drugim błędem jest to, że framework, o którym mówisz, został wydany tylko z nowym podpisem log4net: wersja ze starym podpisem powinna istnieć.
— JoeBilly

6
Właściwie patrzysz na trzeci smak: ten, który geniusze SAP przekompilowali pod własną silną nazwą, jako część pakietu Crystal Reports for Visual Studio, a co gorsza, umieścili go w GAC, co sprawi, że Twoje zależności między maszynami koszmarem.
— Jeremy Holovacs

Odpowiedzi:


65

W ten sposób wszystko działa z wersją 1.2.11.0.

  1. Klątwa apache za zmianę klucza w pierwszej kolejności :)
  2. Pobierz wersję 1.2.11.0 podpisaną starym kluczem.
  3. Uporządkuj swój własny kod, usuwając wszelkie bezpośrednie odwołania do log4net (nowy klucz) i zamień na odwołanie do zestawu podpisanego starym kluczem.
  4. Uporządkuj wszystkie zależne zestawy, które możesz mieć, dołączając ten segment do pliku 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
Pobranie wersji podpisanej starym kluczem publicznym jest konieczne, ponieważ niestety nie jest możliwe wykonanie przekierowania powiązania do zestawu z innym kluczem publicznym.
— David Christiansen

2
Wydaje się, że kończy się to niepowodzeniem z powodu przełomowej zmiany w wersji 1.2.11.0: netpl.blogspot.com/2012/03/…
— sydneyos

Czy ktoś znalazł rozwiązanie problemów opisanych pod linkiem wspomnianym przez @sydneyos, co powoduje następujący wyjątek:Method not found: 'Void log4net.Config.BasicConfigurator.Configure()'
— Neo

Niestety nie ma innego rozwiązania niż obniżenie wersji do 1.2.10. (lub ponowne kompilowanie każdego używanego zestawu zależnego).
— bk0

1
Umieść zestaw 1.2.10 w innym katalogu i użyj tej konfiguracji: „<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

Używam najnowszej wersji log4net, którą pobrałem za pośrednictwem nuget. Jednak jedna z bibliotek, których używam, wymaga starej wersji. Moje kłopoty doprowadziły mnie do tego pytania.

Problem z innymi odpowiedziami polega na tym, że używają one tej samej wersji dll dla wszystkich powiązań. Chcę używać funkcji w nowej wersji do wszystkiego innego oprócz starszej zależności.

Aby to zrobić, musisz wykonać następujące czynności:

  1. Zacznij od pobrania starej wersji (wersja 1.2.11.0).
  2. Zmień nazwę pobranego pliku binarnego na log4net.1.2.10.dll. Uwzględnij go w swoim projekcie startowym z akcją Kompiluj ustawioną na Nonei „Kopiuj, jeśli nowsza” wprowadź opis obrazu tutaj
  3. Poinformuj .NET, gdzie może znaleźć starszą wersję:

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>

hrefAtrybuty identyfikuje gdzie stara wersja jest. Dlatego wszystkie inne żądania dotyczące log4net będą wskazywać na nową wersję.


4
Jest to świetne rozwiązanie, ponieważ pozwala zachować obie wersje dla bibliotek, które się do nich odwołują.
— SouthShoreAK

2
DZIĘKUJĘ CI! To mnie uratowało. Musiałem zmienić „Kopiuj do katalogu wyjściowego” na „Nie kopiuj”, ale poza tym działało to jak urok!
— Daniel Hedenström

3

Możesz pobrać wersję log4net 1.2.11.0, która jest podpisana starym kluczem. Powód, dla którego zmieniono klucz na nowy, wyjaśniono w ich FAQ:

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

(Zasadniczo nowy klucz jest publicznie dostępny iz jakiegoś powodu nie chcieli uwzględniać starego klucza w dystrybucji. Nie jest dla mnie jasne, dlaczego nie udostępnili starego klucza publicznie)


10
Ale kiedy używam biblioteki innej firmy, która jest powiązana z nowym kluczem, nadal utknąłem (prawda?). Nie moim wyborem jest używanie nowego log4net, to framework innej firmy. Nie widzę, jak te rzeczy nie
— wybuchną

To jest niestety poprawne. Chyba trzeba brać pod uwagę nie posiadające wszystkie elementy wykorzystać tę samą wersję log4net ...
— Stefan Egli

1
.... i jak bym to zrobił? Czy w .net istnieje mechanizm obsługi tego problemu?
— AndreasKnudsen


1

Nie wiem, czy jest to odpowiednie dla twojego konkretnego przypadku, czy nie, ale możesz przekompilować jeden z frameworków, aby używał log4net z tym samym kluczem publicznym. W moim przypadku był to FluentNHibernate, który używa log4net 1.2.10 i Combres z log4net 1.2.11 z nowym kluczem. Ściągnąłem log4net 1.2.11 podpisany starym kluczem i ponownie skompilowałem z nim Combress. Następnie dodane powiązanie zestawu przekierowuje z 1.2.10 na 1.2.11 i zaczyna działać.


0

To niekoniecznie zadziała we wszystkich przypadkach, ale ponieważ projekt korzystający z log4net był OSS, pobrałem źródło, zastąpiłem sprzeczną wersję log4net wersją, z której korzystałem i przebudowałem projekt. W moim przypadku był to Topshelf, więc mam teraz wersję zespołu Topshelf, która została zbudowana z tą samą wersją log4net, której używam i teraz mogę odwoływać się do obu bez problemu.


0

Próbowałem przejść do linków podanych powyżej, ale wygląda na to, że wszystkie linki w witrynie Apache nie działają. Oto, co zrobiłem, aby rozwiązać problem:

W programie Visual Studio użyj narzędzia Nuget, aby pobrać i zainstalować najnowszą wersję log4net (1.2.13.0). Menedżer pakietów NuGet automatycznie pobierze i zaktualizuje cały log4net (1.2.11.0) do najnowszej wersji.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.