Announcement Announcement Module
Collapse
No announcement yet.
spring batch & Jaxb2Marshaller Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • spring batch & Jaxb2Marshaller

    I am attempting to use Spring Batch to read an XML input file and save each chunk into a database, but I am getting the following exception:

    Code:
    Caused by: javax.xml.bind.UnmarshalException
     - with linked exception:
    [org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'Account'.]
            at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315)
            at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:514)
            at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:215)
            at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:184)
            at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:120)
            at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:103)
            at org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:581)
            ... 29 more
    Caused by: org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'Account'.
            at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
            at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:131)
            at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:384)
            at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:318)
            at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1916)
            at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:705)
            at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(ValidatorHandlerImpl.java:549)
            at com.sun.xml.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(ValidatingUnmarshaller.java:89)
            at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:71)
            at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:148)
            at org.springframework.xml.stream.StaxEventXmlReader.handleStartElement(StaxEventXmlReader.java:154)
            at org.springframework.xml.stream.StaxEventXmlReader.parseInternal(StaxEventXmlReader.java:98)
            at org.springframework.xml.stream.AbstractStaxXmlReader.parse(AbstractStaxXmlReader.java:132)
            at org.springframework.xml.stream.AbstractStaxXmlReader.parse(AbstractStaxXmlReader.java:115)
            at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:211)
            ... 33 more
    I have seen numerous posts with similar problems, but none of the recommended solutions have resolved the issue. I suspect that the issue is with the namespace / element declarations in my XSD, but I can't seem to find the right combination. Any help would be greatly appreciated.

    Here is my Spring config:

    Code:
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:batch="http://www.springframework.org/schema/batch" 
    	xmlns:p="http://www.springframework.org/schema/p"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    	xmlns:util="http://www.springframework.org/schema/util"
    	xsi:schemaLocation="
    		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    		http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
    		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">
    		
    	<batch:job-repository id="jobRepository"
    		data-source="dataSource" 
    		transaction-manager="transactionManager"
    		isolation-level-for-create="READ_COMMITTED" 
    		table-prefix="BATCH_" />
    
    	<bean id="jobLauncher"
    		class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    		<property name="jobRepository" ref="jobRepository" />
    		<!-- This will allow asynchronous launching of jobs (eg. from a browser) -->
    		<property name="taskExecutor">
    			<bean class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
    		</property>
    	</bean>
    
    	<batch:job id="cfImportJob">
    		<batch:step id="cfImportStep">
    			<batch:tasklet>
    				<batch:chunk 
    					reader="cfImportReader"
    					processor="cfImportProcessor"
    					writer="cfImportWriter" 
    					commit-interval="1">
    					<batch:streams>
    						<batch:stream ref="cfImportReader" />
    					</batch:streams>
    				</batch:chunk>
    				<batch:transaction-attributes isolation="READ_COMMITTED" />
    			</batch:tasklet>
    		</batch:step>
    	</batch:job>
    
    	<bean id="cfImportReader" class="org.springframework.batch.item.xml.StaxEventItemReader">
    		<property name="strict" value="true" />
    		<property name="fragmentRootElementName" value="Account" />
    		<property name="resource" ref="fileInputLocator" />
    		<property name="unmarshaller" ref="jaxbCFMarshaller" />
    	</bean>
    	
    	<bean id="cfImportProcessor" class="com.mydomain.validation.feed.cf.CFImportProcessor" /> 
    
    	<bean id="cfImportWriter" class="com.mydomain.validation.feed.cf.CFImportWriter">
    		<property name="sessionFactory" ref="sessionFactory" />
    	</bean>
    
    	<bean id="jaxbCFMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    		<property name="classesToBeBound">
    			<list>
    				<value>com.mydomain.validation.feed.cf.accountextract.Records</value>
    				<value>com.mydomain.validation.feed.cf.accountextract.Accounts</value>
    				<value>com.mydomain.validation.feed.cf.accountextract.Account</value>
    			</list>
    		</property>
    		<property name="schema" value="classpath:schemas/CF.xsd"/>
    	</bean>
    	
    	<bean id="fileInputLocator" 
    		class="org.springframework.core.io.FileSystemResource" scope="step">
    		<constructor-arg type="java.lang.String" value="#{jobParameters[filename]}" />
    	</bean>
    
    </beans>
    My schema:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema 
    	xmlns:xs="http://www.w3.org/2001/XMLSchema"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:cf="http://mydomain.com/cf/accountextract" 
    	targetNamespace="http://mydomain.com/cf/accountextract"
    	attributeFormDefault="unqualified"
    	elementFormDefault="qualified" >
    
    	<xs:element name="Records">
    		<xs:complexType>
    			<xs:sequence>
    				<xs:element name="Accounts" type="cf:Accounts" />
    			</xs:sequence>
    		</xs:complexType>
    	</xs:element>
    
    	<xs:complexType name="Accounts">
    		<xs:sequence>
    			<xs:element name="Account" type="cf:Account" minOccurs="0" maxOccurs="unbounded"/>
    		</xs:sequence>
    	</xs:complexType>
    
    	<xs:complexType name="Account">
    		<xs:sequence>
    			<!-- Account -->
    	  		<xs:element name="AccountName" type="xs:string" />
          		<xs:element name="Phone" type="xs:string" />
          		<xs:element name="ClientNo" type="xs:string" minOccurs="0"/>
    		</xs:sequence>
    	</xs:complexType>
    
    </xs:schema>
    ... and my XML input file:

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <Records xmlns="http://mydomain.com/cf/accountextract">
      <Accounts>
        <Account>
          <AccountName>Sample Company</AccountName>
          <Phone>5145551212</PhoneNpa>
          <ClientNo>1234567890</ClientNo>
        </Account>
        <Account>
          <AccountName>Sample Company</AccountName>
          <Phone>5145551212</PhoneNpa>
          <ClientNo>1234567890</ClientNo>
        </Account>
      </Accounts>
    </Records>
    Thanks in advance!
    Last edited by freecouch; Jan 12th, 2011, 12:49 PM.

  • #2
    You can probably avoid the schema error by simply switching off the validation (miss out the schema= declaration in the unmarshaller).

    I'm not sure anyone who hangs out in this forum knows the answer. OXM is not a Batch feature so you might get more help on the main Spring forum, or the Web Services forum. If you re-post there you probably need to include the .java source for your Account object.

    Comment


    • #3
      <Phone>5145551212</PhoneNpa>

      This is wrong, it needs to be <Phone>5145551212</Phone>

      Comment

      Working...
      X