24

Running the following xjc command raises an error :

$ 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

Although I understand the JAXB bindings and what are is conflict in XJC, I don't understand where is the conflict in the current schema.

how should I fix this ?

Thanks,

Pierre

update: here is the context of the errors:

$ 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
Pierre
  • 31,741
  • 29
  • 101
  • 180
  • i don't think anyone can help you if you do not provide relevant parts from Core.xsd – hoaz Nov 16 '12 at 18:51
  • Also try using the newer Java JDK to generate them. I had a lot of duplicate errors using JDK 1.7 until I used xjc in JDK 1.8. Also in case someone is trying to generate by right click > Generate in Eclipse, make sure to try it from the command line too. Doing this resolved errors for me. – Kt Mack Sep 05 '18 at 20:24

3 Answers3

30

I'll quote from the most official unofficial guide on JAXB on the net.

When schemas contain similar looking element/type names, they can result in "Two declarations cause a collision in the ObjectFactory class" errors. To be more precise, for each of all types and many elements (exactly what elements get a factory and what doesn't is bit tricky to explain), XJC produces one method on the ObjectFactory class in the same package. The ObjectFactory class is created for each package that XJC generates some files into. The name of the method is derived from XML element/type names, and the error is reported if two elements/types try to generate the same method name.

That said, you have two options.

The first is to define an external binding XML like this

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

In the generated ObjectFactory class this will create two methods called createTypeBioSampleSet and createTypeTargetBioSampleSet (JAXB will append the name you specify to the word create) that can be used to produce BioSampleSet and TargetBioSampleSet objects.

(It's not necessary to define a binding for both types.)

I'm not exactly sure why JAXB refuses to generate classes from the given schema, but when I specified only one binding (for BioSampleSet for example) then the other type's factory method was named like createTypeProjectProjectTypeSubmissionWhateverThisAndThatTargetTargetSampleBioCatDogWoofTypeIDoNotKnowWhatElse so I think JAXB choked on this long method identifier, because it somehow managed to create the same one for both types. I think this is some implementation detail in JAXB.

The other solution is to create a base type for a BioSampleSet and use that at both locations like this

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

The best solution would be to drop every anonymous type declarations from your schema. If you can do that, do it, because this schema looks like a mess (to me at least).

Kohányi Róbert
  • 8,681
  • 3
  • 46
  • 74
  • "I'm not exactly sure why JAXB refuses to generate classes from the given schema,": neither do I, but thank you very much, that worked ! :-) – Pierre Nov 18 '12 at 09:28
  • @Kohányi Róbert Nice answer, it solved my problem. Thanks a lot! – user1516873 Apr 02 '13 at 08:59
  • Thanks for tip, just wondering why I cannot find any factoryMethod element in schema http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/jaxb/bindingschema_2_0.xsd, although it is documented in https://jaxb.java.net/nonav/2.0/binding-customization/http.java.sun.com.xml.n/index.html – kasi Jul 23 '15 at 09:05
3

remove -p package in the command

xjc -d src -XautoNameResolution TFMData_Service.xsd
Plutian
  • 2,127
  • 3
  • 11
  • 22
vks
  • 89
  • 5
  • It's the most easy solution. Couldn't figure out why I still got collisions although -XautoNameResolution was used. Removing the package option is the key. – ka3ak Apr 20 '21 at 10:00
0

I had the same problem, collision of object factory, and my solution was to use the following binding:

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

Here's the solution: https://www.javaer101.com/en/article/1278220.html

razvang
  • 736
  • 8
  • 13