2012-08-01 19 views
13

में एकाधिक एसएलएफ 4 जे बाइंडिंग को हल करें यह एक प्रश्न है जो एसई साइटों पर similar questions के गुच्छा की तरह लगता है, इसलिए मुझे अपना प्रश्न स्पष्ट करने के लिए काफी वर्बोज़ होना चाहिए। तो, यहाँ परियोजना की न्यूनतम pom.xml है:मेवेन प्रोजेक्ट

<dependencies> 
    <dependency> 
     <groupId>ch.qos.logback</groupId> 
     <artifactId>logback-classic</artifactId> 
     <version>1.0.6</version> 
    </dependency> 

    <dependency> 
     <groupId>org.codehaus.gmaven.runtime</groupId> 
     <artifactId>gmaven-runtime-1.7</artifactId> 
     <version>1.3</version> 
    </dependency> 

</dependencies> 
<build> 
    <plugins> 
     <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>exec-maven-plugin</artifactId> 
      <version>1.2.1</version> 
      <configuration> 
       <mainClass>org.shabunc.App</mainClass> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

यहाँ निर्भरता पेड़ Maven द्वारा उत्पादित है।

mvn dependency:tree -Dverbose -Dincludes=org.slf4j:

[INFO] [dependency:tree {execution: default-cli}] 
[INFO] org.shabunc:logdebug:jar:1.0-SNAPSHOT 
[INFO] \- ch.qos.logback:logback-classic:jar:1.0.6:compile 
[INFO] \- org.slf4j:slf4j-api:jar:1.6.5:compile 

अब, चलो बहिष्करण को निकाला और निर्भरता फिर से जाँच करें। हम प्राप्त करेंगे:

[INFO] org.shabunc:logdebug:jar:1.0-SNAPSHOT 
[INFO] +- ch.qos.logback:logback-classic:jar:1.0.6:compile 
[INFO] | \- org.slf4j:slf4j-api:jar:1.6.5:compile 
[INFO] \- org.codehaus.gmaven.runtime:gmaven-runtime-1.7:jar:1.3:compile 
[INFO] +- (org.slf4j:slf4j-api:jar:1.5.10:compile - omitted for conflict with 1.6.5) 
[INFO] +- org.codehaus.gmaven.feature:gmaven-feature-support:jar:1.3:compile 
[INFO] | \- (org.slf4j:slf4j-api:jar:1.5.10:compile - omitted for conflict with 1.6.5) 
[INFO] \- org.codehaus.gmaven.runtime:gmaven-runtime-support:jar:1.3:compile 
[INFO]  +- (org.slf4j:slf4j-api:jar:1.5.10:compile - omitted for conflict with 1.6.5) 
[INFO]  \- org.sonatype.gshell:gshell-io:jar:2.0:compile 
[INFO]   \- org.sonatype.gossip:gossip:jar:1.0:compile 
[INFO]    \- (org.slf4j:slf4j-api:jar:1.5.8:compile - omitted for conflict with 1.6.5) 

तो, जैसा कि हम देख सकते हैं, सब कुछ अपेक्षित काम करता है, और विरोधाभासी निर्भरता वास्तव में बाहर निकलती है। लेकिन बात यह है कि निर्भरता भी साथ बाहर रखा गया मैं अभी भी संदेश का अनुसरण करते हुए संकलन और mvn exec:java बुला मिलता है:

SLF4J: Class path contains multiple SLF4J bindings. 
SLF4J: Found binding in [jar:file:/home/shabunc/.m2/repository/ch/qos/logback/logback-classic/1.0.6/logback-classic-1.0.6.jar!/org/slf4j/impl/StaticLoggerBinder.class] 
SLF4J: Found binding in [jar:file:/home/shabunc/.m2/repository/org/sonatype/gossip/gossip/1.0/gossip-1.0.jar!/org/slf4j/impl/StaticLoggerBinder.class] 

सवाल यह है: क्यों मैं अभी भी यह चेतावनी दिखाई देती है और वास्तव में क्या केवल एक संस्करण बनाने के लिए किया जाना चाहिए निष्पादन के दौरान slf4j पहुंच योग्य?

+1

कोई अपराध इरादा नहीं है लेकिन slf4j-api पर निर्भरता घोषित करता है और फिर slf4j-api को छोड़कर गलत है। निम्नलिखित कथन भी गलत है। "आइए सुनिश्चित करें कि slf4j-api वास्तव में केवल लोड हो गया है, जैसा कि हमने अपेक्षा की थी जब हमने बहिष्करण/बहिष्करण भाग को gmaven-runtime निर्भरता में जोड़ा है।" जब निर्भरताएं एक आर्टिफैक्ट के विभिन्न संस्करणों की घोषणा करते हैं, उदा। slf4j-api, maven वर्ग पथ पर slf4j-api कई बार नहीं रखेगा। यहां तक ​​कि अगर मैवेन ने किया (जो यह नहीं करता है), slf4j-api कई बार लोड नहीं किया जाएगा। कृपया अपने प्रश्न को संपादित करें क्योंकि भविष्य के पाठकों को गुमराह न करें। – Ceki

+0

