2009-06-25 9 views
50

यह पैकेज है कि यह अनुक्रमण होना चाहिए में सही नहीं है,। फिर भी, जब मैं फोनअपाचे फ़ेलिक्स के अंदर चलते समय JAXB मेरे jaxb.index को क्यों नहीं ढूंढ सकता?

JAXBContext jc = JAXBContext.newInstance("my.package.name"); 

मैं एक JAXBException कह रही है कि

"my.package.name" does not को ObjectFactory.class या jaxb.index

होते हैं, हालांकि यह शामिल है मिल दोनों।

काम करता है, लेकिन काफी मैं क्या चाहते हैं नहीं है क्या,

JAXBContext jc = JAXBContext.newInstance(my.package.name.SomeClass.class); 

विभिन्न अन्य लोगों से यह सवाल काफी कुछ मेलिंग सूची और मंचों पर दिखाई देता है लेकिन मालूम होता है जवाब पाने नहीं करता है।

मैं OpenJDK 6 पर इस चल रहा हूँ, इसलिए मैं स्रोत संकुल मिला है और पुस्तकालय में मेरी डिबगर कदम रखा। यह jaxb.properties की तलाश द्वारा शुरू होता है तो प्रणाली संपत्तियों के लिए लग रहा है और या तो लगता है करने में नाकाम रहने, यह com.sun.internal.xml.bind.v2.ContextFactory का उपयोग कर डिफ़ॉल्ट संदर्भ बनाने के लिए कोशिश करता है। वहाँ में, अपवाद (ContextFactor.createContext(String ClassLoader, Map) अंदर) फेंक दिया जाता है, लेकिन मैं नहीं देख सकते हैं क्या हो रहा है, क्योंकि स्रोत यहाँ नहीं है।

ईटीए:

ContentFactory के लिए स्रोत कोड से परखने के बाद, मैं here पाया, यह शायद कोड का टुकड़ा है कि उद्देश्य के अनुसार कार्य करने में विफल रहता है:

