2010-04-25 15 views
6

यह एक बड़ी बात है।जेडीबीसी/ओएसजीआई और बंडल में निर्भरता को स्पष्ट रूप से बताए बिना ड्राइवरों को गतिशील रूप से लोड कैसे करें?

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

मैं अभी लगभग 30 जारों पर निर्भर हूं और मध्य-मार्ग हूं हालांकि उन्हें बांध रहा हूं। अब मेरे कुछ मॉड्यूल वर्जन की निर्भरताओं की घोषणा करना आसान है, जैसे कि मेरे नेटवर्किंग घटक। वे जेआरई और अन्य बीएनडीएड पुस्तकालयों के भीतर सांख्यिकीय रूप से कक्षाओं का संदर्भ देते हैं लेकिन मेरे जेडीबीसी से संबंधित घटक क्लास.forनाम (...) के माध्यम से तत्काल होते हैं और किसी भी ड्राइवर में से किसी एक का उपयोग कर सकते हैं।

मैं सेवा क्षेत्र द्वारा ओएसजीआई बंडलों में सबकुछ तोड़ रहा हूं।

  • मेरे मूल कक्षाएं/इंटरफेस।
  • संबंधित घटकों की रिपोर्ट करना।
  • डेटाबेस एक्सेस संबंधित घटक (जेडीबीसी के माध्यम से)।
  • आदि ....

मैं अपने कोड अभी भी अपने सभी निर्भरता के साथ और सभी (JARJAR के माध्यम से) OSGi बिना एक जार फ़ाइल के माध्यम से OSGi बिना इस्तेमाल किया जा रहा है और यह भी मॉड्यूलर होने के लिए सक्षम होने के लिए के लिए इच्छा ओएसजीआई मेटा-डेटा और निर्भरता जानकारी के साथ दानेदार बंडलों के माध्यम से।

  • मैं अपने बंडल और मेरी कोड कैसे कॉन्फ़िगर करूँ इतना है कि यह गतिशील classpath पर और/या OSGi कंटेनर पर्यावरण के भीतर किसी भी ड्राइवर का उपयोग कर सकते (फेलिक्स/विषुव/आदि।)?

  • क्या यह पता लगाने के लिए एक रन-टाइम विधि है कि क्या मैं ओएसजीआई कंटेनर में चल रहा हूं जो कंटेनरों (फ़ेलिक्स/विषुव/आदि) में संगत है?

  • क्या मुझे ओएसजीआई कंटेनर में एक अलग वर्ग लोडिंग तंत्र का उपयोग करने की आवश्यकता है?

  • क्या मुझे अपने प्रोजेक्ट में ओएसजीआई कक्षाएं आयात करने की आवश्यकता है ताकि मेरे डेटाबेस मॉड्यूल के माध्यम से एक-बंडल-टाइम-अज्ञात जेडीबीसी ड्राइवर लोड हो सके?

  • मैं भी, एक ड्राइवर (JNDI के माध्यम से है, जो केवल वास्तव में लागू होता है जब कोई ऐप सर्वर में चल रहे) प्राप्त करने की एक दूसरी विधि है मैं OSGi अवगत अनुप्रयोग सर्वर के लिए मेरी JNDI एक्सेस कोड को बदलने की जरूरत है?

उत्तर

7
  • OSGi पर्यावरण के भीतर किसी भी ड्राइवर का उपयोग आप उपयोग करने की आवश्यकता एक DynamicImport-पैकेज: * बयान जब आप Class.forName (..) के साथ एक ड्राइवर लोड अपने बंडल इन पैकेजों को हल कर सकते हैं।
  • शायद सबसे आसान तरीका org.osgi.framework पैकेज में मौजूद किसी वर्ग तक पहुंचने का प्रयास करना है। उन लोगों को कम से कम हमेशा एक ओएसजीआई वातावरण में होना चाहिए (नीचे स्निपेट देखें)। अधिक परिष्कृत तंत्र हैं, इसलिए मुझे कुछ और उन्नत की आवश्यकता होने पर मुझे बताएं। साथ ही, ओएसजीआई आर 4.2 कोर स्पेक, अनुच्छेद 3.8.9 पर एक नज़र डालें जो एक वर्ग के बंडल और बंडल कॉन्टेक्स्ट को खोजने के कुछ तरीकों को दिखाता है और इसलिए अप्रत्यक्ष यह निर्धारित करने में सहायता करता है कि आप ढांचे में हैं या नहीं।
  • यह आपके द्वारा किए जा रहे कार्यों पर निर्भर करता है, यहां कोई सामान्य "हां" या "नहीं" उत्तर है। ओएसजीआई क्लासलोडर्स का उपयोग करता है और ऐसा करता है जो एक मानक जावा एप्लिकेशन के लिए "ठेठ" नहीं है, लेकिन आप जो कर रहे हैं उसके आधार पर, आपको नोटिस नहीं हो सकता है।
  • सं।
  • हाल ही में जारी ओएसजीआई एंटरप्राइज़ चश्मे पर एक नज़र डालें। उनके पास ओएसजीआई में जेएनडीआई एकीकरण पर एक अध्याय है जो शायद आपको अपना कोड छोड़ने की अनुमति देता है (काफी हद तक) असम्बद्ध।

