3
votes

I want to translate a complicated set of xsd files into Java/Hibernate entities. Towards that end, I downloaded version 2.2.7 of JAXB from this link. I unzipped the file, opened cmd.exe, navigated to the directory of the create-marshal sample, ran ant compile to confirm everything works, then ran ant clean to eliminate the results to return everything to starting conditions.

The problem came when I tried to use a different xsd file as the input for the create-marshal sample. Specifically, I am getting an error when the xsd file distinguishes between data structures by changing the value of an attribute of the same tag type. The create-marshal sample gives the following error in that case:

[ERROR] 'POCD_MT000040.InfrastructureRoot.typeId' is already defined
[xjc] line 54 of file:/C:/Temp/jaxb/apps/create-marshal/POCD_MT000040_SDTC.xsd

The error repeats again and again, once for every time that the value of the attribute is re-assigned for a different data structure definition. How can I resolve this error?

Here are the first few iterations of the data structure in the xsd file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema targetNamespace="urn:the-publisher:v3" 
  xmlns:mif="urn:the-publisher:v3/mif" 
  xmlns="urn:the-publisher:v3"  
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  elementFormDefault="qualified"  
  xmlns:sdtc="urn:the-publisher:sdtc">
<xs:annotation>
    <xs:documentation>Manually edited to add Schema Extensions, July 2012</xs:documentation>
    <xs:documentation>Generated using schema builder version 2.0. Stylesheets: RoseTreeToMIFStaticModel.xsl version: 1.1 StaticMifToXsd.xsl version 2.0</xs:documentation>
</xs:annotation>
<xs:complexType name="POCD_MT000040.InfrastructureRoot.typeId">
    <xs:complexContent>
        <xs:restriction base="II">
            <xs:attribute name="root" type="uid" 
              use="required" 
              fixed="2.16.840.1.113883.1.3"/>
            <xs:attribute name="extension" type="st" 
              use="required"/>
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>
<xs:complexType name="POCD_MT000040.Act">
    <xs:sequence>
        <xs:element name="realmCode" type="CS" 
          minOccurs="0" 
          maxOccurs="unbounded"/>
        <xs:element name="typeId"
          type="POCD_MT000040.InfrastructureRoot.typeId" 
          minOccurs="0"/>
        <xs:element name="templateId" type="II" 
          minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="id" type="II" minOccurs="0" 
          maxOccurs="unbounded"/>
        <xs:element name="code" type="CD"/>
        <xs:element name="text" type="ED" minOccurs="0"/>
        <xs:element name="statusCode" type="CS" 
          minOccurs="0"/>
        <xs:element name="effectiveTime" type="IVL_TS" 
          minOccurs="0"/>
        <xs:element name="priorityCode" type="CE" 
          minOccurs="0"/>
        <xs:element name="languageCode" type="CS" 
          minOccurs="0"/>
        <xs:element name="subject" 
          type="POCD_MT000040.Subject" minOccurs="0"/>
        <xs:element name="specimen" 
          type="POCD_MT000040.Specimen" minOccurs="0" 
          maxOccurs="unbounded"/>
        <xs:element name="performer" 
          type="POCD_MT000040.Performer2" minOccurs="0" 
          maxOccurs="unbounded"/>
        <xs:element name="author" 
          type="POCD_MT000040.Author" minOccurs="0" 
          maxOccurs="unbounded"/>
        <xs:element name="informant" 
          type="POCD_MT000040.Informant12" 
          minOccurs="0" 
          maxOccurs="unbounded"/>
        <xs:element name="participant" 
          type="POCD_MT000040.Participant2" 
          minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="entryRelationship" 
          type="POCD_MT000040.EntryRelationship" 
          minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="reference" 
          type="POCD_MT000040.Reference" 
          minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="precondition" 
          type="POCD_MT000040.Precondition" 
          minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="nullFlavor" 
          type="NullFlavor" use="optional"/>
    <xs:attribute name="classCode" 
          type="x_ActClassDocumentEntryAct" use="required"/>
    <xs:attribute name="moodCode" type="x_DocumentActMood" 
          use="required"/>
    <xs:attribute name="negationInd" type="bl" 
          use="optional"/>