सेकी, यह ठीक रहेगा भले ही यह अपराध होगा जो मुझे कुछ सिखाएगा)) तथ्य यह है कि slf4j-api कई बार लोड किया जाता है, इस प्रकार जब मैं टॉमकैट के लिए युद्ध के रूप में तैनात करने की कोशिश कर रहा हूं तो संघर्ष बना रहा हूं। एक slf4j logblack में है और एक gmaven-runtime की निर्भरता की निर्भरता में है। अगर मुझे कुछ याद आ रहा है, तो यह बहुत दयालु होगा यदि आप इसे स्पष्ट कर देंगे, क्योंकि यह निर्भरता हल करने की बात यह नहीं है कि मैं एक विशेषज्ञ हूं। – shabunc

+0

यदि आप मेवेन का उपयोग कर रहे हैं तो आपके वर्ग पथ पर slf4j-api के विभिन्न संस्करण मौजूद होने का कोई जोखिम नहीं है। हालांकि, यह विभिन्न slf4j * बाइंडिंग * के लिए आम है, उदा। slf4j-jdj14.jar, slf4j-log4j.jar या logback-classic.jar कक्षा पथ पर एक साथ उपस्थित होने के लिए। आपके मामले में, आपके पास लॉगबैक-क्लासिक-1.0.6.jar गॉसिप-1.0.जर मौजूद है। टॉम एंडरसन ने पहले से ही 'गपशप' को छोड़कर एक अच्छा जवाब दिया है। – Ceki

उत्तर

18

आपकी समस्या SLF4J एपीआई की दो प्रतियां नहीं मिल रहा है, यह दो अलग अलग SLF4J कार्यान्वयन हो रही है की तरह कुछ जोड़ना है। आपको एपीआई नहीं, गॉसिप को बाहर करने की जरूरत है। ऐसा ही कुछ अर्थ है:

<dependency> 
    <groupId>org.codehaus.gmaven.runtime</groupId> 
    <artifactId>gmaven-runtime-1.7</artifactId> 
    <version>1.3</version> 
    <exclusions> 
     <exclusion> 
     <groupId>org.sonatype.gossip</groupId> 
     <artifactId>gossip</artifactId> 
     </exclusion> 
    </exclusions> 
</dependency> 

बातुनी निर्भरता gshell-io द्वारा घोषित है; उम्मीद है कि इसे वास्तव में गॉसिप की आवश्यकता नहीं है, इसे सिर्फ एक एसएलएफ 4 जे एसएलएफ 4 जे की जरूरत है, जिसे आप लॉगबैक के आकार में आपूर्ति कर रहे हैं।

+0

तो, क्या आपका मतलब है कि मैं बिना किसी नाटकीय परिणामों के गपशप निर्भरता को मुक्त कर सकता हूं?))) ठीक है, और यदि और भी अधिक निर्भरताएं हैं, जो बदले में, slf4j पर निर्भर करती हैं, यह जल्दी ही एक दुःस्वप्न बन जाएगी (( – shabunc

+1

एसएलएफ 4 जे को खुश करने का एकमात्र तरीका या तो लॉगबैक पर निर्भरता को दूर करना है, या गॉसिप पर gshell-io की निर्भरता को बहिष्कृत करें। हालांकि, मैं वादा नहीं कर सकता कि इसमें नाटकीय परिणाम नहीं होंगे। मुझे आशा है कि ऐसा नहीं होगा - पुस्तकालय के लिए लॉगिंग कार्यान्वयन पर प्रत्यक्ष निर्भरता होना बहुत खराब होगा –

+0

समस्या 2 अलग-अलग प्रदाताओं की वजह से है ... गॉसिप जार में इसके अंदर एक slf4j कार्यान्वयन है .. तो आपको या तो अपने निर्भरता पेड़ से लॉगबैक या गपशप को हटा देना चाहिए .. – Byter

1

मैं तुम्हें निर्भरता के दायरे के साथ खेलने की जरूरत है लगता है, देखें: http://www.mojohaus.org/exec-maven-plugin/java-mojo.html

classpathScope - को परिभाषित करता है classpath के दायरे प्लगइन करने के लिए पारित कर दिया। अपनी जरूरतों के आधार पर संकलन, परीक्षण, रनटाइम या सिस्टम को सेट करें।

+0

के प्रश्न को बनाए रखने के लिए, कृपया, कृपया अधिक विशिष्ट हो, मुझे अभी भी यह नहीं पता कि क्लासपाथस्कोप सेटिंग इस समस्या को हल करने में कैसे मदद करेगी। – shabunc

3

तुम सब करने की ज़रूरत है इस

compile "org.sonatype.gossip:gossip:1.0" { 
    exclude module:'slf4j-jcl' 
    exclude module:'slf4j-log4j12' 
} 
+0

समस्या गॉसिप जार के पारगमन निर्भरता के कारण हुई है। उपरोक्त कोड गपशप से sl4j कार्यान्वयन की निर्भरता को बाहर कर देगा। – Byter

+2

"इस तरह कुछ" यहां का अर्थ है "इस ग्रैडल कोड के बराबर मेवेन"! –

+0

@ टॉम एंडरसन या ... माफ करना मैंने इसका उल्लेख नहीं किया :) – Byter

संबंधित मुद्दे