ฉันจะแก้ปัญหา log4net ได้อย่างไรโดยเปลี่ยน publickeytoken


99

เรามีโปรเจ็กต์ asp.net 4.0 ซึ่งใช้เฟรมเวิร์กสองสามตัวซึ่งขึ้นอยู่กับ log4net เวอร์ชัน 1.2.10.0 วันนี้ฉันพยายามรวมเฟรมเวิร์กใหม่ซึ่งขึ้นอยู่กับ log4net เวอร์ชัน 1.2.11.0 ฉันก็ติดตั้งแต่นั้นมา:

log4net 1.2.10.0 มี publickeytoken = 1b44e1d426115821

log4net 1.2.11.0 มี publickeytoken = 669e0ddf0bb1aa2a

เนื่องจากสิ่งเหล่านี้แตกต่างกันฉันจึงไม่สามารถใช้การเปลี่ยนเส้นทางแอสเซมบลี (เพื่อให้เฟรมเวิร์กทั้งหมดใช้ log4net เวอร์ชันเดียวกัน) หรือโค้ดเบส (เพื่อให้มีเพียงเฟรมเวิร์กใหม่ใช้เวอร์ชัน 1.2.11.0) ผ่านองค์ประกอบรันไทม์ใน web.config

ตัวเลือกของฉันที่นี่มีอะไรบ้าง?

(และเหตุใด log4net จึงเปลี่ยน publickeytokens ไปมาระหว่างเวอร์ชันเนื่องจากฉันเข้าใจว่าคีย์ที่หายไปเป็นสาเหตุของการสลับระหว่างเวอร์ชัน 1.2.9.0 และ 1.2.10.0 พวกเขาทำคีย์หายอีกหรือไม่ฉันจะอาสาดรอปบ็อกซ์ของฉัน เพื่อให้ปลอดภัยหากพวกเขาต้องการ ... )

แก้ไข: ตกลงดังนั้นพวก log4net จึงมีความคิดที่ว่าการปล่อยปุ่มสองปุ่มเป็นความคิดที่ดี แต่นั่นหมายความว่าทุกเฟรมเวิร์กที่คุณใช้จำเป็นต้องตกลงว่าจะเลือกรสชาติใดจากสองรสชาติที่พวกเขาต้องการหรือกรอบงานเหล่านั้นไม่สามารถทำงานได้ เคียงข้างกันใน appdomain เดียวกัน ฉันเป็นคนเดียวที่พบความคิดที่น่ากลัวนี้หรือไม่? ถ้าทุกคนทำอย่างนี้ทุกอย่างจะพังใช่ไหม?

Edit2: ตามที่ฉันระบุไว้ฉันไม่ได้ใช้ log4net ในรหัสธุรกิจของฉัน แต่ฉันใช้เฟรมเวิร์กหลายอันซึ่งขึ้นอยู่กับ 1.2.10.0 และปัญหาเกิดขึ้นเมื่อฉันพยายามใช้เฟรมเวิร์กใหม่ซึ่งขึ้นอยู่กับ 1.2.11.0 (คีย์ใหม่ ) ดังนั้นคำตอบของ Stefans จึงใช้ไม่ได้เพราะกรอบงานใหม่จะคาดหวังคีย์ใหม่ไม่ใช่คีย์เก่า


1
IMHO ข้อผิดพลาดแรกจาก apache ที่นี่คือการระบุไบนารีที่ลงนามด้วยคีย์ใหม่: คีย์ใหม่มีไว้สำหรับเวอร์ชันโอเพนซอร์สที่ได้รับการแก้ไข / ปรับปรุงและไม่ควรใช้ตามที่เป็นอยู่ ข้อผิดพลาดประการที่สองคือกรอบงานที่คุณกำลังพูดถึงได้รับการเผยแพร่พร้อมกับลายเซ็น log4net ใหม่เท่านั้น: ควรมีเวอร์ชันที่มีลายเซ็นเก่า
JoeBilly

6
จริงๆแล้วคุณกำลังดูรสชาติที่สาม: คนอัจฉริยะที่ SAP คอมไพล์ใหม่ด้วยชื่อที่แข็งแกร่งของพวกเขาเองซึ่งเป็นส่วนหนึ่งของแพ็คเกจ Crystal Reports for Visual Studio และที่จะทำให้เรื่องแย่ลงพวกเขาก็ติดอยู่ใน GAC ซึ่งจะทำให้ การพึ่งพาระหว่างเครื่องจักรของคุณเป็นฝันร้าย
Jeremy Holovacs