</xs:complexType>
<xs:complexType name="POCD_MT000040.AssignedAuthor">
    <xs:sequence>
        <xs:element name="realmCode" type="CS" 
          minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="typeId" 
          type="POCD_MT000040.InfrastructureRoot.typeId" 
          minOccurs="0"/>
        <xs:element name="templateId" type="II" 
          minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="id" type="II" 
          maxOccurs="unbounded"/>
        <xs:element name="code" type="CE" minOccurs="0"/>
        <xs:element name="addr" type="AD" 
          minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="telecom" type="TEL" 
          minOccurs="0" maxOccurs="unbounded"/>
        <xs:choice>
            <xs:element name="assignedPerson" 
          type="POCD_MT000040.Person" minOccurs="0"/>
            <xs:element name="assignedAuthoringDevice" 
          type="POCD_MT000040.AuthoringDevice" 
          minOccurs="0"/>
        </xs:choice>
        <xs:element name="representedOrganization" 
          type="POCD_MT000040.Organization" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute name="nullFlavor" 
          type="NullFlavor" use="optional"/>
    <xs:attribute name="classCode" 
          type="RoleClassAssignedEntity" 
          use="optional" fixed="ASSIGNED"/>
</xs:complexType>

Here are the corresponding first few iterations of the error message:

