xjc:在ObjectFactory类中,两个声明引起了冲突

30
运行以下命令会导致错误:
$ xjc "ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd"
parsing a schema...
compiling a schema...
[ERROR] Two declarations cause a collision in the ObjectFactory class.
  line 340 of ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd

[ERROR] (Related to above error) This is the other declaration.   
  line 475 of ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd

尽管我理解JAXB绑定以及XJC中的冲突是什么,但我不明白当前模式中的冲突在哪里。我该如何修复这个问题?谢谢,Pierre。
更新:以下是错误的上下文。
$ curl -s "ftp://ftp.ncbi.nih.gov/bioproject/Schema/Core.xsd" | sed 's/^[ \t]*//' | cat -n | egrep -w -A 10 -B 10 '(340|475)' 
   330  <xs:element maxOccurs="1" name="Description"
   331  type="xs:string" minOccurs="0">
   332  <xs:annotation>
   333  <xs:documentation>
   334  Optionally provide description especially when "eOther" is selected
   335  </xs:documentation>
   336  </xs:annotation>
   337  </xs:element>
   338  <xs:element name="BioSampleSet" minOccurs="0" maxOccurs="1"><xs:annotation><xs:documentation>Identifier of the BioSample when known</xs:documentation>
   339  </xs:annotation>
   340  <xs:complexType><xs:sequence><xs:element name="ID" maxOccurs="unbounded" type="xs:token"></xs:element>
   341  </xs:sequence>
   342  </xs:complexType>
   343  </xs:element>
   344  </xs:sequence>
   345  <xs:attribute name="sample_scope" use="required">
   346  <xs:annotation>
   347  <xs:documentation>
   348  The scope and purity of the biological sample used for the study
   349  </xs:documentation>
   350  </xs:annotation>
--
   465  <xs:documentation>Please,  fill Description element when choose "eOther"</xs:documentation>
   466  </xs:annotation>
   467  </xs:enumeration>
   468  </xs:restriction>
   469  </xs:simpleType>
   470  </xs:attribute>
   471  </xs:complexType>
   472  </xs:element>
   473  <xs:element name="TargetBioSampleSet">
   474  <xs:annotation><xs:documentation>Set of Targets references to BioSamples</xs:documentation></xs:annotation>
   475  <xs:complexType>
   476  <xs:sequence>
   477  <xs:element name="ID" type="xs:token" minOccurs="1" maxOccurs="unbounded"></xs:element>                                                 
   478  </xs:sequence>
   479  </xs:complexType>
   480  </xs:element>                        
   481  </xs:choice>
   482  <xs:element name="Method" minOccurs="1">
   483  <xs:annotation>
   484  <xs:documentation>
   485  The core experimental approach used to obtain the data that is submitted to archival databases

如果您没有提供Core.xsd的相关部分,我认为没有人可以帮助您。 - hoaz
还可以尝试使用较新的Java JDK来生成它们。在使用JDK 1.7时,我遇到了许多重复错误,直到我使用JDK 1.8中的xjc才解决了这个问题。此外,如果有人正在尝试通过右键单击>Eclipse中的生成来生成,请确保也从命令行尝试。这样做可以为我解决错误。 - Kt Mack
6个回答

33
我将引用网络上最正式的非官方JAXB指南中的内容,该指南位于此链接
当模式包含相似的元素/类型名称时,可能会导致“两个声明在ObjectFactory类中引起冲突”的错误。更准确地说,对于所有类型和许多元素(哪些元素获得工厂,哪些不是有点棘手),XJC在同一包中的ObjectFactory类上产生一个方法。为每个XJC生成某些文件的包创建ObjectFactory类。该方法的名称源自XML元素/类型名称,如果两个元素/类型尝试生成相同的方法名称,则会报告错误。
话虽如此,您有两个选择。
第一个选择是定义一个外部绑定XML,如下所示:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  version="1.0">
  <jaxb:bindings schemaLocation="Core.xsd">
    <jaxb:bindings node="//xs:element[@name='BioSampleSet']/xs:complexType">
      <jaxb:factoryMethod name="TypeBioSampleSet"/>
    </jaxb:bindings>
    <jaxb:bindings node="//xs:element[@name='TargetBioSampleSet']/xs:complexType">
      <jaxb:factoryMethod name="TypeTargetBioSampleSet"/>
    </jaxb:bindings>
  </jaxb:bindings>
</jaxb:bindings>
在生成的ObjectFactory类中,这将创建两个方法,分别称为createTypeBioSampleSetcreateTypeTargetBioSampleSet(JAXB将把您指定的名称附加到单词create),可用于生成BioSampleSetTargetBioSampleSet对象。
(不需要为两种类型都定义绑定。)
我不确定为什么JAXB拒绝从给定的模式生成类,但是当我只指定一个绑定(例如BioSampleSet)时,则另一种类型的工厂方法的名称类似于createTypeProjectProjectTypeSubmissionWhateverThisAndThatTargetTargetSampleBioCatDogWoofTypeIDoNotKnowWhatElse,因此我认为JAXB在这个长方法标识符上卡住了,因为它以某种方式成功地为两种类型创建了相同的标识符。 我认为这是JAXB的一些实现细节。
另一种解决方案是为BioSampleSet创建一个基类型,并在两个位置都使用它,就像这样
<xs:element name="ProjectTypeSubmission">

