हम अपने सिस्टम में लंबे समय तक जेएक्सबी 2.1 का उपयोग कर रहे हैं। हमारे पास एक मंच है जो चींटी के साथ बनाया गया है और ओएसजीआई रनटाइम में तैनात बंडलों का एक गुच्छा उत्पन्न करता है। हम जावा एसई 6.दो वर्गों में एक ही एक्सएमएल प्रकार का नाम "ऑब्जेक्ट फैक्ट्री"
का उपयोग करते हैं हम विभिन्न योजनाओं से डेटाटाइप उत्पन्न करने के लिए निर्माण प्रक्रिया के दौरान जेएक्सबी का उपयोग करते हैं। उन वर्गों को बंडलों में पैक किया जाता है और सामग्री को क्रमबद्ध/deserialize करने के लिए रनटाइम में उपयोग किया जाता है। इसके अलावा हम उपयोगकर्ता द्वारा प्रदान किए गए अन्य स्कीमा से डेटाटाइप उत्पन्न करने के लिए रनटाइम में हमारे प्लेटफॉर्म में जेएक्सबी का उपयोग करते हैं (यह एक प्रकार का एमडीए मंच है)।
ओएसजीआई रनटाइम में हमारे पास एक बंडल है जिसमें जेएक्सबी जार हैं और आवश्यक पैकेज निर्यात करते हैं। हम उत्पन्न सभी ऑब्जेक्ट कारखानों के संदर्भ पथ के साथ एक JAXBContext उदाहरण बनाते हैं, ताकि हम अपने सभी डेटाटाइप को मार्शल/अनमशेल कर सकें।
यह अब तक काम कर रहा है लेकिन अभी हम JAXB (2.2.4) के नवीनतम स्थिर संस्करण में अपग्रेड करने का प्रयास कर रहे हैं और हमें रनटाइम में संदर्भ बनाने की कोशिश करने में समस्याएं आ रही हैं। हम निम्नलिखित अपवाद:
Two classes have the same XML type name "objectFactory". Use @XmlType.name and @XmlType.namespace to assign different names to them.
this problem is related to the following location:
at some.package.ObjectFactory
this problem is related to the following location:
at some.other.package.ObjectFactory
at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:91)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:436)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:277)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:110)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:191)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:187)
... 76 more
त्रुटि दो कक्षाएं एक ही एक्सएमएल प्रकार का नाम "objectFactory" है निर्माण प्रक्रिया के दौरान उत्पन्न वस्तु कारखानों से प्रत्येक के लिए मुद्रित है।
हमने एसओ में एक ही त्रुटि के साथ कई पोस्ट देखी हैं लेकिन उत्पन्न कारखाने के लिए जेनरेट किए गए प्रकारों पर लागू नहीं हैं। हम सोचते हैं कि जेएक्सबी ऑब्जेक्ट फैक्ट्री क्लास को ऑब्जेक्ट फ़ैक्टरी के रूप में पहचान नहीं सकता है बल्कि डेटाटाइप के रूप में।
एक संभावना यह है कि हम जावा 6 में JAXB की आंतरिक संस्करण का उपयोग कर रहे थे था, इसलिए हम सिस्टम संपत्ति -Djava.endorsed.dirs का उपयोग करें और (JAXB-api-2.2.4 तीन जार डाल करने का निर्णय लिया .jar, jaxb-impl-2.2.4.jar और jaxb-xjc-2.2.4.jar) उस पथ में, लेकिन अभी भी काम नहीं कर रहा है।
हमें लगता है कि समस्या यह हो सकती है कि हम ओएसजीआई रनटाइम में और निर्माण प्रक्रिया में जेएक्सबी के एक अलग संस्करण का उपयोग कर रहे हैं, इसलिए जेनरेट कोड संगत नहीं है। लेकिन शायद हम गलत हैं और एक और समस्या है।
क्या आपके पास कोई विचार है?
अग्रिम धन्यवाद।
(संपादित करें: इस बारे में अधिक जानकारी)
हम इस तरह से JAXBContext बनाएँ:
ClassLoader classLoader = new JAXBServiceClassLoader(getParentClassLoader(),
Collections.unmodifiableMap(objectFactories));
context = JAXBContext.newInstance(contextPath.toString(), classLoader);
जहां contextPath एक स्ट्रिंग है कि हमारे सभी वस्तु कारखानों द्वारा अलग होता है ':', और JAXBServiceClassLoader है:
private static final class JAXBServiceClassLoader extends ClassLoader
{
@NotNull
private final Map<String, Object> objectFactories;
private JAXBServiceClassLoader(@NotNull ClassLoader parent, @NotNull Map<String, Object> objectFactories)
{
super(parent);
this.objectFactories = objectFactories;
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException
{
Class<?> ret;
try
{
ret = super.loadClass(name);
}
catch (ClassNotFoundException e)
{
Object objectFactory = objectFactories.get(name);
if (objectFactory != null)
{
ret = objectFactory.getClass();
}
else
{
throw new ClassNotFoundException(name + " class not found");
}
}
return ret;
}
}
(संपादित करें: हारून के पोस्ट के बाद)
मैं JAXBContextImpl के सभी आंतरिकों को डीबग कर रहा हूं और यह बात यह है कि JAXBContextImpl हमारे ऑब्जेक्ट फैक्ट्री कक्षाओं से टाइप जानकारी प्राप्त करने का प्रयास कर रहा है, जो गलत है। वास्तव में, com.sun.xml.internal.bind.v2.model.impl.ModelBuilder: 314 में, getClassAnnotation() कॉल शून्य देता है लेकिन जब मैं उदाहरण देखता हूं तो मैं एनोटेशन XmlRegistry देख सकता हूं।
बात यह है कि, उस बिंदु पर XmlRegistry.class.getClassLoader() शून्य लौटाता है, लेकिन अगर मैं चलाता हूं (क्लास) सी) .getAnnotations() [0] .annotationType()। GetClassLoader() यह लौटाता है ओएसजीआई बंडल "lib.jaxb" का क्लासलोडर जिसमें मेरे जेएक्सबी जार शामिल हैं, जो सही है।
तो, मुझे लगता है कि हम एक ही समय में XmlRegistry के दो अलग-अलग संस्करणों को लोड कर रहे हैं, एक जेडीके से और दूसरा एक जेएक्सबी 2.2.4 जार से लोड हो रहा है। सवाल यह है: क्यों?
और उन सभी com.sun.xml.internal लोड करने के बजाय, और भी अधिक, * कक्षाएं (जैसे JAXBContextImpl), को com.sun.xml.bind.v2.runtime.JAXBContextImpl को लोड और निष्पादित नहीं किया जाना चाहिए जेएक्सबी जार? डीबग प्रक्रिया के दौरान मैं देख सकता हूं कि यह प्रतिबिंब के साथ कुछ सामान कर रहा है लेकिन मुझे समझ में नहीं आता कि ऐसा क्यों कर रहा है।
जावा एसई 6 का उपयोग करके मैं आपके जेएक्सबी इत्यादि की नवीनतम पैच रिलीज का उपयोग करने की अनुशंसा करता हूं जो JAXB 2.1 का समर्थन करता है जब तक कि कोई विशेष JAXB 2.2 सुविधा न हो जिसे आप उपयोग करने का प्रयास कर रहे हैं। –
क्षमा करें कि मैंने इसका उल्लेख नहीं किया है। जेएक्सबी 2.2.4 में अपग्रेड करने का कारण यह है कि हम अपने जेएक्स-डब्ल्यूएस संस्करण को 2.2.5 तक अपग्रेड कर रहे हैं और यह जेएक्सबी के उस संस्करण पर निर्भर करता है (http://jax-ws.java.net/2.2.5/docs/ ReleaseNotes.html)। अन्यथा हम जेएक्सबी 2.1 का उपयोग कर सकते हैं। – Denian
ऐसा लगता है कि आपका जेएक्सबी इत्यादि गलती से 'ऑब्जेक्ट फैक्ट्री' को डोमेन क्लास के रूप में देख रहा है। आपकी डोमेन कक्षाओं और जेएक्स-डब्ल्यूएस कार्यान्वयन के बीच 'क्लासलोडर' अंतर के कारण' @ XmlRegistry' एनोटेशन की पहचान होने की संभावना अधिकतर है। क्या आप सीधे 'JAXBContext' बना रहे हैं या यह कर रहे जेएक्स-डब्ल्यूएस कार्यान्वयन है? –