Build sequence for target(s) `compile' is [compile]
Complete build sequence is [compile, javadoc, clean, run, ]
compile:
[echo] Compiling the schema...
[mkdir] Created dir: C:\Temp\jaxb\apps\create-marshal\gen-src
[mkdir] Created dir: C:\Temp\jaxb\apps\create-marshal\gen-src\primer\po
[xjc] build id of XJC is 2.2.7
[xjc] Checking timestamp of C:\Temp\jaxb\apps\create-marshal\POCD_MT000040_SDTC.xsd
[xjc] the last modified time of the inputs is 1409957672397
[xjc] the last modified time of the outputs is -9223372036854775808
[xjc] Compiling file:/C:/Temp/jaxb/apps/create-marshal/POCD_MT000040_SDTC.xsd
[xjc] [ERROR] 'POCD_MT000040.InfrastructureRoot.typeId' is already defined
[xjc] line 54 of file:/C:/Temp/jaxb/apps/create-marshal/POCD_MT000040_SDTC.xsd
[xjc]
[xjc] [ERROR] (related to above error) the first definition appears here
[xjc] line 46 of file:/C:/Temp/jaxb/apps/create-marshal/infrastructure/cda/POCD_MT000040_SDTC.xsd
[xjc]
[xjc] [ERROR] 'POCD_MT000040.Act' is already defined
[xjc] line 81 of file:/C:/Temp/jaxb/apps/create-marshal/POCD_MT000040_SDTC.xsd
[xjc]

.....the same error repeats many more times, once for each repetition of xs:complexType

[xjc] failure in the XJC task. Use the Ant -verbose switch for more details
compile: duration 2 seconds
BUILD FAILED
C:\Temp\jaxb\apps\create-marshal\build.xml:29: unable to parse the schema. Error messages should have been provided
at com.sun.tools.xjc.XJC2Task._doXJC(XJC2Task.java:520)
at com.sun.tools.xjc.XJC2Task.doXJC(XJC2Task.java:457)
at com.sun.tools.xjc.XJC2Task.execute(XJC2Task.java:380)
at com.sun.istack.tools.ProtectedTask.execute(ProtectedTask.java:103)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:292)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:435)
at org.apache.tools.ant.Target.performTasks(Target.java:456)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1393)
at org.apache.tools.ant.Project.executeTarget(Project.java:1364)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
at org.apache.tools.ant.Project.executeTargets(Project.java:1248)
at org.apache.tools.ant.Main.runBuild(Main.java:851)
at org.apache.tools.ant.Main.startAnt(Main.java:235)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

Here is the ant build file:

<?xml version="1.0" standalone="yes"?>
<!--  Copyright 2004 Sun Microsystems, Inc. All rights reserved. -->
<project basedir="." default="run">
<description>This sample application demonstrates how to use the ObjectFactory class to create a Java content tree from scratch and marshal it to XML data. It also demonstrates how to add content to a JAXB List property.</description>
<record name="build.log" loglevel="verbose" action="start"/>
<property name="jaxb.home" value="../.." />
<path id="classpath">
    <pathelement path="src" />
    <pathelement path="classes" />
    <pathelement path="schemas" />
    <fileset dir="${jaxb.home}" includes="lib/*.jar" />
</path>
<taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask">
    <classpath refid="classpath" />
</taskdef>
<!--compile Java source files-->
<target name="compile" description="Compile all Java source files">
    <echo message="Compiling the schema..." />
    <mkdir dir="gen-src" />
    <mkdir dir="gen-src/primer/po" />
    <xjc schema="POCD_MT000040_SDTC.xsd" package="primer.po" destdir="gen-src">
        <produces dir="gen-src/primer/po" includes="**/*.java" />
    </xjc>
    <echo message="Compiling the java source files..." />
    <mkdir dir="classes" />
    <javac destdir="classes" debug="on">
      <src path="src" />
      <src path="gen-src" />
      <classpath refid="classpath" />
    </javac>
  </target>
  <target name="run" depends="compile" description="Run the sample app">
    <echo message="Running the sample application..." />
    <java classname="Main" fork="true">
      <classpath refid="classpath" />
    </java>
  </target>
  <target name="javadoc" description="Generates javadoc" depends="compile">
    <echo message="Generating javadoc..." />
    <mkdir dir="docs/api" />
    <javadoc sourcepath="gen-src" destdir="docs/api" windowtitle="create-marshal (formerly SampleApp3)" useexternalfile="yes">
      <fileset dir="." includes="gen-src/**/*.java" excludes="**/impl/**/*.java" />
    </javadoc>
  </target>
  <target name="clean" description="Deletes all the generated artifacts.">
    <delete dir="docs/api" />
    <delete dir="gen-src" />
    <delete dir="schemas" />
    <delete dir="classes" />
  </target>
</project>
1
I have created [JIRA] (JAXB-1037). It seems that only duplicates of the form "abc" and "ABC" (all lower, all upper case) result in this particular bug/internal error causing IllegalArgumentException. Other duplicate field names (e.g. "abc" and "ABc") are properly diagnosed as an error.laune
There are three complexTypes with an "id" and an attribute ID. It is only these three that cause the problem. I have added the full xjb fixing everything to my answer. --- Forget the JIRA: this is only for others that stumble across this Q and think an issue should be raised, so they don't duplicate it.laune
i hope that everything is clear now: full bindings file, with it there is no error when compiling using xjc.laune
You might also read jaxb.java.net/tutorial, the JAXB tutorial I wrote. - What should be the purpose of me skimming over XML Schema files? Why would you need to write a book about them, and how would that be avoided?? Enigmatic ;-)laune

1 Answers

3
votes

The error you are reporting indicates that, somehow, ant has been instructed to read the same XML Schema definitions twice. Indeed, the error message says that one definition is in

C:\Temp\jaxb\apps\create-marshal\POCD_MT000040_SDTC.xsd

and the other one was found in

...\create-marshal\infrastructure\cda\POCD_MT000040_SDTC.xsd

You should clean up the file tree below create-marshal. You need one of these two, and, relatived to this file, the ones included by it, e.g.:

..\coreschemas\datatypes.xsd
..\coreschemas\voc.xsd
..\coreschemas\NarrativeBlock.xsd

Finally, datatypes-base.xsd must be in the same folder as these three, as it is included by datatypes.xsd.

But when you have tidied this up, you'll run into another problem, at least with the JAXB that comes with JDK 1.8. This is a bug in xjc, triggered by the (unintentional) duplication of a field "id" in a number of complex types, e.g., here:

<xs:complexType name="POCD_MT000040.ObservationMedia">
    ...
    <xs:element name="id" type="II" minOccurs="0" maxOccurs="unbounded"/>
    ...
  <xs:attribute name="ID" type="xs:ID"/>

The mapping of XML Schema names to Java names is defined in the JAXB spec, and, no matter how a clash is produced, this should result in an error message (not a stack dump, as it happens).

You have to handle this problem (bug or no bug) using customization with a JAXB binding file. Here's one (let'S call it rename.xjb), renaming the field matching @ID in POCD_MT000040.ObservationMedia to `xsid

FIXES ALL NAME CLASHES id vs. ID

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

<bindings schemaLocation="./POCD_MT000040.xsd" node="/xs:schema">
    <bindings node="//xs:complexType[@name='POCD_MT000040.ObservationMedia']/xs:attribute[@name='ID']">
        <property name="xsid"/>
    </bindings>
</bindings>

<bindings schemaLocation="./POCD_MT000040.xsd" node="/xs:schema">
    <bindings node="//xs:complexType[@name='POCD_MT000040.RegionOfInterest']/xs:attribute[@name='ID']">
        <property name="xsid"/>
    </bindings>
</bindings>

<bindings schemaLocation="./POCD_MT000040.xsd" node="/xs:schema">
    <bindings node="//xs:complexType[@name='POCD_MT000040.Section']/xs:attribute[@name='ID']">
        <property name="xsid"/>
    </bindings>
</bindings>
</bindings>

You have to add the bindings file to the xjc invocation. In ant, this would be the @binding of <xjc>:

<xjc schema="POCD_MT000040_SDTC.xsd" binding="rename.xjb" ...