2009-07-21 4 views
20

JAXBをGroovyクラスのクラスで動作させようとしていますが、動作しませんが、javaバージョンは動作します。ここでは、コードがある...ここでGroovyとJAXBをうまく合わせるにはどうすればいいですか?

はシナリオです:

2と3は、それが正常に動作しますコメントを解除している場合。

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. 

任意のアイデア

1の場合と4は、私が得るコメントを解除していますか?

ジャワ:

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

コメント解除1及び4は、グルービーでアップJAXBを設定するための正しい方法です。それが動作しない理由は、各GroovyクラスにmetaClassプロパティがあるからです。 JAXBは明らかにこれが失敗するJAXBプロパティとしてこれを公開しようとしています。 metaClassプロパティを自分で宣言しないので、JAXBがそれを無視するようにアノテーションを付けることはできません。代わりに、XmlAccessTypeをNONEに設定します。これは、XML要素として公開するJAXBのプロパティの自動検出を無効にします。その後、公開するフィールドを明示的に宣言する必要があります。

例:GrailsのGORMオブジェクトを露出させ

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

+1すばらしい答え – skaffman

15

私は同じ問題を抱えていました。上記のソリューションを調べた後、@XmlAccessorType(XmlAccessType.NONE)を使用して、私はすぐにすべてを@XmlAttributeとマークすることに疲れました。

私が使用して成功をたくさん持っている:

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

参照:私は正しい方向に開始するため、元の答えにXmlAccessType

感謝。

+5

これは返されるものに影響することに注意してください。 XmlAccessType.FIELDは、getterおよびsetterで発生する操作ではなく、 "String value"の値を返します。だから私はこのように好きではない。しかし、はい、物事をあまり冗長にしていません。 – Jackie

1

解決策は、抽象サブクラスでは機能していないようです。コンパイラがgetMetaClassオーバーライドコードを生成しないためです。私は次のようにthis questionからの手順を模倣することになった:

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

私はよりよい解決策を好むだろうが、今、これは私が持っているすべてです。

+0

このコードは実際にはうまくいくかどうかわかりませんが、動作するようです。 'メタクラスメタクラス=新しいDelegatingMetaClass(設定)' '@ XmlTransient''メタクラスgetMetaClass(){ '' metaClass' '}' – ngreen

関連する問題