2010-03-15 15 views
8

मैं कोड का एक टुकड़ा पैकेज करना चाहता हूं जो को जावा 1.5 पर चलाना चाहिए। कोड का एक हिस्सा है जहां वीएम 1.6 वीएम है, तो प्रोग्राम को "बढ़ाया जा सकता है"।जावा: जावा 1.5 और 1.6 कोड दोनों को पैकेज करने का सबसे आसान तरीका

मूल रूप से यह इस पद्धति है:

private long[] findDeadlockedThreads() { 
    // JDK 1.5 only supports the findMonitorDeadlockedThreads() 
    // method, so you need to comment out the following three lines 
    if (mbean.isSynchronizerUsageSupported()) 
     return mbean.findDeadlockedThreads(); 
    else 
     return mbean.findMonitorDeadlockedThreads(); 
    } 

इस 1.5 पर संकलन और अभी तक 1.6 प्रणाली को बुलाती है जब 1.6 पर क्या है करने के लिए सबसे आसान तरीका होगा क्या?

अतीत में मैंने एक अद्वितीय 1.6 वर्ग को संकलित करके कुछ ऐसा किया है जो मैं अपने ऐप के साथ पैकेज करता हूं और 1.6 पर जब क्लासलोडर का उपयोग कर तत्काल उपयोग करता हूं (क्योंकि 1.6 जेवीएम पूरी तरह से 0x32 और 0x31 कक्षाओं को मिलाकर ठीक करता है), लेकिन मुझे लगता है कि यह थोड़ा अधिक है (और थोड़ा दर्दनाक है क्योंकि निर्माण प्रक्रिया के दौरान आपको 0x31 और 0x32 .class फ़ाइलों दोनों बनाना होगा)।

अगर मैं उपरोक्त विधि 1.5 पर संकलित करना चाहता हूं तो मुझे कैसे जाना चाहिए? हो सकता है कि प्रतिबिंब का उपयोग कर, लेकिन फिर कैसे

नोट (मैं प्रतिबिंब से परिचित नहीं हूँ): (लेकिन मैं नहीं करना चाहती http://www.javaspecialists.eu/archive/Issue130.html

: यदि आप उत्सुक हैं, उपरोक्त विधि इस लेख से आता है "तीन पंक्तियों पर टिप्पणी करें" लेख में, मैं इसे 1.5 और 1.6 दोनों पर संकलित और चलाने के लिए चाहता हूं)

उत्तर

3

आप इसे 1.5 पर संकलित नहीं कर सकते हैं, लेकिन आप लक्ष्य-विकल्प सेट 1.5 के साथ 1.6 पर संकलित कर सकते हैं (जो 1.5 के लिए बाइट-कोड उत्पन्न करेगा) और यह पता लगाने के लिए कि विधि उपलब्ध है या नहीं, प्रतिबिंब का उपयोग करके कोड में।

यह कोड विधि को देखेगा: mbean.getClass()। GetMethod ("findDeadlockedThreads", नई कक्षा [0]); समस्या यह है कि अगर यह शून्य या कुछ समान लौटने की बजाय विधि मौजूद नहीं है, तो यह NoSuchMethodException फेंकता है। इसका मतलब है, आपको इस तरह के कोड की आवश्यकता है:

try 
{ 
    mbean.getClass().getMethod("findDeadlockedThreads", new Class<?>[0]); 
    return mbean.findDeadlockedThreads(); 
} 
catch(NoSuchMethodException ex) 
{ 
    return mbean.findMonitorDeadlockedThreads(); 
} 

यह बहुत अच्छा नहीं है, क्योंकि यह निर्णय लेने के लिए अपवाद का उपयोग करता है। शायद यह बहुत तेज़ नहीं है। वैकल्पिक रूप से getMethods का उपयोग करना और आपकी विधि उपलब्ध होने पर लौटाई गई सूची पर फिर से उपयोग करना है। यह भी बहुत तेज़ नहीं है।

संपादित करें: क्रिस्टोफर ओज़बेक केवल एक बार विधि के अस्तित्व की जांच करने के लिए टिप्पणियों में सुझाव देता है और परिणाम को बचाने के लिए ओवर -हेड से बचने के लिए परिणाम बचाता है। यह सही है और एक अच्छा समाधान है। मैट बी चेतावनी देता है कि जावा-कंपाइलर का लक्ष्य-विकल्प जांच नहीं करता है, यदि जावा 1.5 के तहत उपयोग की जाने वाली कक्षाएं और विधियां उपलब्ध हैं। यह सही है (और अन्यथा यह काम नहीं करेगा, क्योंकि आप 1.6-विधि के खिलाफ संकलन करना चाहते हैं) और इसका मतलब है कि इस समस्या से बचने के लिए कार्यक्रम को 1.5-वीएम के तहत सावधानीपूर्वक परीक्षण किया जाना चाहिए। आप दोनों की टिप्पणियों के लिए धन्यवाद।

