java.lang.IllegalStateException: Marshaller must support the class of the marshalled object
Asked Answered
S

0

0

I am using spring batch in the spring-boot application. The Spring Boot version is 2.3.3.RELEASE. I have a complex XML that contains header(file information) and body(List of the transaction). I used XJC tool to get java classes from the XSD.

To reproduce this error i have added the code on Github spring-batch-xml-to-xml

What I need to do: I have to read(unmarshal) the XML, do some business logic on each transaction element in the body, and then finally write(marshal) the XML file with the same header and updated body.

When I try to marshal a child element object, I am getting IllegalStateException: Marshaller must support the class of the marshalled object.

Sample XML file

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

Spring Batch Configuration

package com.trax.europeangateway.config;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.JobScope;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.launch.support.SimpleJobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemStreamReader;
import org.springframework.batch.item.support.CompositeItemProcessor;
import org.springframework.batch.item.support.CompositeItemWriter;
import org.springframework.batch.item.xml.StaxEventItemWriter;
import org.springframework.batch.item.xml.builder.StaxEventItemReaderBuilder;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.task.TaskExecutor;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.oxm.xstream.XStreamMarshaller;
import org.springframework.util.ClassUtils;
import org.springframework.web.client.RestTemplate;

import com.trax.europeangateway.itemprocessor.omegaxml.PIExtractorItemProcessor;
import com.trax.europeangateway.itemprocessor.omegaxml.PIRemoverItemProcessor;
import com.trax.europeangateway.itemwriter.omegaxml.EdsClientItemWriter;
import com.trax.europeangateway.itemwriter.omegaxml.ExtendedStaxEventItemWriter;
import com.trax.europeangateway.itemwriter.omegaxml.OmegaXmlFileWriter;
import com.trax.europeangateway.itemwriter.omegaxml.OmegaXmlFooterCallBack;
import com.trax.europeangateway.itemwriter.omegaxml.OmegaXmlHeaderCallBack;
import com.trax.europeangateway.listener.JobResultListener;
import com.trax.europeangateway.listener.StepResultListener;
import com.trax.europeangateway.model.dto.FileInformationHeaderDto;
import com.trax.europeangateway.model.dto.ProcessorWriterDto;
import com.trax.europeangateway.model.dto.xsd.omega.TransactionPositionReport;
import com.trax.europeangateway.service.ExtractHeaderOmegaXml;
import com.trax.europeangateway.util.FileUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
    
    @Autowired
    PIExtractorItemProcessor pIExtractorItemProcessor;
    
    @Autowired
    StepResultListener stepResultListener;
    
    @Autowired
    JobBuilderFactory jobBuilderFactory;
     
    @Autowired
    StepBuilderFactory stepBuilderFactory;
    
    @Autowired
    private FileUtils fileUtils;
    
    @Qualifier("europeanGatewayJobExecutor")
    @Autowired
    private TaskExecutor taskExecutor;
    
    @Value( "${eugateway.batch.chunk.size}" )
    private int chunkSize;
    
    @Qualifier("euGatewayJobLauncher")
    @Bean
    public JobLauncher euGatewayJobLauncher(JobRepository jobRepository) throws Exception {
        SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
        jobLauncher.setJobRepository(jobRepository);
        jobLauncher.setTaskExecutor(taskExecutor);
        jobLauncher.afterPropertiesSet();
        return jobLauncher;
    }
    
    @JobScope
    @Bean (name = "extractHeaderStep")
    public Step extractHeaderStep(StepBuilderFactory steps , @Value("#{jobParameters['file.path']}") String path) {
        return steps.get("extractHeaderStep")
                .tasklet((contribution, chunkContext) -> {
                    FileInformationHeaderDto fileInformation = new ExtractHeaderOmegaXml().readHeader(path);
                    ExecutionContext jobExecutionContext =  chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();
                    jobExecutionContext.put("file.information", fileInformation);
                    return RepeatStatus.FINISHED;
                }).build();
    }
    
    @JobScope
    @Bean (name = "extractAndReplacePersonalDataStep")
    public Step jobStep(ItemStreamReader<TransactionPositionReport> reader,
            CompositeItemProcessor<TransactionPositionReport, 
            ProcessorWriterDto> processor,
            CompositeItemWriter<ProcessorWriterDto> writer,
            StepBuilderFactory stepBuilderFactory) {
        return stepBuilderFactory.get("extractAndReplacePersonalDataStep")
                .<TransactionPositionReport, ProcessorWriterDto>chunk(chunkSize)
                .reader(reader)
                .processor(processor)
                .writer(writer)
                .listener(stepResultListener)
                .build();
    }

    @Qualifier("omegaXmlJob")
    @Bean
    public Job extractPersonalDataJob(Step extractHeaderStep, Step extractAndReplacePersonalDataStep, JobResultListener jobListener,
            JobBuilderFactory jobBuilderFactory) {
        return jobBuilderFactory.get("extractAndReplacePersonalDataJob")
                .incrementer(new RunIdIncrementer())
                .start(extractHeaderStep)
                .next(extractAndReplacePersonalDataStep)
                .listener(jobListener)
                .build();
    }

    @Bean
    @StepScope
    public ItemStreamReader<TransactionPositionReport> itemReader(@Value("#{jobParameters['file.path']}") String path) {
        Jaxb2Marshaller transactionMarshaller = new Jaxb2Marshaller();
        transactionMarshaller.setMappedClass(TransactionPositionReport.class);
        transactionMarshaller.setPackagesToScan(ClassUtils.getPackageName(TransactionPositionReport.class));
        transactionMarshaller.setSupportJaxbElementClass(true);
        transactionMarshaller.setSupportDtd(true);
        log.debug("Generating StaxEventItemReader");
 
        return new StaxEventItemReaderBuilder<TransactionPositionReport>()
                .name("transactionPositionReport")
                .resource(new FileSystemResource(path))
                .addFragmentRootElements("transaction")
                .unmarshaller(transactionMarshaller)
                .build();
    }
    
    @Bean
    @JobScope
    OmegaXmlHeaderCallBack getOmegaXmlHeaderCallBack(@Value("#{jobExecutionContext['file.information']}") FileInformationHeaderDto fileInformation){
        return new OmegaXmlHeaderCallBack(fileInformation);
    }
    
    @Bean
    OmegaXmlFooterCallBack getOmegaXmlFooterCallBack(){
        return new OmegaXmlFooterCallBack();
    }
    
    @StepScope
    @Bean(name = "staxTransactionWriter")
    public StaxEventItemWriter<TransactionPositionReport> staxTransactionItemWriter(OmegaXmlHeaderCallBack omegaXmlHeaderCallBack, 
            @Value("#{jobParameters['file.path']}") String path, @Value("#{jobParameters['submission.account']}") String submissionAccount) {
        Resource exportFileResource = new FileSystemResource(fileUtils.getOutputFilePath(path, submissionAccount));
 
        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;
    }
    
    @StepScope
    @Bean
    public PIExtractorItemProcessor extractItemProcessor() {
        log.debug("Generating PIExtractorItemProcessor");
        return new PIExtractorItemProcessor();
    }
    
    @Bean
    public PIRemoverItemProcessor removeItemProcessor() {
        log.debug("Generating PIRemoverItemProcessor");
        return new PIRemoverItemProcessor();
    }
    
    @Bean
    @StepScope
    CompositeItemProcessor<TransactionPositionReport, ProcessorWriterDto> extractAndRemoveItemProcessor() {
        log.debug("Generating CompositeItemProcessor");
        CompositeItemProcessor<TransactionPositionReport, ProcessorWriterDto> itemProcessor = new CompositeItemProcessor<>();
        itemProcessor.setDelegates((List<? extends ItemProcessor<?, ?>>) Arrays.asList(extractItemProcessor(), removeItemProcessor()));
        return itemProcessor;
    }
    
    @Bean
    public EdsClientItemWriter<ProcessorWriterDto> edsClientItemWriter() {
        log.debug("Generating EdsClientItemWriter");
        return new EdsClientItemWriter<>();
    }
    
    @Bean
    @StepScope
    public OmegaXmlFileWriter<ProcessorWriterDto> omegaXmlFileWriter(OmegaXmlHeaderCallBack omegaXmlHeaderCallBack, @Value("#{jobParameters['file.path']}") String path, @Value("#{jobParameters['submission.account']}") String submissionAccount) {
        log.debug("Generating OmegaXmlFileWriter");
        return new OmegaXmlFileWriter(staxTransactionItemWriter(omegaXmlHeaderCallBack, path, submissionAccount));
    }
    
    
    @Bean
    @StepScope
    public CompositeItemWriter<ProcessorWriterDto> compositeItemWriter(OmegaXmlHeaderCallBack omegaXmlHeaderCallBack, @Value("#{jobParameters['file.path']}") String path, @Value("#{jobParameters['submission.account']}") String submissionAccount) {
        log.debug("Generating CompositeItemWriter");
        CompositeItemWriter<ProcessorWriterDto> compositeItemWriter = new CompositeItemWriter<>();
        compositeItemWriter.setDelegates(Arrays.asList(edsClientItemWriter(), omegaXmlFileWriter(omegaXmlHeaderCallBack, path, submissionAccount)));
        return compositeItemWriter;
    }
    
    @Bean
    public RestTemplate restTemplate() {
        log.debug("Generating RestTemplate");
        return new RestTemplate();
    }
}