คำตอบ:


65

นี่คือวิธีที่ฉันได้รับสิ่งต่างๆที่ทำงานร่วมกับเวอร์ชัน 1.2.11.0

  1. สาปแช่ง apache สำหรับการเปลี่ยนคีย์ตั้งแต่แรก :)
  2. ดาวน์โหลดเวอร์ชัน 1.2.11.0 ที่เซ็นชื่อด้วยคีย์เก่า
  3. จัดเรียงรหัสของคุณเองโดยลบการอ้างอิงโดยตรงไปยัง log4net (คีย์ใหม่) และแทนที่ด้วยการอ้างอิงไปยังแอสเซมบลีที่ลงนามด้วยคีย์เก่า
  4. จัดเรียงแอสเซมบลีที่อ้างอิงใด ๆ ที่คุณอาจมีโดยรวมเซ็กเมนต์นี้ใน 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
การดาวน์โหลดเวอร์ชันที่เซ็นชื่อด้วยคีย์สาธารณะเก่าเป็นสิ่งที่จำเป็นเนื่องจากไม่สามารถทำการเปลี่ยนเส้นทางการผูกไปยังแอสเซมบลีที่มีคีย์สาธารณะอื่นได้
David Christiansen

2
ดูเหมือนว่าจะล้มเหลวเนื่องจากการเปลี่ยนแปลงอย่างรุนแรงใน 1.2.11.0: netpl.blogspot.com/2012/03/…
sydneyos

มีใครพบวิธีแก้ปัญหาที่อธิบายไว้ในลิงค์ที่กล่าวถึงโดย @sydneyos ซึ่งทำให้เกิดข้อยกเว้นดังต่อไปนี้:Method not found: 'Void log4net.Config.BasicConfigurator.Configure()'
นีโอ

ไม่มีวิธีแก้ไขอื่นนอกจากการดาวน์เกรดเป็น 1.2.10 น่าเสียดาย (หรือคอมไพล์ใหม่ทุกชุดประกอบที่คุณใช้)
bk0

1
ใส่แอสเซมบลี 1.2.10 ในไดเร็กทอรีอื่นและใช้ config นี้: '<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

ฉันใช้ log4net เวอร์ชันล่าสุดที่ดาวน์โหลดผ่าน nuget อย่างไรก็ตามหนึ่งในไลบรารีที่ฉันใช้นั้นต้องใช้เวอร์ชันเก่า ปัญหาของฉันทำให้ฉันเจอคำถามนี้

ปัญหากับคำตอบอื่น ๆ คือพวกเขากำลังใช้เวอร์ชัน dll เดียวกันสำหรับการผูกทั้งหมด ฉันต้องการใช้คุณสมบัติในเวอร์ชันใหม่สำหรับทุกอย่างยกเว้นการพึ่งพาเดิม

เพื่อให้สามารถทำได้คุณต้องทำสิ่งต่อไปนี้:

  1. เริ่มต้นด้วยการดาวน์โหลดเวอร์ชันเก่า (เวอร์ชัน 1.2.11.0)
  2. เปลี่ยนชื่อไบนารีที่ดาวน์โหลดมาlog4net.1.2.10.dllเป็น รวมไว้ในโปรเจ็กต์เริ่มต้นของคุณโดยตั้งค่าBuild actionเป็นNoneและ "Copy if newer" ป้อนคำอธิบายภาพที่นี่
  3. บอก. NET ว่าจะหาเวอร์ชันเก่าได้ที่ไหน:

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>

hrefแอตทริบิวต์ระบุที่เป็นรุ่นเก่า ดังนั้นคำขออื่น ๆ ทั้งหมดสำหรับ log4net จะชี้ไปที่เวอร์ชันใหม่


4
นี่เป็นทางออกที่ยอดเยี่ยมเพราะช่วยให้คุณสามารถรักษาทั้งสองเวอร์ชันสำหรับไลบรารีที่อ้างอิงอย่างใดอย่างหนึ่ง
SouthShoreAK