+0

@Mnementh: ठीक है, लेकिन फिर क्या होगा प्रतिबिंब कोड देखो की तरह ? – SyntaxT3rr0r

+0

मैंने प्रतिबिंब-कोड शामिल करने के लिए अपना उत्तर संपादित किया। – Mnementh

+0

@Mnementh: +1 शानदार ... मैं इसे आज दोपहर सेट करने की कोशिश करूंगा :) – SyntaxT3rr0r

2

1.5 के लिए संकलन।

आपके कोड में प्रतिबिंब का उपयोग करें। आप क्लास इंटरफ़ेस से विधि ऑब्जेक्ट प्राप्त कर सकते हैं; इसमें एक चालान विधि है जो आपके एमबीएन उदाहरण को पैरामीटर के रूप में लेती है। कुछ ऐसा:

कक्षा सी = mbean.getClass(); // यह

विधि m = c प्राप्त करने के लिए YourClass.class भी कर सकता है।getMethod ("findMonitorDeadLockedThreads"); // या किसी अन्य विधि ( विधि के लिए मानकों को कक्षा में निर्दिष्ट होती getMethod करने के लिए ... दूसरा पैरामीटर)

m.invoke (MBean) // अपने उदाहरण के साथ विधि invokes

बेशक

आप डॉन हर बार ऐसा करने के लिए नहीं है; एक कन्स्ट्रक्टर में विधि संदर्भ सेट करें और फिर मांग पर दाहिनी ओर आओ।

+0

@ दांपाक: विधि के पास जाने के लिए कोई पैरामीटर नहीं है, यह एक साधारण मामला है। तो मन्मेन्थ से और आपके जवाब में मैं इसे प्रतिबिंबित करने का तरीका लेता हूं ... इसलिए मैं यहां सुझाए गए प्रयासों का प्रयास करूंगा। – SyntaxT3rr0r

+0

@WizardOfOdds: अगर आपको लगता है कि यह सुझाव मूल्यवान है, तो कृपया इसे ऊपर उठाएं। –

1

मैवेन आपको प्रोफाइल के साथ आसानी से ऐसा करने देता है। प्रोफाइल के पीछे विचार यह है कि आप कुछ मानदंडों के आधार पर चीजों के दो अलग-अलग संस्करण बनाना चाहते हैं। इस विशिष्ट उदाहरण में, आप jdk15 और jdk16 प्रोफ़ाइल को परिभाषित कर सकते हैं, निर्दिष्ट करें कि प्रत्येक जेडीके संस्करण किसके साथ संकलित करें, और इसे jdk15 प्रोफ़ाइल में कक्षा की एक प्रति और अन्य jdk16 में शामिल करने के लिए कहें।

आरंभ करने के लिए, देखें:

http://unserializableone.blogspot.com/2008/09/compile-and-test-with-different-jdk.html

यह बताता है कि कैसे इस समस्या के विभिन्न JDK संस्करण योगदान दें।

समस्या के दूसरे भाग को संभालने के लिए JDK संस्करण के आधार पर वर्ग का एक अलग परिभाषा का उपयोग, इस देखें:

Maven - Include Different Files at Build Time

+0

क्षमा करें, उम्मीद है कि मदद करता है ... मेरे पास पूर्ण मैवेन बिल्ड स्क्रिप्ट दिखाने के लिए अभी एक पल मुक्त नहीं है। –

+0

बस यह सुनिश्चित करने के लिए कि मैं समझता हूं कि आपने सही तरीके से क्या कहा है: मुझे एक अद्वितीय * .jar * पैक करना और 1.5 और 1.6 दोनों पर काम करना है जो 1.6 पर 1.6 सुविधाओं का उपयोग करता है, क्या मैं इसे माव प्रोफाइल के साथ कर सकता हूं? – SyntaxT3rr0r

+0

@WizardOfOdds: हां, यही वह है जिसे मैंने पहले वर्णन करने की कोशिश की थी। मैंने लिंक का जवाब देने के लिए अपनी प्रतिक्रिया में संशोधन किया है कि यह वर्णन करने से बेहतर तरीके से कैसे किया जा सकता है। –

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