XMLStreamException: xmlns has been already bound to . Rebinding it to http://deutsche-boerse.com/DBRegHub is an error
Asked Answered
V

2

1

I am using spring-batch in spring-boot application. The Spring Boot version is 2.3.3.RELEASE. I am not able to move the xmlns to the root tag.

Namespace and schema info should be attached at root level

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<reportFile xmlns="http://deutsche-boerse.com/DBRegHub" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://deutsche-boerse.com/DBRegHub regulatoryHubUpload_MiFIR_001.60.xsd">
    <fileInformation>
        <sender>11003220</sender>
        <timestamp>2020-12-23T09:05:34Z</timestamp>
        <environment>LOCAL</environment>
        <version>1.0</version>
    </fileInformation>
    <record>
        <transaction>
        </transaction>
        <transaction>
        </transaction>
        <transaction>
        </transaction>
    </record>
</reportFile>

What I am actually getting in response

<?xml version="1.0" encoding="UTF-8"?>
<reportFile xsi:schemaLocation="http://deutsche-boerse.com/DBRegHub regulatoryHubUpload_MiFIR_001.60.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <fileInformation>
        <sender>11003220</sender>
        <timestamp>2020-12-23T09:05:34Z</timestamp>
        <environment>LOCAL</environment>
        <version>1.0</version>
    </fileInformation>
    <record>
        <transaction xmlns="http://deutsche-boerse.com/DBRegHub">
        </transaction>
        <transaction xmlns="http://deutsche-boerse.com/DBRegHub">
        </transaction>
        <transaction xmlns="http://deutsche-boerse.com/DBRegHub">
        </transaction>
    </record>
</reportFile>

Below is a code snippet for configuring ItemWriter

public StaxEventItemWriter<TransactionPositionReport> staxTransactionItemWriter() {
    Resource exportFileResource = new FileSystemResource(FILE_LOCATION_PATH);


Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setSupportJaxbElementClass(true);
marshaller.setClassesToBeBound(TransactionPositionReport.class);
HashMap<String, String> rootElementAttribs = new HashMap<String, String>();
//rootElementAttribs.put("xmlns", "http://deutsche-boerse.com/DBRegHub");
rootElementAttribs.put("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
rootElementAttribs.put("xsi:schemaLocation", "http://deutsche-boerse.com/DBRegHub regulatoryHubUpload_MiFIR_001.60.xsd");

 ExtendedStaxEventItemWriter<TransactionPositionReport> writer = new ExtendedStaxEventItemWriter<TransactionPositionReport>();
 writer.setName("transactionWriter");
 writer.setVersion("1.0");
 writer.setResource(exportFileResource);
 writer.setMarshaller(marshaller);
 writer.setRootTagName("reportFile");
 writer.setRootElementAttributes(rootElementAttribs);
 writer.setHeaderCallback(omegaXmlHeaderCallBack);
 writer.setFooterCallback(getOmegaXmlFooterCallBack());
 writer.setShouldDeleteIfEmpty(true);
 writer.setIndenting(true);
 return writer;
}


import java.io.Writer;

import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;

import org.springframework.batch.item.xml.StaxEventItemWriter;

import javanet.staxutils.IndentingXMLEventWriter;

public class ExtendedStaxEventItemWriter<T> extends StaxEventItemWriter<T> {

    private boolean indenting;
    
    public void setIndenting(boolean indenting) {
        this.indenting = indenting;
    }

    public boolean isIndenting() {
        return indenting;
    }

    @Override
    protected XMLEventWriter createXmlEventWriter(XMLOutputFactory outputFactory, Writer writer)
            throws XMLStreamException {
        if (isIndenting()) {
            return new IndentingXMLEventWriter(super.createXmlEventWriter(outputFactory, writer));
        } else {
            return super.createXmlEventWriter(outputFactory, writer);
        }
    }

}



//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2021.05.18 at 02:21:55 PM BST 
//

   
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for transactionPositionReport complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="transactionPositionReport">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="processingDetails" type="{http://deutsche-boerse.com/DBRegHub}processingDetails"/>
 *         &lt;element name="configurableFields" type="{http://deutsche-boerse.com/DBRegHub}configurableFields" minOccurs="0"/>
 *         &lt;element name="mifir" type="{http://deutsche-boerse.com/DBRegHub}mifirDetails" minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "transactionPositionReport", propOrder = {
    "processingDetails",
    "configurableFields",
    "mifir"
})
@XmlRootElement(name = "transaction")
public class TransactionPositionReport {

    @XmlElement(required = true)
    protected ProcessingDetails processingDetails;
    protected ConfigurableFields configurableFields;
    protected MifirDetails mifir;