/** 
* Look for jaxb.index file in the specified package and load it's contents 
* 
* @param pkg package name to search in 
* @param classLoader ClassLoader to search in 
* @return a List of Class objects to load, null if there weren't any 
* @throws IOException if there is an error reading the index file 
* @throws JAXBException if there are any errors in the index file 
*/ 
private static List<Class> loadIndexedClasses(String pkg, ClassLoader classLoader) throws IOException, JAXBException { 
    final String resource = pkg.replace('.', '/') + "/jaxb.index"; 
    final InputStream resourceAsStream = classLoader.getResourceAsStream(resource); 

    if (resourceAsStream == null) { 
     return null; 
    } 

मेरी previousexperience से, मेरा अनुमान है कि इस OSGi कंटेनर के वर्ग लोड हो रहा है तंत्र है कि इस में चल रहा है के साथ क्या करना है। दुर्भाग्य से, मैं अभी भी एक छोटे से मेरी गहराई यहाँ से बाहर हूँ।

+0

मेरा मतलब है कि अपवाद स्टैक ट्रेस पोस्ट करें। – akarnokd

+0

पोस्ट पहले से थोड़ा लंबा हो रहा है, लेकिन मैंने पहले ही अपवाद की उत्पत्ति को ट्रैक किया है, बस इसे ऊपर पोस्ट किया है। –

उत्तर

57

ठीक है, यह काफी कुछ खुदाई लिया, लेकिन जवाब यह है कि आश्चर्य की बात नहीं है और यहां तक ​​कि जटिल नहीं है:

JAXB, jaxb.index नहीं मिल सकता है क्योंकि डिफ़ॉल्ट रूप से, newInstance(String) वर्तमान धागा की क्लास लोडर का उपयोग करता है (जैसा कि Thread.getContextClassLoader() द्वारा लौटाया गया है)। यह फ़ेलिक्स के अंदर काम नहीं करता है, क्योंकि ओएसजीआई बंडलों और ढांचे के धागे में अलग-अलग वर्ग लोडर होते हैं।

समाधान कहीं से उपयुक्त वर्ग लोडर प्राप्त करना है और newInstance(String, ClassLoader) का उपयोग करना है।मैं पैकेज कि jaxb.index, लचीलापन कारणों के लिए एक समझदार विकल्प शायद ObjectFactory होता है में वर्गों में से एक से एक उपयुक्त वर्ग लोडर मिला:

ClassLoader cl = my.package.name.ObjectFactory.class.getClassLoader(); 
JAXBContext jc = JAXBContext.newInstance("my.package.name", cl); 

शायद तुम भी वर्ग लोडर कि Bundle उदाहरण उपयोग कर रहा है पर मिल सकता है , लेकिन मैं यह नहीं समझ पाया कि कैसे, और उपरोक्त समाधान मेरे लिए सुरक्षित लगता है।

+1

यह वास्तव में ओएसजीआई वातावरण में एक बहुत ही ग़लत समस्या है जब आप पुस्तकालयों का उपयोग कर रहे हैं जो ओएसजीआई के लिए डिज़ाइन नहीं किए गए हैं और उन्हें प्राप्त होने वाले क्लासलोडर के बारे में धारणाएं हैं। यह मुद्दा यह है कि लोग दावा करते हैं कि ईक्लीपसेलिंक एकमात्र जेपीए प्रदाता है जो ओएसजीआई में काम करता है (पता नहीं है कि यह अभी भी सच है)। –

+1

ContextClassLoader; क्लासलोडर को सेट करते समय, आपको पहले यह देखने के लिए जांच करनी चाहिए कि कोई पहले से सेट है या नहीं, यदि इसे स्थानीय चर के रूप में रखें और उसके बाद जेएक्स को कॉल करने के बाद अंत में ब्लॉक में रीसेट करें - आपको नहीं पता कि क्लासलोडर हैक्स का उपयोग करने के लिए और क्या है। .. – earcam

+0

क्या इस मुद्दे से संबंधित एक जिरा आइटम है? हम यहां ठोकर खाए और मैं यह प्रमाणित कर सकता हूं कि समाधान काम करता है, मैं बस सोच रहा हूं कि यह अपाचे-फ़ेलिक्स प्रोजेक्ट – Monachus

0

संपादित करें 2:

मैं एक बार अपने आवेदन में इसी तरह की अजीब वर्ग लोड हो रहा है समस्या थी। यदि मैं इसे सामान्य एप्लिकेशन के रूप में चलाता हूं, तो सब कुछ ठीक था, लेकिन जब मैंने इसे विंडोज सेवा के रूप में बुलाया, तो क्लास नॉटफाउंड अपवादों के साथ विफल होना शुरू हो गया। विश्लेषण से पता चला है कि धागे में उनके क्लासलोडर किसी भी तरह शून्य हैं। मैं धागे पर SystemClassLoader की स्थापना करके समस्या का समाधान: अपने कंटेनर परिवर्तन के इस प्रकार की अनुमति देता है, हालांकि

// ... 
thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); 
thread.start(); 
// ... 

पता नहीं है।

+0

ठीक है, यह हो सकता है (मुझे नहीं पता), लेकिन मुझे ऐसा लगता है कि वहां कुछ जगह होनी चाहिए जहां मैं फ़ाइल डाल सकता हूं ताकि क्लासलोडर इसका इस्तेमाल कर सके। –

6

मुझे जिस परियोजना पर मैं काम कर रहा हूं उसके साथ मुझे इसी तरह के मुद्दे का सामना करना पड़ा। http://jaxb.java.net/faq/index.html#classloader पढ़ने के बाद मुझे एहसास हुआ कि JAXBContext jaxb.index युक्त पैकेज को ढूँढने में सक्षम नहीं है।

मैं इसे यथासंभव स्पष्ट करने की कोशिश करूंगा।

हम

Bundle A 
    -- com.a 
     A.java 
     aMethod() 
     { 
      B.bMethod("com.c.C"); 
     } 
MANIFEST.MF 
Import-Package: com.b, com.c   

Bundle B 
    -- com.b 
     B.java 
     bmethod(String className) 
     { 
      Class clazz = Class.forName(className); 
     } 

Export-Package: com.b 

Bundle C 
    -- com.c 
     C.java 
     c() 
     { 
      System.out.println("hello i am C"); 
     } 

Export-Package: com.c 

है JAXB से संबंधित हैं करने के लिए। वर्ग बी JAXBContext है और bMethod newInstance है()

आप OSGi पैकेज प्रतिबंध से परिचित तो यह अब बहुत स्पष्ट होना चाहिए बंडल बी का आयात नहीं कर रहा है कि पैकेज com.c यानी क्लास सी हैं है नहीं दिखाईके लिए कक्षा बी इसलिए यह सी