2
ขอบคุณ! สิ่งนี้ช่วยฉันได้ ฉันต้องเปลี่ยน "คัดลอกไปยังไดเรกทอรีผลลัพธ์" เป็น "ห้ามคัดลอก" แต่อย่างอื่นมันใช้งานได้ดี!
Daniel Hedenström

3

คุณสามารถดาวน์โหลด log4net 1.2.11.0 เวอร์ชันที่เซ็นชื่อด้วยคีย์เก่าได้ เหตุผลที่เปลี่ยนเป็นคีย์ใหม่มีอธิบายไว้ในคำถามที่พบบ่อย:

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

(โดยทั่วไปคีย์ใหม่จะเปิดเผยต่อสาธารณะและด้วยเหตุผลบางประการพวกเขาไม่ต้องการรวมคีย์เก่าในการแจกจ่ายฉันไม่ทราบแน่ชัดว่าเหตุใดจึงไม่เพียงทำให้คีย์เก่าเปิดเผยต่อสาธารณะ)


10
แต่เมื่อฉันใช้ไลบรารีของบุคคลที่สามซึ่งเชื่อมโยงกับคีย์ใหม่ฉันก็ยังติดอยู่ (ใช่มั้ย?) ไม่ใช่ตัวเลือกของฉันที่จะใช้ log4net ใหม่ แต่เป็นกรอบงานของบุคคลที่สาม ฉันไม่เห็นว่าสิ่งนี้จะไม่ระเบิดในทุกคนเนื่องจากเฟรมเวิร์กเริ่มใช้ log4net ด้วยคีย์ใหม่มากขึ้นเรื่อย ๆ
AndreasKnudsen

ที่ถูกต้องอย่างน่าเสียดาย ฉันเดาว่าคุณต้องพิจารณาไม่ให้ส่วนประกอบทั้งหมดใช้ log4net เวอร์ชันเดียวกัน ...
Stefan Egli

1
.... แล้วฉันจะไปทำอย่างนั้นได้อย่างไร? มีกลไกใดใน. net สำหรับจัดการปัญหานี้หรือไม่?
AndreasKnudsen


1

ไม่ทราบว่าเหมาะสำหรับกรณีเฉพาะของคุณหรือไม่ แต่คุณสามารถคอมไพล์เฟรมเวิร์กใหม่ได้ดังนั้นพวกเขาจะใช้ log4net ด้วยคีย์สาธารณะเดียวกัน ในกรณีของฉันคือ FluentNHibernate ซึ่งใช้ log4net 1.2.10 และ Combres กับ log4net 1.2.11 พร้อมคีย์ใหม่ ฉันดาวน์โหลด log4net 1.2.11 ที่ลงนามด้วยคีย์เก่าและคอมไพล์ Combress ใหม่ด้วย หลังจากนั้นเพิ่มการเปลี่ยนเส้นทางการผูกแอสเซมบลีจาก 1.2.10 เป็น 1.2.11 และเริ่มทำงาน


0

สิ่งนี้อาจไม่ได้ผลในทุกกรณี แต่เนื่องจากโปรเจ็กต์ที่ใช้ log4net เป็น OSS ที่ฉันดาวน์โหลดซอร์สมาแทนที่ log4net เวอร์ชันที่ขัดแย้งกันด้วยเวอร์ชันที่ฉันใช้และสร้างโปรเจ็กต์ใหม่ ในกรณีของฉันมันคือ Topshelf ดังนั้นตอนนี้ฉันมีชุดประกอบ Topshelf เวอร์ชันที่สร้างขึ้นด้วย log4net เวอร์ชันเดียวกับที่ฉันใช้และตอนนี้ฉันสามารถอ้างอิงทั้งสองอย่างได้โดยไม่มีปัญหา


0

ฉันพยายามไปที่ลิงก์ที่ให้ไว้ด้านบน แต่ดูเหมือนว่าลิงก์ทั้งหมดในไซต์ Apache จะไม่ทำงาน นี่คือสิ่งที่ฉันทำเพื่อแก้ไขปัญหา:

จาก Visual Studio ให้ใช้ Nuget เพื่อดาวน์โหลดและติดตั้ง log4net เวอร์ชันล่าสุด (1.2.13.0) ตัวจัดการแพ็คเกจ NuGet จะดาวน์โหลดและอัปเกรด log4net (1.2.11.0) ทั้งหมดเป็นเวอร์ชันล่าสุดโดยอัตโนมัติ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.