2009-07-21 18 views
20

अच्छी तरह से खेलने के लिए ग्रोवी और जेएक्सबी कैसे प्राप्त करूं, मैं जेएक्सबी को मेरी ग्रोवी क्लास के साथ काम करने की कोशिश कर रहा हूं, हालांकि, ऐसा लगता है कि यह काम नहीं करता है लेकिन जावा संस्करण करता है।मैं

तो 2 और 3 uncommented हैं यह ठीक काम करता है: यहाँ कोड ...

यहाँ परिदृश्य हैं।

तो 1 और 4 uncommented कर रहे हैं मैं: 5 uncommented हैं

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 
     2 counts of IllegalAnnotationExceptions 
groovy.lang.MetaClass is an interface, and JAXB can't handle interfaces. 

तो 1 और मैं:

javax.xml.bind.JAXBException: class org.oclc.presentations.simplejaxb.PlayerGroovy 
     nor any of its super class is known to this context. 

कोई भी विचार?

जावा:

import javax.xml.bind.annotation.XmlRootElement; 

    @XmlRootElement 
    public class Player { 
    } 

ग्रूवी:

import javax.xml.bind.annotation.XmlRootElement 

    @XmlRootElement 
    public class PlayerGroovy { 
    } 

टेस्ट:

import org.junit.Test 
    import javax.xml.bind.JAXBContext 
    import javax.xml.bind.Marshaller 
    import org.junit.Assert 

    class PlayerTest { 
     @Test 
     public void testJaXB(){ 
      //1 PlayerGroovy player = new PlayerGroovy() 
      //2 Player player = new Player() 
      StringWriter writer = new StringWriter(); 
      //3 JAXBContext context = JAXBContext.newInstance(Player.class); 
      //4 JAXBContext context = JAXBContext.newInstance(PlayerGroovy.class); 
      //5 JAXBContext context = JAXBContext.newInstance(PlayerGroovy.getClass()); 
      Marshaller m = context.createMarshaller(); 
      m.marshal(player, writer); 
      println(writer) 
      Assert.assertTrue(true) 
     } 
    } 

उत्तर

21

uncommenting 1 और 4 ग्रूवी साथ JAXB सेट अप करने के लिए सही तरीका है। कारण यह काम नहीं कर रहा है कि प्रत्येक ग्रोवी क्लास में मेटा क्लास संपत्ति है। जेएक्सबी इसे एक जेएक्सबी संपत्ति के रूप में बेनकाब करने की कोशिश कर रहा है जो स्पष्ट रूप से विफल रहता है। चूंकि आप मेटा क्लास संपत्ति को स्वयं घोषित नहीं करते हैं, इसलिए JAXB को अनदेखा करने के लिए इसे एनोटेट करना संभव नहीं है। इसके बजाय आप XmlAccessType को किसी पर सेट करें। एक्सएमएल तत्वों के रूप में उजागर करने के लिए यह अक्षमता JAXB की गुणों की स्वत: खोज है। ऐसा करने के बाद, आपको उन क्षेत्रों को स्पष्ट रूप से घोषित करने की आवश्यकता है जिन्हें आप उजागर करना चाहते हैं।

उदाहरण:

@XmlAccessorType(XmlAccessType.NONE) 
@XmlRootElement 
public class PlayerGroovy { 
    @XmlAttribute 
    String value 
} 
+3

+1 उत्कृष्ट उत्तर – skaffman

15

मैं एक Grails GORM वस्तु को उजागर करते हुए एक ही समस्या हो रही थी। ऊपर पोस्ट किए गए समाधान का शोध करने के बाद, @XmlAccessorType(XmlAccessType.NONE) का उपयोग करके, मैं जल्दी से @XmlAttribute के रूप में सबकुछ चिह्नित करने से थक गया।

मैं का उपयोग कर सफलता के बहुत हो रही है:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlRootElement 
public class PlayerGroovy { 
    String value 
} 

देखें: XmlAccessType

हो रही मुझे सही दिशा में शुरू कर दिया के लिए मूल जवाब देने के लिए धन्यवाद।

+5

इस प्रभाव को ध्यान में रखने के लिए क्या किया जाता है। XmlAccessType.FIELD "स्ट्रिंग मान" का मान देता है जो गेटर्स और सेटर्स में होने वाली किसी भी हेरफेर से नहीं होता है। यही कारण है कि मुझे इस तरह से पसंद नहीं है। लेकिन हाँ यह चीजों को कम verbose बनाता है। – Jackie

1

समाधान एक सार उप-वर्ग पर काम नहीं करता है। मुझे लगता है कि ऐसा इसलिए है क्योंकि संकलक getMetaClass ओवरराइड कोड उत्पन्न नहीं करता है।

@XmlAccessorType(XmlAccessType.NONE) 
package groovy.lang; 

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 

हाँ, यह थोड़े अजीब है: मैं this question से कुछ कदम दूर नकल उतार इस प्रकार समाप्त हो गया।

package pkg; 
abstract class ScriptMomma extends groovy.lang.Script { 
    // write some nice supporting code here 
} 

और मेरे आलेख निष्पादित करने, मेरे पास है:: मेरे मामले में, मैं इस तरह कोड है

def config = new org.codehaus.groovy.control.CompilerConfiguration() 
config.scriptBaseClass = 'pkg.ScriptMomma' 
ScriptMomma mine = new GroovyShell(config).evaluate(scriptFile, 'TheOne') 

मैं एक बेहतर समाधान पसंद करते हैं, लेकिन अभी यह सब मैं है।

+0

यह कोड भी काम करता प्रतीत होता है, हालांकि मुझे यकीन नहीं है कि यह वास्तव में एक अच्छा विचार है। 'MetaClass metaClass = नए DelegatingMetaClass (सेटिंग)' ' @ XmlTransient' ' MetaClass getMetaClass() { '' metaClass' ''} – ngreen