Transaction, Report and ReportFile java classes generated from XJC tool

//
// 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"
})
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;
    }

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

}

Stacktrace of exception that I get when trying to marshal

java.lang.IllegalStateException: Marshaller must support the class of the marshalled object
    at org.springframework.util.Assert.state(Assert.java:76) ~[spring-core-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.batch.item.xml.StaxEventItemWriter.write(StaxEventItemWriter.java:767) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.batch.item.xml.StaxEventItemWriter$$FastClassBySpringCGLIB$$d105dd1.invoke(<generated>) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:136) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) ~[spring-aop-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.batch.item.xml.StaxEventItemWriter$$EnhancerBySpringCGLIB$$25cb8145.write(<generated>) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at com.trax.europeangateway.itemwriter.omegaxml.OmegaXmlFileWriter.write(OmegaXmlFileWriter.java:37) ~[classes/:?]
    at com.trax.europeangateway.itemwriter.omegaxml.OmegaXmlFileWriter$$FastClassBySpringCGLIB$$48e7f3da.invoke(<generated>) ~[classes/:?]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    

FYI: In the generated java classes only ReportFile class is annotated with @XmlRootElement. But if I annotate the transaction class with @XmlRootElement, I am able to get generate a XML file but then all the transaction tag in the output file have namespace info with them.

<?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>
Salena answered 18/6, 2021 at 7:48 Comment(12)
I see you have set marshaller.setSupportJaxbElementClass(true); marshaller.setClassesToBeBound(TransactionPositionReport.class); on the marshaller, so I don't understand (by just looking at what you shared) why you are getting this error. This kind of errors is not easy to investigate without being able to reproduce them, so please provide a repo with a minimal complete example to be able to help you.Counselor
github.com/trueKiller07/spring-batch-xml-to-xml README file has the information to run integration test To reproduce the error, simply remove the @XmlRootElement from TransactionPositionReport.java class.Salena
If you see the logs you will also see footer being called multiple times which throws ArrayIndexOutOfBoundException also. I reckon that header and footer are called once per job but then why multiple time exception is thrown?Salena
@MahmoudBenHassine, were you able to reproduce the issue?Salena
Thanks for the sample, I will take a look.Counselor
When I run your integration test, I get this error: java: java.lang.ExceptionInInitializerError Unable to make field private com.sun.tools.javac.processing.JavacProcessingEnvironment$DiscoveredProcessors com.sun.tools.javac.processing.JavacProcessingEnvironment.discoveredProcs accessible: module jdk.compiler does not "opens com.sun.tools.javac.processing" to unnamed module @272e20ee.Counselor
Moreover, your expected xml file contains the namespace in transactions tags: github.com/trueKiller07/spring-batch-xml-to-xml/blob/main/src/… , but in your description you said that you don't want those namespace attributes on the transaction tags: But if I annotate the transaction class with @XmlRootElement, I am able to get generate a XML file but then all the transaction tag in the output file have namespace info with them.. Sorry, I'm trying to help but I'm lost.Counselor
@MahmoudBenHassine, sorry if I confused you. I have updated the desired output file.Salena
@MahmoudBenHassine, I am not getting ExceptionInInitializerError. I cloned the project on a different laptop and tested it there as well.Salena
Let us continue this discussion in chat.Salena
@MahmoudBenHassine Can you have a look at another problem i faced in batch app. #68150180Salena
I was facing same issue, changing the import javax.xml.bind.annotation.XmlRootElement; to import jakarta.xml.bind.annotation.XmlRootElement worked for me. Dont forget to add maven dependenciesBrandi

© 2022 - 2024 — McMap. All rights reserved.