Как заставить Groovy и JAXB хорошо играть вместе? - PullRequest
20 голосов
/ 21 июля 2009

Я пытаюсь заставить JAXB работать с моим классным классом, однако, похоже, что он не работает, но версия Java работает. Вот код ...

Вот сценарии:

Если 2 и 3 не закомментированы, все работает нормально.

Если 1 и 4 не прокомментированы, я получаю:

 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 и 5 не прокомментированы, я получаю:

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

Есть идеи?

Java:

    import javax.xml.bind.annotation.XmlRootElement;

    @XmlRootElement
    public class Player {
    }

Groovy:

    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)
        }
    }

Ответы [ 3 ]

22 голосов
/ 24 июля 2009

Раскомментирование 1 и 4 является правильным способом настройки JAXB с помощью Groovy. Причина, по которой он не работает, заключается в том, что у каждого класса Groovy есть свойство metaClass. JAXB пытается представить это как свойство JAXB, которое явно не работает. Поскольку вы не объявляете свойство metaClass самостоятельно, аннотировать его невозможно, чтобы JAXB его игнорировал. Вместо этого вы и установите XmlAccessType в NONE. Это отключает автоматическое обнаружение свойств JAXB для представления в виде элементов XML. После этого вам нужно явно объявить любые поля, которые вы хотите открыть.

Пример:

@XmlAccessorType( XmlAccessType.NONE )
@XmlRootElement
public class PlayerGroovy {
    @XmlAttribute
    String value
}
15 голосов
/ 21 октября 2009

У меня была такая же проблема при экспонировании объекта Grails GORM. После исследования решения, опубликованного выше, используя @XmlAccessorType( XmlAccessType.NONE ), я быстро устал отмечать все как @XmlAttribute.

Я добился большого успеха, используя:

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

См .: XmlAccessType

Спасибо за оригинальный ответ, который помог мне начать в правильном направлении.

1 голос
/ 17 января 2014

Решение, похоже, не работает на абстрактном подклассе. Я думаю, это потому, что компилятор не генерирует код переопределения getMetaClass. Я закончил, подражая шагам от этого вопроса следующим образом:

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

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

Да, это немного странно. В моем случае у меня есть такой код:

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')

Я бы предпочел лучшее решение, но сейчас это все, что у меня есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...