...

  <xs:element name="Target">

    ...

    <xs:element name="BioSampleSet" type="typeBioSampleSet" minOccurs="0" maxOccurs="1"/>

    ...

  </xs:element>

  ...

  <xs:element name="TargetBioSampleSet" type="typeBioSampleSet"/>

  ...

<xs:element/>

...

<xs:complexType name="typeBioSampleSet">
  <xs:sequence>
    <xs:element name="ID" maxOccurs="unbounded" type="xs:token"></xs:element>
  </xs:sequence>
</xs:complexType>

最好的解决方案是从你的架构中删除每个匿名类型声明。如果可以这样做,请执行此操作,因为我认为此架构看起来很混乱。

最好的解决方案是从你的架构中删除每个匿名类型声明。如果可以这样做,请执行此操作,因为我认为此架构看起来很混乱。

“我不确定为什么JAXB拒绝从给定的模式生成类”,我也不确定,但非常感谢,这个方法有效! :-)” - Pierre
谢谢您的提示,我只是想知道为什么在 http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/jaxb/bindingschema_2_0.xsd 模式中找不到任何 factoryMethod 元素,尽管它在 https://jaxb.java.net/nonav/2.0/binding-customization/http.java.sun.com.xml.n/index.html 中有记录。 - kasi

9

在命令中删除 -p 包

xjc -d src -XautoNameResolution TFMData_Service.xsd

这是最简单的解决方案。虽然使用了-XautoNameResolution,但仍然无法弄清楚为什么仍然会发生冲突。移除包选项是关键。 - ka3ak
1
对于那些正在琢磨如何"删除-P"的人,我的原始xjc命令[在build.gradle中]是这样的:"xjc(destdir: sourcesDir, schema: schema, package: "com.example.consumingwebservice.wsdl")"。移除package意味着我的xjc命令变成了"xjc(destdir: sourcesDir, schema: schema)"。 - Jach

2

当我使用下面的maven插件时,对我有用的解决方案是添加-XautoNameResolution

<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>

示例代码:

       <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <version>2.5.0</version>
            <executions>
                <execution>
                    <id>xjc</id>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <xjbSources>
                    <xjbSource>src/main/resources/global.xjb</xjbSource>
                </xjbSources>
                <sources>
                    <source>src/main/xsd/</source>
                </sources>
                <arguments>
                    <argument>-XautoNameResolution</argument>
                </arguments>
                <packageName>com.xxx.yyy.zzz.policy.xml</packageName>
            </configuration>
        </plugin>

1

我曾遇到同样的问题,即对象工厂的冲突,我的解决方案是使用以下绑定:

<jaxb:bindings version="1.0"
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
               jaxb:extensionBindingPrefixes="xjc">

    <jaxb:bindings
            schemaLocation="../pfel_xsd/pfel-mng-managedocument-v4-vs_data.xsd"
            node="/xs:schema">
        <jaxb:schemaBindings>
            <jaxb:package name="document.client.pfelservice"/>
        </jaxb:schemaBindings>
    </jaxb:bindings>

    <jaxb:bindings
            schemaLocation="../pfel_xsd/pfel-mng-managedocument-v4-vs_data-types.xsd"
            node="/xs:schema">
        <jaxb:schemaBindings>
            <jaxb:package name="document.client.pfel"/>
        </jaxb:schemaBindings>
    </jaxb:bindings>

</jaxb:bindings>

这里是解决方案:https://www.javaer101.com/en/article/1278220.html

0

我在ObjectFactory类中遇到了类似的名称冲突问题。

其中一个问题是,在默认设置下,XJC生成了一个更冗长的Java模型和中间类型。这会导致所需的模型对象和中间模型对象之间发生冲突。

解决方案是使用XLC simple绑定模式。这将消除中间模型对象,从而解决冲突问题。

要启用此功能,请添加此绑定文件:

<jxb:bindings version="1.0"
              xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc">

    <jxb:globalBindings>
        <xjc:simple/>
    </jxb:globalBindings>

</jxb:bindings>

一个关于ObjectFactory的例子,展示了在使用simple绑定设置前后相同XSD的简化。 (请注意,在此之前发生冲突的CitationCitationX元素,我曾试图将其中一个重命名为CitationX。)

enter image description here

有关简单绑定的更多信息,请参考:

  1. https://dev59.com/iG435IYBdhLWcg3w4UWs#5155704
  2. https://dev59.com/uG855IYBdhLWcg3wKw5Y#13359717

很遗憾,这并没有生成正确的模式模型。有很多缺失的类。 - Teddy

0
在我的情况下,问题是我在运行wsimport时指定了目标包,这意味着所有生成的类都在同一个包中。wsimport的默认行为是根据模式标记中指定的命名空间在包中生成代码,这通常是您想要的行为。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接