2011-11-04 14 views
6

मैं स्काला 2.9.1स्काला 2.9 ब्रिज-विधि

उपयोग कर रहा हूँ मैं इस तरह के रूप में एक लॉगिंग विशेषता परिभाषित किया है:

trait Logging { 
    def debug(msg: String, throwables: Throwable*) = .... 
    .... 
} 

और मैं एक JMSPublisher वर्ग जो मिक्स में लॉगिंग विशेषता है :

class JMSPublisher extends Publisher with Logging { 
    def publishProducts(list: List[_ <: Product]) = .... 
    def publish(list: Seq[Product]) = .... 
} 

यह सब ठीक संकलित करता है। मेरी समस्या यह है कि मेरे पास एक ऐसा उपयोगकर्ता है जो मेरे जेएमस्पब्लिशर को स्प्रिंग में लोड करना चाहता है। वह वसंत 2.5.6 का उपयोग कर रहा है।

जब स्टार्टअप के दौरान एप्लिकेशन कॉन्टेक्स्ट लोड किया जाता है, तो ऐप एक अवैध स्टाइल अपवाद के साथ क्रैश हो जाता है, शिकायत करता है कि यह मेरे लॉगिंग विशेषता से संबंधित ब्रिज-विधि नहीं ढूंढ सकता है।

Initialization of bean failed; nested exception is java.lang.IllegalStateException: Unable to locate bridged method for bridge method 'public void com.app.messaging.JmsPublisher.debug(java.lang.String, scala.collection.Seq)' 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480) 
    .....stack trace follows....... 

इस कोड को स्काला 2.8 के तहत काम किया, और मैंने सुना है कि स्काला विशेषता के रूप में 2.9 में पाट कुछ तरीकों है कि अंकन है। मुझे लगता है कि वसंत असफल होने के कारण यही है। मैं स्काला-2.9 में अपग्रेड नहीं कर सकता अगर मेरी कक्षा वसंत द्वारा लोड नहीं की जा सकती है।

क्या कोई इस मुद्दे में भाग लेता है? क्या कोई फिक्स या काम-आसपास है?

+0

मुझे लगता है कि हमें कुछ मिल रहा है - सौभाग्य से यह हमारे वास्तविक ऐप को प्रभावित नहीं कर रहा है, बस स्प्रिंग आईडीई जो कुछ बीन्स को त्रुटियों के साथ चिह्नित करता है क्योंकि यह शिकायत करता है कि कुछ विशेषता-परिभाषित विधियां मौजूद नहीं हैं। – Nick

+1

इसे देखें: http://stackoverflow.com/questions/8748625/why-are-concrete-function-implementations-in-traits-compiled-to-bridge-methods-i – Janx

उत्तर

3

हमने वही चीज़ देखी। मैंने कभी नहीं सोचा कि स्कैला 2.9.एक्स में किस बदलाव ने इसे ट्रिगर किया, लेकिन मुझे लगता है कि वास्तविक समस्या स्प्रिंग के साथ ही है।

जब आप कक्षा में एक विशेषता को मिलाते हैं, तो कक्षा में सिंथेटिक विधियों को जोड़ता है, जो बाइट कोड में पुल विधियों के रूप में चिह्नित है, जो कि विशेषता में विधि के कार्यान्वयन के लिए आगे है।

जावा कक्षाओं में ब्रिज विधियों को भी जोड़ता है, जब एक उप-वर्ग सुपरक्लस या इंटरफ़ेस में किसी विधि को ओवरराइड करता है, लेकिन रिटर्न प्रकार को परिशोधित करता है। चूंकि रिटर्न प्रकार बाइटकोड स्तर पर विधि हस्ताक्षर का हिस्सा है, इसलिए अग्रेषण विधि की आवश्यकता होती है ताकि क्लाइंट जो केवल माता-पिता विधि हस्ताक्षर को जानते हैं, अब भी उप-वर्ग में विधि को कॉल कर सकते हैं। (अधिक जानकारी: what java.lang.reflect.Method.isBridge() used for?)

वसंत लेख A Bridge Too Far में वर्णित कारणों के लिए पुल विधियों के लिए बाइटकोड का निरीक्षण करता है। उस लेख का नाम विडंबनापूर्ण है - स्प्रिंग इस "स्प्रिंग का एक आदर्श उदाहरण है जो कठोर आधारभूत संरचना समस्याओं को हल करता है जो जावा डेवलपर्स का सामना करते हैं और उन्हें एप्लिकेशन स्टैक में एकीकृत करते हैं", लेकिन यह बाइटकोड के स्रोत के बारे में बहुत अधिक धारणा करता है, और बदतर, अक्षम नहीं किया जा सकता है।

शॉर्ट टर्म वर्कअराउंड, स्प्रिंग में उपयोग की जाने वाली कक्षाओं में मिश्रण गुणों से बचने के लिए है। आपको गैर-जावा बाइटकोड के लिए इस चेक को अक्षम करने की अनुमति देने के लिए आपको स्प्रिंग के साथ एक बग लॉज करना चाहिए।