tags:

views:

959

answers:

3

I am trying to get JAXB to work with a groovy class of mine, however, it appears it doesn't work but the java version does. Here is the code...

Here are the Scenarios

if 2 and 3 are uncommented it works fine

if 1 and 4 are uncommented I get...

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

if 1 and 5 are uncommented I get

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

Any ideas?

Java: import javax.xml.bind.annotation.XmlRootElement;

    @XmlRootElement
    public class Player {
    }

    Groovy:
    import javax.xml.bind.annotation.XmlRootElement

    @XmlRootElement
    public class PlayerGroovy {
    }

    Test:
    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)
        }
    }
+3  A: 

Uncommenting 1 and 4 is the correct way to set JAXB up with Groovy. The reason it is not working is that each Groovy Class has a metaClass property on it. JAXB is trying to expose this as a JAXB property which obviously fails. Since you don't declare the metaClass property yourself, it is not possible to annotate it to have JAXB ignore it. Instead you and set the XmlAccessType to NONE. This disable's JAXB's auto-discovery of properties to expose as XML elements. After you do that, you need to explicitly declare any fields you want exposed.

Example:

@XmlAccessorType( XmlAccessType.NONE )
@XmlRootElement
public class PlayerGroovy {
    @XmlAttribute
    String value
}
Chris Dail
+1 excellent answer
skaffman
+1  A: 

I was having the same problem while exposing a Grails GORM object. After researching the solution posted above, using "@XmlAccessorType( XmlAccessType.NONE )", I quickly grew tired of marking everything as @XmlAttribute.

I'm having plenty of success using:

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

See: http://www.ermalaev.spb.ru/javase/6/docs/api/javax/xml/bind/annotation/XmlAccessType.html

Thanks to the original answer for getting me started in the right direction.

Steve Ardis

Steve Ardis
A: 

Thanks for saving me countless nights of banging my head against the wall

Iroiso