का दृष्टांत नहीं कर सकते समाधान bMethod करने के लिए एक classloader पारित करने के लिए किया जाएगा। यह क्लासलोडर बंडल से आना चाहिए जो com.c आयात कर रहा है। इस मामले में हम A.class.getClassLoader पारित कर सकते हैं()के बाद से बंडल एक com.c आयात कर रहा है

आशा यह सहायक था।

0

मैंने अभी इस मुद्दे में भाग लिया है। मेरे लिए, समाधान ओरेकल के बजाय आईबीएम के जेआरई का उपयोग करना था। ऐसा लगता है कि जेएक्सबी कार्यान्वयन उस में अधिक ओएसजीआई-अनुकूल है।

4

इसी समस्या के लिए, मैंने पैकेज को मैन्युअल रूप से आयात में डालकर हल किया।

1

आप अपने प्रोजेक्ट में Maven उपयोग कर रहे हैं, तो बस इस पुस्तकालय का उपयोग करें:

<dependency> 
    <groupId>com.sun.xml.bind</groupId> 
    <artifactId>jaxb-osgi</artifactId> 
    <version>2.2.7</version> 
</dependency> 

यह Glasfish सर्वर के लिए बनाई गई है, लेकिन यह भी बिलाव के साथ काम (चयनित)। इस पुस्तकालय के साथ आप आसानी से ओएसजीआई बंडलों के साथ जेएक्सबी का उपयोग कर सकते हैं।

+0

मेरे लिए बहुत अच्छा काम किया – user617136

0

मैं सफलतापूर्वक मेरी उत्पन्न वर्गों मेरी बंडल परिभाषा के <Private-Package> भाग को ObjectFactory युक्त पैकेज जोड़कर इस का समाधान, प्लस org.jvnet.jaxb2_commons.*

-1

मेरे समाधान किया गया था:

JAXBContext संदर्भ = JAXBContext.newInstance (नई कक्षा [] { "my.package।नाम "});

या

JAXBContext संदर्भ = JAXBContext.newInstance (नई क्लास [] {class.getName()});

या

एक पूर्ण समाधान:

public static <T> T deserializeFile(Class<T> _class, String _xml) { 

     try { 

      JAXBContext context = JAXBContext.newInstance(new Class[]{_class}); 
      Unmarshaller um = context.createUnmarshaller(); 

      File file = new File(_xml); 
      Object obj = um.unmarshal(file); 

      return _class.cast(obj); 

     } catch (JAXBException exc) { 
      return null; 
     } 
    } 

वर्क्स 100%

0

एक और परिदृश्य हो सकता है जो इस समस्या को दे सकता है।

जब आप को स्थापित करने और एक बंडल जो पैकेज कि jaxb.index या objectFactory.java

शामिल तो सुनिश्चित करें कि कक्षाओं का आयात बंद कर दिया बंडलों या सही पैकेज का नाम ओर इशारा करते हैं कि सुनिश्चित करें निर्यात शुरू करते हैं।

इसके अलावा pom.xml

servicemix (karaf) OSGi कंटेनर में सामना समान मुद्दा

0

में निर्यात और आयात के बयानों की जाँच मेरे लिए समस्या यह थी कि एक इकाई परीक्षण जो मॉड्यूल से संबंधित नहीं था मैंने विकसित किया है कि मेरे मॉड्यूल में pom.xml में निर्भरता नहीं थी। साझा कॉन्फ़िगरेशन फ़ाइल से संकुल सूची लाने के कारण यूटी ने अभी भी मेरे मॉड्यूल को पहचाना है।

जब केन्द्र शासित प्रदेशों में यह चल रहा है नया मॉड्यूल संकलन नहीं किया तो यह ObjectFactory.java इसलिए उत्पन्न नहीं था कि मैं त्रुटि प्राप्त भी जब मैं मॉड्यूल मैं ObjectFactory.java

देखने के लिए सक्षम था संकलित हालांकि

ने निम्नलिखित निर्भरता को जोड़ा:

<dependency> 
    <groupId>com.myCompany</groupId> 
    <artifactId>my-module-name</artifactId> 
    <version>${project.version}</version> 
    <scope>test</scope> 
</dependency> 
संबंधित मुद्दे