एक साधारण उदाहरण टुकड़ा:

public static boolean inOSGi() { 
    try { 
    Class.forName("org.osgi.framework.FrameworkUtil"); 
    return true; 
    } 
    catch (ClassNotFoundException e) { 
    return false; 
    } 
} 

बस सुनिश्चित करें कि आप अगर आप एक बंडल में इस कोड डाल दिया, बंडल org.osgi.framework आयात करना चाहिए बनाने के (अन्यथा यह उस वर्ग कभी नहीं मिलेगा) ।

+0

जानकारी के लिए धन्यवाद, विशेष रूप से DynamicImport-पैकेज: * टिप जो आश्चर्यजनक रूप से मैं इंटरनेट खोज के माध्यम से नहीं मिल सका। दूसरे उत्तर के संबंध में, यदि आपके पास समय है तो एक स्निपेट अच्छा हो सकता है। जैसा कि आपने मेरे मुख्य प्रश्नों के उत्तर दिए हैं, वैसे भी मैं इसे अनुमोदित उत्तर के रूप में ध्वजांकित करूंगा। धन्यवाद। – Chris

0

मैंने ओसीजीआई के लिए एक ग्रहण आरसीपी में एक जेडीबीसी चालक प्रबंधक बनाया और मैं आपको ओएसजीआई के साथ अच्छा खेलना सीखूंगा। सबसे पहले, डायनामिक इंपोर्ट-पैकेज के बारे में भूल जाओ, ओएसजीआई का उपयोग करने का एकमात्र अच्छा तरीका बंडलों को स्थापित/प्रारंभ/बंद करना है और ओएसजीआई तंत्र का उपयोग जिस तरह से किया गया था, उसका उपयोग करना है।

  1. आप अपने JDBC- बंडल है, और एक और "ड्राइवर बंडल" जो DriverClass, कनेक्शन तर्क का प्रारंभ है बना सकते हैं और dbcp2 और pool2 के रूप में इस तरह के आवश्यक कॉमन्स पुस्तकालयों जोड़ें।

  2. चालक बंडल को एक जार/ज़िप के रूप में निर्यात करें और इसे अपने जेडीबीसी बंडल में संसाधन के रूप में शामिल करें।

  3. अपने जेडीबीसी बंडल को अपने कार्यक्षेत्र में चालक बंडल को अनजिप करने दें।

    String workdir= Platform.getStateLocation(jdbc_bundle).toPortableString(); 
    
  4. प्रोग्राम चालक जार जोड़ सकते हैं और उसके अनुसार चालक बंडल के MANIFEST.MF फ़ाइल को संशोधित।

  5. लोड कार्य क्षेत्र से चालक बंडल प्रोग्राम के रूप में

    getBundleContext().installBundle("file:/"+workdir); 
    
  6. उपयोग bundle.start(), बंद करो(), स्थापना रद्द करें() के रूप में आवश्यक जब प्रोग्राम के रूप में ड्राइवरों की सूची को संशोधित।

0

पैक्स-JDBC, कथात्मक तरीका के माध्यम से datasources को सौंपने के लिए इस्तेमाल किया जा सकता आप ConfigAdmin सेवा में एक config प्रविष्टि बना सकते हैं इसका मतलब है, और डेटा स्रोत JNDI के माध्यम से पहुँचा जा सकता है। जेडीबीसी चालक को बंडल के रूप में तैनात किया गया है। (उनमें से ज्यादातर OSGi संस्करण है)

उदाहरण के लिए:

config प्रविष्टि पीआईडी ​​है org.ops4j.datasource परीक्षण

गुण:

osgi.jdbc.driver.name=H2 
databaseName=test 
user=sa 
password= 
dataSourceName=testds-h2 

सेवा द्वारा पहचाना जाता है दिया गया डेटा स्रोत नाम। तो आप इसके लिए फ़िल्टर कर सकते हैं (& (objectClass = javax.sql.DataSource) (डेटासोर्सनाम = test2))।

और तुम JNDI के माध्यम से डेटा स्रोत का उपयोग कर सकते हैं:

osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=test2) 
संबंधित मुद्दे