    /**
     * Gets the value of the processingDetails property.
     * 
     * @return
     *     possible object is
     *     {@link ProcessingDetails }
     *     
     */
    public ProcessingDetails getProcessingDetails() {
        return processingDetails;
    }

    /**
     * Sets the value of the processingDetails property.
     * 
     * @param value
     *     allowed object is
     *     {@link ProcessingDetails }
     *     
     */
    public void setProcessingDetails(ProcessingDetails value) {
        this.processingDetails = value;
    }

    /**
     * Gets the value of the configurableFields property.
     * 
     * @return
     *     possible object is
     *     {@link ConfigurableFields }
     *     
     */
    public ConfigurableFields getConfigurableFields() {
        return configurableFields;
    }

    /**
     * Sets the value of the configurableFields property.
     * 
     * @param value
     *     allowed object is
     *     {@link ConfigurableFields }
     *     
     */
    public void setConfigurableFields(ConfigurableFields value) {
        this.configurableFields = value;
    }

    /**
     * Gets the value of the mifir property.
     * 
     * @return
     *     possible object is
     *     {@link MifirDetails }
     *     
     */
    public MifirDetails getMifir() {
        return mifir;
    }

    /**
     * Sets the value of the mifir property.
     * 
     * @param value
     *     allowed object is
     *     {@link MifirDetails }
     *     
     */
    public void setMifir(MifirDetails value) {
        this.mifir = value;
    }

}


//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2021.05.18 at 02:21:55 PM BST 
//


import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for record complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="record">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;choice>
 *         &lt;element name="transaction" type="{http://deutsche-boerse.com/DBRegHub}transactionPositionReport" maxOccurs="unbounded" minOccurs="0"/>
 *         &lt;element name="referencePartyDetails" type="{http://deutsche-boerse.com/DBRegHub}referencePartyDetails" maxOccurs="unbounded" minOccurs="0"/>
 *       &lt;/choice>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "record", propOrder = {
    "transaction",
    "referencePartyDetails"
})
public class Record {

    protected List<TransactionPositionReport> transaction;
    protected List<ReferencePartyDetails> referencePartyDetails;

    /**
     * Gets the value of the transaction property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the transaction property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getTransaction().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link TransactionPositionReport }
     * 
     * 
     */
    public List<TransactionPositionReport> getTransaction() {
        if (transaction == null) {
            transaction = new ArrayList<TransactionPositionReport>();
        }
        return this.transaction;
    }

    /**
     * Gets the value of the referencePartyDetails property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the referencePartyDetails property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getReferencePartyDetails().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link ReferencePartyDetails }
     * 
     * 
     */
    public List<ReferencePartyDetails> getReferencePartyDetails() {
        if (referencePartyDetails == null) {
            referencePartyDetails = new ArrayList<ReferencePartyDetails>();
        }
        return this.referencePartyDetails;
    }

}


import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType>
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="fileInformation" type="{http://deutsche-boerse.com/DBRegHub}fileInformation"/>
 *         &lt;element name="record" type="{http://deutsche-boerse.com/DBRegHub}record"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "fileInformation",
    "record"
})
@XmlRootElement(name = "reportFile")
public class ReportFile {

    @XmlElement(required = true)
    protected FileInformation fileInformation;
    @XmlElement(required = true)
    protected Record record;

    /**
     * Gets the value of the fileInformation property.
     * 
     * @return
     *     possible object is
     *     {@link FileInformation }
     *     
     */
    public FileInformation getFileInformation() {
        return fileInformation;
    }

    /**
     * Sets the value of the fileInformation property.
     * 
     * @param value
     *     allowed object is
     *     {@link FileInformation }
     *     
     */
    public void setFileInformation(FileInformation value) {
        this.fileInformation = value;
    }

    /**
     * Gets the value of the record property.
     * 
     * @return
     *     possible object is
     *     {@link Record }
     *     
     */
    public Record getRecord() {
        return record;
    }

    /**
     * Sets the value of the record property.
     * 
     * @param value
     *     allowed object is
     *     {@link Record }
     *     
     */
    public void setRecord(Record value) {
        this.record = value;
    }

}

I have to comment rootElementAttribs.put("xmlns", "http://deutsche-boerse.com/DBRegHub"); otherwise it throws

    Caused by: javax.xml.stream.XMLStreamException: xmlns has been already bound to . Rebinding it to http://deutsche-boerse.com/DBRegHub is an error
        at com.sun.xml.internal.stream.writers.XMLStreamWriterImpl.writeDefaultNamespace(XMLStreamWriterImpl.java:786) ~[?:1.8.0_291]
        at com.sun.xml.internal.stream.writers.XMLStreamWriterImpl.writeNamespace(XMLStreamWriterImpl.java:1003) ~[?:1.8.0_291]
        at com.sun.xml.internal.stream.writers.XMLEventWriterImpl.add(XMLEventWriterImpl.java:127) ~[?:1.8.0_291]
        at javanet.staxutils.IndentingXMLEventWriter.add(IndentingXMLEventWriter.java:382) ~[stax-utils-20040917.jar:?]
        at org.springframework.batch.item.xml.StaxEventItemWriter.startDocument(StaxEventItemWriter.java:632) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.batch.item.xml.StaxEventItemWriter.open(StaxEventItemWriter.java:489) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]

