Announcement Announcement Module
Collapse
No announcement yet.
Batch - JAXB2, JIBX and XMLBeans not working Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Batch - JAXB2, JIBX and XMLBeans not working

    I'm working on the Spring 3.1.0 release environment and using JDK1.6.
    I've a set of schema and I created the classes with the three tools (JAXB2, JiBX and XMLBeans). The compiled classes work when I tested them on standalone programs. Unfortunately they are not working when I incorporated them into my String Batch (ver 2.1.9) job. Only XStream works for my environment.

    My job is to unmarshall the XML and marshall the object to another XML.

    The symptom is the same - the job finished without error but the read count was zero.

    To be more exact, XMLBeans sort of work if I do not introduce a processor. Otherwise a ClassCast exception (cannot cast from XmlAnyTypeImpl ) will be thrown.

    Any hint is well appreciated.

    Thanks
    Last edited by yctang888; Nov 29th, 2012, 10:13 AM.

  • #2
    Can we see your job's configuration?

    Comment


    • #3
      Hi Michael,

      Attached please find my job.

      Since all the XML tools failed, it's quite sure to be a problem particular to my environment. I build using Gradle, here is part of the script:

      apply plugin: 'java'
      apply plugin: 'eclipse'
      apply plugin:'application'
      apply plugin:'maven'

      group = 'org.jfrog.buildinfo'
      version = '1.0'
      sourceCompatibility = 1.6


      compileJava {
      options.fork(executable: "C:/Program Files/Java/jdk1.6.0_34/bin/javac")
      }


      def artifactId = projectDir.name
      def groupId = group
      def versionNumber = version

      def springFrameworkVersion = '3.1+'
      def springBatchVersion = '2.1.9.RELEASE'
      def slf4jVersion = '1.6.4'
      def logbackVersion = '1.0.3'



      mainClassName = 'org.springframework.batch.core.launch.support.Com mandLineJobRunner'
      run {
      args = ['classpath:/jobs.xml', 'xmlFileReadAndWriterJob', 'inputFilePath=src/test/resources/test_2.xml', 'outputFilePath=C://temp/test_out.xml']

      }

      dependencies {
      runtime files(schemajar, jaxbschemajar, castorjar, domainjar, oraclejdbc)
      compile files(schemajar, jaxbschemajar, castorjar, domainjar)

      compile gradleApi()
      //groovy localGroovy()
      // runtime 'org.apache.xmlbeans:xmlbeans:2.5.0'
      compile 'org.apache.xmlbeans:xmlbeans:2.6.0'

      compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
      testCompile group: 'junit', name: 'junit', version: '4.+'

      compile group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.3.1'
      compile group: 'com.google.collections', name: 'google-collections', version: '1.0-rc5'

      compile "org.springframework:spring-jdbc:${springFrameworkVersion}"
      compile "org.springframework:spring-context:${springFrameworkVersion}"
      compile 'org.springframework:spring-oxm:3.1+'
      compile "cglib:cglib-nodep:2.2"
      compile "org.springframework.batch:spring-batch-core:${springBatchVersion}"
      compile "commons-dbcp:commons-dbcp:1.2.2"
      compile "hsqldb:hsqldb:1.8.0.7"
      compile "org.jibx:jibx-bind:1.2.4+"
      compile "org.jibx:jibx-extras:1.2.4+"
      runtime 'org.apache.commons:commons-lang3:3.1'
      runtime group: 'com.sun.xml.bind', name: 'jaxb-xjc', version: '2.2.4'
      runtime 'org.codehaus.castor:castor-xml:1.3.1'
      }


      Thanks.
      Last edited by yctang888; Nov 30th, 2012, 11:10 PM.

      Comment


      • #4
        Hi Michael,

        As in many other applications, each XML that we need to process contains repeating records. Here's a modified version of a schema that we are using:


        <xs:element name="MITEM" type="MyItems"></xs:element>
        <xs:complexType name="MyItems">
        <xs:sequence maxOccurs="1000">
        <xs:element name="ELEMENT" type="MyRecord">
        </xs:element>
        </xs:sequence>
        <xs:attributeGroup ref="FileAttrGroup">
        <xs:annotation>
        </xs:annotation>
        </xs:attributeGroup>
        </xs:complexType>

        Comment


        • #5
          Dear Michael,

          I found that it's an XML namespace issue similar to this:

          http://stackoverflow.com/questions/4...axb2marshaller

          I've not yet solved the problem, any suggestion is appreciated.

          Comment


          • #6
            Can I see the XML you're attempting to parse? In the example you linked to, their XML was invalid (non matching start and end tags for phone).

            Also, in your origional post, you point out that XStream works...why not use it then?

            Comment


            • #7
              Dear Michael,

              I'll switch to XStream.

              It's just a very typical structure like the Customers-customer XML described in your book (list 7-34). By the way your book and Manning's provided different views to Spring Batch, both books are very useful.

              The book (in fact all documents about Spring Batch told the same thing) mentioned that "Spring Batch is not picky about the XML binding technology you choose to use. Spring provides Unmarshaller implementations that use Castor, JAXB, JiBX, XMLBeans, and XStream". But this thread http://blog.gmane.org/gmane.comp.jav...month=20090501 mentioned the exactly the problem I got with JiBX that invalidated the claim of this "non picky"-ness.

              I extended the StaxEventItemReader to debug and sort of understood the problem but did not know how to solve.

              I'll open another thread to see whether any bright developer would care to tell me the solution.
              Last edited by yctang888; Dec 10th, 2012, 10:40 AM.

              Comment


              • #8
                So to recap, the issue you are experiencing is that the ItemReader is returning an instance of XmlAnyTypeImpl instead of your intended domain class. This causes the ClassCastException on the ItemProcessor because your processor is expecting your domain class but the ItemWriter is fine with accepting the XmlAnyTypeImpl class that gets passed if no processor exists.

                When we look at the job configuration you have posted, we see that your marshaller has been configured as below:
                Code:
                <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/>
                While this does create an instance of the CastorMarshaller, per the documentation (see here: http://static.springsource.org/sprin...arshaller.html) you need to provide a bit of additional information for it to know what object to serialize/deserialzie to. I tested the below configuration with a simple XML file with no issues.

                Code:
                    <bean id="customerFileReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
                        <property name="fragmentRootElementName" value="customer" />
                        <property name="resource" ref="customerFile" />
                        <property name="unmarshaller" ref="customerMarshaller" />
                    </bean>
                
                    <bean id="outputFile" class="org.springframework.core.io.FileSystemResource" scope="step">
                	<constructor-arg value="/tmp/customerProcessed.xml"/>
                    </bean>
                
                    <bean id="xmlOutputWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
                    	<property name="resource" ref="outputFile" />
                    	<property name="marshaller" ref="customerMarshaller" />
                    	<property name="rootTagName" value="customers" />
                    </bean>
                
                    <bean id="customerMarshaller" class="org.springframework.oxm.castor.CastorMarshaller">
                	<property name="targetClass" value="org.springsource.batch.domain.Customer"/>
                    </bean>

                Comment


                • #9
                  Dear Michael,
                  Thank you for your advise. Castor worked on my test program after adding the "targetClass" property.
                  I'll go for either XStreams or Castor for my project.

                  Thanks

                  Comment

                  Working...
                  X