web-dev-qa-db-ja.com

JAXB:共通のXSDを共有する2つのXSDのクラスを生成する

それぞれ異なるtargetNamespaceを持つ2つのサービスXSDファイルAService.xsdとBService.xsdがあります。これらは両方とも、common.xsdと呼ばれる共通のXSDを使用します。 JAXBMavenプラグインを使用してクラスを生成します。方法は次のとおりです。

<execution>
    <id>generate-package</id>
    <goals>
        <goal>generate</goal>
    </goals>
    <configuration>
        <extension>true</extension>
        <schemaIncludes>
            <include>schema/Aservice.xsd</include>
            <include>schema/Bservice.xsd</include>                             
        </schemaIncludes>
        <bindingIncludes>                                   
            <include>schema/*.xjb</include>
        </bindingIncludes>
        <generatePackage>com.schema</generatePackage>
        <generateDirectory>src/main/Java</generateDirectory>
    </configuration>
</execution>

これを実行しようとすると、次のエラーが発生します。 ValidationTypeはcommon.xsdで定義されています

org.xml.sax.SAXParseException: A class/interface with the same name "com.schema.ValidationType" is already in use. Use a class customization to resolve this conflict.
..........
org.xml.sax.SAXParseException: (Relevant to above error) another "ValidationType" is generated from here.
......
com.Sun.istack.SAXParseException2: Two declarations cause a collision in the ObjectFactory class.

2つの異なるパッケージに生成する2つの異なる実行で2つのサービスxsdsを実行すると、2つの異なるパッケージで同じValidationTypeクラスを取得します。

JAXBに共有スキーマを認識させる方法に関するアイデアはありますか?

17
Aravindan R

あなたは、悪い習慣と考えられている、いわゆる「カメレオンスキーマ」に直面しています。残念ながら、JAXBの性質上、適切な解決策はありません。 JAXBアノテーションは、Beanプロパティを特定の名前空間のXML要素および属性にバインドします(スキーマのコンパイル時に決定されます)。したがって、スキーマがコンパイルされると、プロパティがバインドされている要素と属性の名前空間を変更する公式の良い方法はありません。

ただし、これはまさに「カメレオン」スキーマで実現したいことです。 「common.xsd」から派生したクラスは、Aクラスで使用されている場合は名前空間Aに、Bクラスで使用されている場合は名前空間Bに魔法のようにマップする必要があります。この魔法は想像できますが、実生活では見られません。

基本的にA/commonとB/commonを「同じもの」にしたいので、それを解決する方法の1つは、2回の実行でAとB(両方ともcommon)を生成し、commonクラスに特定の「common」を実装させることです。 " インターフェース。そうすれば、ソフトウェアはA/commonとB/commonを、実際には異なるパッケージのクラスであるという事実に関係なく、同じファシオンで処理できます。

更新:

コメントから、カメレオンスキーマはなく、通常のインポートであることがわかります。そうすれば簡単です。共通のAとBを別々にコンパイルするだけです。 maven-jaxb2-pluginについては、 個別のスキーマコンパイル を参照してください。

6
lexicore

ここで説明するようにパッケージをカスタマイズしました 。したがって、common.xsdcom.common.schemaに入り、異なる名前空間にあるため、両方とも異なるパッケージにあるAService.xsdBService.xsdによって共有されます。

generatePackageはMaven構成から削除され、次のようになります。

<execution>
    <id>generate-package</id>
    <goals>
        <goal>generate</goal>
    </goals>
    <configuration>
        <extension>true</extension>
        <schemaIncludes>
            <include>schema/Aservice.xsd</include>
            <include>schema/Bservice.xsd</include>                            
        </schemaIncludes>
        <bindingIncludes>
            <include>schema/*.xjb</include>
        </bindingIncludes>                                
        <generateDirectory>src/main/Java</generateDirectory>
    </configuration>
</execution>
5
Aravindan R