UPDATE: If I remove @XmlRootElement(name = "transaction") from TransactionPositionReport class, I start getting below exception

    2021-06-15 10:10:59,390 ERROR o.s.b.c.s.AbstractStep [taskExecutor-1] Encountered an error executing step extractAndReplacePersonalDataStep in job extractAndReplacePersonalDataJob
org.springframework.batch.core.step.skip.NonSkippableReadException: Non-skippable exception during read
    at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:105) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:126) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:145) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:118) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:71) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:407) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:331) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:273) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:82) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:375) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    ... 72 more
Caused by: org.springframework.oxm.UnmarshallingFailureException: JAXB unmarshalling exception; nested exception is javax.xml.bind.UnmarshalException
 - with linked exception:
[com.sun.istack.internal.SAXParseException2; lineNumber: 10; columnNumber: 22; unexpected element (uri:"http://deutsche-boerse.com/DBRegHub", local:"transaction"). Expected elements are (none)]
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:951) ~[spring-oxm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:818) ~[spring-oxm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:788) ~[spring-oxm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.batch.item.xml.StaxEventItemReader.doRead(StaxEventItemReader.java:257) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:93) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_291]
    
    ... 72 more
Caused by: javax.xml.bind.UnmarshalException
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:468) ~[?:1.8.0_291]
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:448) ~[?:1.8.0_291]
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:420) ~[?:1.8.0_291]
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshalStaxSource(Jaxb2Marshaller.java:852) ~[spring-oxm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:801) ~[spring-oxm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:788) ~[spring-oxm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.batch.item.xml.StaxEventItemReader.doRead(StaxEventItemReader.java:257) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader.read(AbstractItemCountingItemStreamItemReader.java:93) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    
    ... 72 more
Caused by: com.sun.istack.internal.SAXParseException2: unexpected element (uri:"http://deutsche-boerse.com/DBRegHub", local:"transaction"). Expected elements are (none)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726) ~[?:1.8.0_291]
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247) ~[?:1.8.0_291]
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242) ~[?:1.8.0_291]
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109) ~[?:1.8.0_291]
    
    at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:87) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    ... 72 more
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://deutsche-boerse.com/DBRegHub", local:"transaction"). Expected elements are (none)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726) ~[?:1.8.0_291]
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247) ~[?:1.8.0_291]
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242) ~[?:1.8.0_291]
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109) ~[?:1.8.0_291]
    
    at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:99) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:87) ~[spring-batch-core-4.2.4.RELEASE.jar:4.2.4.RELEASE]
Vitals answered 14/6, 2021 at 17:59 Comment(0)
B
1

This is because the transaction element is marked as a root element while it should not:

@XmlRootElement(name = "transaction")
public class TransactionPositionReport {
   //...
}

<transaction/> tags are not root elements, you only need to mark <reportFile> as root element so that Spring Batch adds namespace attributes to it.

Brigette answered 15/6, 2021 at 6:45 Comment(10)
If I remove @XmlRootElement from TransactionPositionReport, I start getting this while reading: Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"deutsche-boerse.com/DBRegHub", local:"transaction"). Expected elements are (none)Vitals
Did you find anything wrong? I am getting above mentioned error after removing @XmlRootElement.Vitals
My answer is based on my static analysis of what you shared. It is not possible to find the root cause without reproducing the problem. Please provide a minimal example stackoverflow.com/help/minimal-reproducible-example that I can run to be able to help you in an efficient way.Brigette
After removing XmlRootElement from transaction, now i am getting org.springframework.oxm.MarshallingFailureException: JAXB marshalling exception; nested exception is javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.internal.SAXException2: unable to marshal type "com.trax.europeangateway.model.dto.xsd.omega.TransactionPositionReport" as an element because it is missing an @XmlRootElement annotation] at org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:948) ~[spring-oxm-5.2.8.RELEASE.jar:5.2.8.RELEASE]Vitals
Just after removing XmlRootElement from Transaction, I started getting SAXParseException2: unexpected element. But after adding transactionMarshaller.setMappedClass(TransactionPositionReport.class) it got resolved. Now only problem is with the marshalling.Vitals
So what's the latest status on this? Please update the question with the latest issue you still have to solve.Brigette
I have raised another question for the latest problem that i am facing. #68031811Vitals
ok I will take a look. That's another issue indeed. But I believe the answer here answered your initial question. If this is the case, please accept it. Thank you.Brigette
It didn't solve the complete problem, but i have upvoted your answer. Thanks for the help.Vitals
Yes, but your problem involves multiple issues. It would have been more efficient to share a repo with the minimal code the reproduces the issue as requested previously: #67975611. Anyway, I will try to help on the other question.Brigette
V
1

