我如何让Groovy和JAXB一起玩得很好

时间:2021-03-26 16:23:32

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...

我试图让JAXB与我的一个groovy类一起工作,但是,它似乎不起作用,但java版本。这是代码......

Here are the Scenarios:

以下是场景:

If 2 and 3 are uncommented it works fine.

如果取消注释2和3,它可以正常工作。

If 1 and 4 are uncommented I get:

如果取消注释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.

If 1 and 5 are uncommented I get:

如果取消注释1和5,我得到:

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

Any ideas?

有任何想法吗?

Java:

Java的:

    import javax.xml.bind.annotation.XmlRootElement;

    @XmlRootElement
    public class Player {
    }

Groovy:

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 个解决方案

#1


21  

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.

取消注释1和4是使用Groovy设置JAXB的正确方法。它不起作用的原因是每个Groovy类都有一个metaClass属性。 JAXB试图将其公开为JAXB属性,这显然是失败的。由于您没有自己声明metaClass属性,因此无法对其进行注释以使JAXB忽略它。而是将XmlAccessType设置为NONE。此禁用JAXB自动发现属性以作为XML元素公开。执行此操作后,您需要显式声明要公开的任何字段。

Example:

例:

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

#2


15  

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.

我在暴露Grails GORM对象时遇到了同样的问题。在研究了上面发布的解决方案后,使用@XmlAccessorType(XmlAccessType.NONE),我很快就厌倦了将所有内容标记为@XmlAttribute。

I'm having plenty of success using:

我使用以下方面取得了很大的成功:

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

See: XmlAccessType

请参阅:XmlAccessType

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

感谢最初的答案让我开始朝着正确的方向前进。

#3


1  

The solution does not seem to work on an abstract subclass. I think it's because the compiler does not generate the getMetaClass override code. I ended up mimicking the steps from this question as follows:

该解决方案似乎不适用于抽象子类。我认为这是因为编译器不生成getMetaClass覆盖代码。我最后模仿了这个问题的步骤如下:

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

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

Yes, it's kinda weird. In my case, I have code like this:

是的,这有点奇怪。就我而言,我有这样的代码:

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

And to execute my scripts, I have:

为了执行我的脚本,我有:

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

I'd prefer a better solution, but right now this is all I have.

我更喜欢更好的解决方案,但现在这就是我的全部。

#1


21  

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.

取消注释1和4是使用Groovy设置JAXB的正确方法。它不起作用的原因是每个Groovy类都有一个metaClass属性。 JAXB试图将其公开为JAXB属性,这显然是失败的。由于您没有自己声明metaClass属性,因此无法对其进行注释以使JAXB忽略它。而是将XmlAccessType设置为NONE。此禁用JAXB自动发现属性以作为XML元素公开。执行此操作后,您需要显式声明要公开的任何字段。

Example:

例:

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

#2


15  

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.

我在暴露Grails GORM对象时遇到了同样的问题。在研究了上面发布的解决方案后,使用@XmlAccessorType(XmlAccessType.NONE),我很快就厌倦了将所有内容标记为@XmlAttribute。

I'm having plenty of success using:

我使用以下方面取得了很大的成功:

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

See: XmlAccessType

请参阅:XmlAccessType

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

感谢最初的答案让我开始朝着正确的方向前进。

#3


1  

The solution does not seem to work on an abstract subclass. I think it's because the compiler does not generate the getMetaClass override code. I ended up mimicking the steps from this question as follows:

该解决方案似乎不适用于抽象子类。我认为这是因为编译器不生成getMetaClass覆盖代码。我最后模仿了这个问题的步骤如下:

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

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

Yes, it's kinda weird. In my case, I have code like this:

是的,这有点奇怪。就我而言,我有这样的代码:

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

And to execute my scripts, I have:

为了执行我的脚本,我有:

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

I'd prefer a better solution, but right now this is all I have.

我更喜欢更好的解决方案,但现在这就是我的全部。