What I really wanted to achieve is to have namespace at the root level, rather than at every transaction tag. To get rid of this error I had to make a few changes in the StaxEventItemWriter object builder. First thing that I wanted is to add namespace at the root level, for that I have modified the rootTagName,

rootTagName("{http://deutsche-boerse.com/DBRegHub}reportFile")

@JobScope
@Bean(name = "staxTransactionWriter", destroyMethod="")
    public StaxEventItemWriter<TransactionPositionReport> staxTransactionItemWriter(OmegaXmlHeaderCallBack omegaXmlHeaderCallBack, 
            @Value("#{jobParameters['file.path']}") String path, @Value("#{jobParameters['submission.account']}") String submissionAccount) throws JAXBException {
        Resource exportFileResource = new FileSystemResource(fileUtils.getFilePath(path, submissionAccount, Directory.TEMP, true));
 
        JAXBContext jaxbContext = JAXBContext.newInstance(TransactionPositionReport.class);
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        
        OmegaXmlJaxb2Marshaller omegaXmlJaxb2Marshaller = new OmegaXmlJaxb2Marshaller(marshaller);
        omegaXmlJaxb2Marshaller.setContextPath("com.trax.europeangateway.model.dto.xsd.omega");
        omegaXmlJaxb2Marshaller.setSupportJaxbElementClass(true);
        omegaXmlJaxb2Marshaller.setCheckForXmlRootElement(false);
        
        return new StaxEventItemWriterBuilder<TransactionPositionReport>()
                .name("transactionWriter")
                .resource(exportFileResource)
                .marshaller(omegaXmlJaxb2Marshaller)
                .rootTagName("{http://deutsche-boerse.com/DBRegHub}reportFile")
                .headerCallback(omegaXmlHeaderCallBack)
                .footerCallback(getOmegaXmlFooterCallBack())
                .build();
    }

And because my transaction was not the root element, i had to add below provided code

QName qName = new QName(XMLConstants.NULL_NS_URI, "transaction", XMLConstants.DEFAULT_NS_PREFIX);
            JAXBElement<TransactionPositionReport> element = new JAXBElement(qName, TransactionPositionReport.class,
                    TransactionPositionReport.class, transaction);

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventWriter;
import javax.xml.transform.Result;

import org.springframework.lang.Nullable;
import org.springframework.oxm.XmlMappingException;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.oxm.mime.MimeContainer;
import org.springframework.util.xml.StaxUtils;

import com.trax.europeangateway.model.dto.xsd.omega.ObjectFactory;
import com.trax.europeangateway.model.dto.xsd.omega.TransactionPositionReport;

public class OmegaXmlJaxb2Marshaller extends Jaxb2Marshaller {
    
    private Marshaller marshaller = null;
    
    public OmegaXmlJaxb2Marshaller(Marshaller marshaller) {
        this.marshaller = marshaller;
    }
    
    @Override
    public void marshal(Object graph, Result result, @Nullable MimeContainer mimeContainer) throws XmlMappingException {
            try {
                marshalStaxResult(graph, result);
            } catch (JAXBException e) {
                e.printStackTrace();
            }
    }
    
    private void marshalStaxResult(Object graph, Result staxResult) throws JAXBException {

        XMLEventWriter eventWriter = StaxUtils.getXMLEventWriter(staxResult);
        if (eventWriter != null) {
            ObjectFactory fact = new ObjectFactory();
            TransactionPositionReport transaction = fact.createTransactionPositionReport();
            transaction.setConfigurableFields(((TransactionPositionReport) graph).getConfigurableFields());
            transaction.setMifir(((TransactionPositionReport) graph).getMifir());
            transaction.setProcessingDetails(((TransactionPositionReport) graph).getProcessingDetails());
            

            QName qName = new QName(XMLConstants.NULL_NS_URI, "transaction", XMLConstants.DEFAULT_NS_PREFIX);
            JAXBElement<TransactionPositionReport> element = new JAXBElement(qName, TransactionPositionReport.class,
                    TransactionPositionReport.class, transaction);

            marshaller.marshal(element, eventWriter);
        } else {
            throw new IllegalArgumentException("StAX Result contains neither XMLStreamWriter nor XMLEventConsumer");
        }

    }

}
Vitals answered 21/8, 2021 at 10:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.