title: Spring: StaxEventItemReader returning object with null values
body: <p>I have a Spring Batch job that reads an XML file and writes it to a database. Until today, everything was working fine. However, now the job is returning a ProgramElement object with null attributes to the processor. I am using the StaxEventItemReader and a custom Partitioner. Any idea why the reader is returning null attributes?</p>
  
  <p>EDIT: I should mention this happened after I updated Java from version 102 to 112.</p>
  
  <p>Job context file:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:aop="http://www.springframework.org/schema/aop" xmlns:batch="http://www.springframework.org/schema/batch"
  xmlns:task="http://www.springframework.org/schema/task" xmlns:file="http://www.springframework.org/schema/integration/file"
  xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:util="http://www.springframework.org/schema/util"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans.xsd    
  http://www.springframework.org/schema/integration/file 
  http://www.springframework.org/schema/integration/file/spring-integration-file.xsd
  http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/batch 
  http://www.springframework.org/schema/batch/spring-batch.xsd
  http://www.springframework.org/schema/context 
  http://www.springframework.org/schema/context/spring-context.xsd    
  http://www.springframework.org/schema/util 
  http://www.springframework.org/schema/util/spring-util.xsd
  http://www.springframework.org/schema/task
  http://www.springframework.org/schema/task/spring-task.xsd
  http://www.springframework.org/schema/jdbc 
  http://www.springframework.org/schema/jdbc/spring-jdbc.xsd"&gt;
  
  &lt;import resource="data-source-context.xml" /&gt;
  &lt;import resource="job-launcher-context.xml" /&gt;
  
  &lt;batch:job id="spa_r2_data_load"&gt;
      &lt;batch:step id="loadData"&gt;
          &lt;batch:partition step="loadDataStep" partitioner="filePartitioner" /&gt;
      &lt;/batch:step&gt;
  &lt;/batch:job&gt;
  
  &lt;batch:step id="loadDataStep"&gt;
      &lt;batch:tasklet&gt;
          &lt;batch:chunk reader="xmlItemReader" processor="peProcessor"
              writer="dbWriter" commit-interval="1" /&gt;
      &lt;/batch:tasklet&gt;
      &lt;batch:listeners&gt;
          &lt;batch:listener ref="listener"/&gt;
      &lt;/batch:listeners&gt;
  &lt;/batch:step&gt;
  
  &lt;bean id="listener" class="com.mason.seor.listener.FileListener" scope="step"&gt;
      &lt;property name="fileName" value="#{stepExecutionContext['file.location']}"/&gt;
  &lt;/bean&gt;
  
  &lt;bean id="filePartitioner" class="com.mason.seor.partitioner.FilePartitioner"&gt;
      &lt;property name="fileLocationsProp" value="${file.location}" /&gt;
      &lt;property name="fileNamesProp" value="${file.names:#{null}}" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="xmlItemReader" class="org.springframework.batch.item.xml.StaxEventItemReader" scope="step"&gt;
      &lt;property name="resource" value="#{stepExecutionContext['file.location']}" /&gt;
      &lt;property name="fragmentRootElementName" value="ProgramElement" /&gt;
      &lt;property name="unmarshaller"&gt;
          &lt;bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller"&gt;
              &lt;property name="classesToBeBound"&gt;
                  &lt;list&gt;
                      &lt;value&gt;com.mason.seor.model.r2.ProgramElement&lt;/value&gt;
                      &lt;value&gt;com.mason.seor.model.r2.ProgramElementFunding&lt;/value&gt;
                  &lt;/list&gt;
              &lt;/property&gt;
          &lt;/bean&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="peProcessor" class="com.mason.seor.processor.R2Processor"
      scope="step"/&gt;
  
  &lt;bean id="dbWriter"
      class="org.springframework.batch.item.database.HibernateItemWriter"&gt;
      &lt;property name="sessionFactory" ref="sessionFactory" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p></p>
  
  <p>File Partitioner:</p>
  
  <pre><code>package com.mason.seor.partitioner;
  
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileOutputStream;
  import java.io.FilenameFilter;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.io.OutputStreamWriter;
  import java.io.PrintWriter;
  import java.util.HashMap;
  import java.util.Map;
  
  import org.apache.commons.lang3.StringUtils;
  import org.springframework.batch.core.partition.support.Partitioner;
  import org.springframework.batch.item.ExecutionContext;
  
  public class FilePartitioner implements Partitioner {
  
  String fileLocationsProp;
  String fileNamesProp;
  
  @Override
  public Map&lt;String, ExecutionContext&gt; partition(int arg0){
  
      Map&lt;String, ExecutionContext&gt; partitionMap = new HashMap&lt;&gt;();
      String[] fileNames;
      if (fileNamesProp == null) {
          File filesDir = new File(fileLocationsProp.replace("file:", ""));
          if (!filesDir.isDirectory()) {
              throw new IllegalStateException("HEY! " + fileLocationsProp + " is not a directory!!!!!!!");
          }
  
          // create new filename filter
           FilenameFilter fileNameFilter = new FilenameFilter() {
  
              @Override
              public boolean accept(File dir, String name) {
                 if(name.lastIndexOf('.')&gt;0)
                 {
                    // get last index for '.' char
                    int lastIndex = name.lastIndexOf('.');
  
                    // get extension
                    String str = name.substring(lastIndex);
  
                    // match path name extension
                    if(str.equals(".xml"))
                    {
                       return true;
                    }
                 }
                 return false;
              }
           };
  
          fileNames = filesDir.list(fileNameFilter);
      } else {
          fileNames = fileNamesProp.split(",");
      }
      int counter = 0;
  
      for (String fileName : fileNames) {
  
          //trimXmlTags(fileLocationsProp,fileName);
  
          ExecutionContext context = new ExecutionContext();
          context.put("file.location", fileLocationsProp + fileName);
          context.put("file.name", fileName);
          counter++;
          partitionMap.put("file" + counter, context);
      }
  
      return partitionMap;
  }
  
  private void trimXmlTags(String fileLocation, String fileName){
          File xml = new File(fileLocation.replace("file:", "")+fileName);
          String charset = "UTF-8";
          // need to get rid of these prefixes for the XML tags and attributes
          String[] delete = {"r2:",":r2"};
          String[] replace = {"",""};
          // we don't need these lines
          String throwOut = "jb:";
          try {
              File temp = File.createTempFile("temp", ".xml", xml.getParentFile());
  
              //open file for reading
              BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(xml), charset));
              //open temp file for writing
              PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(temp), charset));
  
              for (String line; (line = reader.readLine()) != null;) {
                  line = StringUtils.replaceEach(line, delete, replace);
                  if(!line.contains(throwOut)){
                      writer.println(line);
                  }
              }
  
              reader.close();
              writer.close();
  
              xml.delete();
              temp.renameTo(xml);
  
  
          } catch (IOException e) {
              System.out.println("file location not found: "+xml.getParentFile());
              System.exit(1);
          }
  }
  
  public void setFileLocationsProp(String fileLocationsProp) {
      this.fileLocationsProp = fileLocationsProp;
  }
  
  public void setFileNamesProp(String fileNamesProp) {
      this.fileNamesProp = fileNamesProp;
  }
  
  }
  </code></pre>
  
  <p>ProgramElement class:</p>
  
  <pre><code>package com.mason.seor.model.r2;
  
  import java.util.Date;
  
  import javax.xml.bind.annotation.XmlAttribute;
  import javax.xml.bind.annotation.XmlElement;
  import javax.xml.bind.annotation.XmlRootElement;
  import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
  
  import com.mason.seor.data.SubmissionDateConverter;
  
  @XmlRootElement(name = "ProgramElement",     namespace="http://www.dtic.mil/comptroller/xml/schema/022009/r2")
  public class ProgramElement {
  
  String monetaryUnit;
  String programElementNumber;
  String programElementTitle;
  Integer r1LineNumber;
  Integer budgetYear;
  String budgetCycle;
  Date submissionDate;
  String serviceAgencyName;
  String AppropriationCode;
  String appropriationName;
  Integer budgetActivityNumber;
  String budgetActivityTitle;
  ProgramElementFunding programElementFunding;
  
  @XmlAttribute(name = "MonetaryUnit")
  public String getMonetaryUnit() {
      return monetaryUnit;
  }
  
  public void setMonetaryUnit(String monetaryUnit) {
      this.monetaryUnit = monetaryUnit;
  }
  
  @XmlElement(name = "ProgramElementNumber")
  public String getProgramElementNumber() {
      return programElementNumber;
  }
  
  public void setProgramElementNumber(String programelementNumber) {
      this.programElementNumber = programelementNumber;
  }
  
  @XmlElement(name = "ProgramElementTitle")
  public String getProgramElementTitle() {
      return programElementTitle;
  }
  
  public void setProgramElementTitle(String programElementTitle) {
      this.programElementTitle = programElementTitle;
  }
  
  @XmlElement(name = "R1LineNumber")
  public Integer getR1LineNumber() {
      return r1LineNumber;
  }
  
  public void setR1LineNumber(Integer r1LineNumber) {
      this.r1LineNumber = r1LineNumber;
  }
  
  @XmlElement(name = "BudgetYear")
  public Integer getBudgetYear() {
      return budgetYear;
  }
  
  public void setBudgetYear(Integer budgetYear) {
      this.budgetYear = budgetYear;
  }
  
  @XmlElement(name = "BudgetCycle")
  public String getBudgetCycle() {
      return budgetCycle;
  }
  
  public void setBudgetCycle(String budgetCycle) {
      this.budgetCycle = budgetCycle;
  }
  
  @XmlJavaTypeAdapter(type = Date.class, value = SubmissionDateConverter.class)
  @XmlElement(name = "SubmissionDate")
  public Date getSubmissionDate() {
      return submissionDate;
  }
  
  public void setSubmissionDate(Date submissionDate) {
      this.submissionDate = submissionDate;
  }
  
  @XmlElement(name = "ServiceAgencyName")
  public String getServiceAgencyName() {
      return serviceAgencyName;
  }
  
  public void setServiceAgencyName(String serviceAgencyName) {
      this.serviceAgencyName = serviceAgencyName;
  }
  
  @XmlElement(name = "AppropriationCode")
  public String getAppropriationCode() {
      return AppropriationCode;
  }
  
  public void setAppropriationCode(String appropriationCode) {
      AppropriationCode = appropriationCode;
  }
  
  @XmlElement(name = "AppropriationName")
  public String getAppropriationName() {
      return appropriationName;
  }
  
  public void setAppropriationName(String appropriationName) {
      this.appropriationName = appropriationName;
  }
  
  @XmlElement(name = "BudgetActivityNumber")
  public Integer getBudgetActivityNumber() {
      return budgetActivityNumber;
  }
  
  public void setBudgetActivityNumber(Integer budgetActivityNumber) {
      this.budgetActivityNumber = budgetActivityNumber;
  }
  
  @XmlElement(name = "BudgetActivityTitle")
  public String getBudgetActivityTitle() {
      return budgetActivityTitle;
  }
  
  public void setBudgetActivityTitle(String budgetActivityTitle) {
      this.budgetActivityTitle = budgetActivityTitle;
  }
  
  @XmlElement(name = "ProgramElementFunding")
  public ProgramElementFunding getProgramElementFunding() {
      return programElementFunding;
  }
  
  public void setProgramElementFunding(ProgramElementFunding programElementFunding) {
      this.programElementFunding = programElementFunding;
  }
  
  }
  </code></pre>
  
  <p>ProgramElementFunding class:</p>
  
  <pre><code>package com.mason.seor.model.r2;
  
  import javax.xml.bind.annotation.XmlElement;
  import javax.xml.bind.annotation.XmlType;
  
  @XmlType(name = "ProgramElementFunding")
  public class ProgramElementFunding {
  
  Double priorYear;
  Double currentYear;
  Double budgetYearOne;
  Double budgetYearOneBase;
  Double budgetYearTwo;
  Double budgetYearThree;
  Double budgetYearFour;
  Double budgetYearFive;
  
  @XmlElement(name = "PriorYear")
  public Double getPriorYear() {
      return priorYear;
  }
  public void setPriorYear(Double priorYear) {
      this.priorYear = priorYear;
  }
  @XmlElement(name = "CurrentYear")
  public Double getCurrentYear() {
      return currentYear;
  }
  public void setCurrentYear(Double currentYear) {
      this.currentYear = currentYear;
  }
  @XmlElement(name = "BudgetYearOne")
  public Double getBudgetYearOne() {
      return budgetYearOne;
  }
  public void setBudgetYearOne(Double budgetYearOne) {
      this.budgetYearOne = budgetYearOne;
  }
  @XmlElement(name = "BudgetYearOneBase")
  public Double getBudgetYearOneBase() {
      return budgetYearOneBase;
  }
  public void setBudgetYearOneBase(Double budgetYearOneBase) {
      this.budgetYearOneBase = budgetYearOneBase;
  }
  @XmlElement(name = "BudgetYearTwo")
  public Double getBudgetYearTwo() {
      return budgetYearTwo;
  }
  public void setBudgetYearTwo(Double budgetYearTwo) {
      this.budgetYearTwo = budgetYearTwo;
  }
  @XmlElement(name = "BudgetYearThree")
  public Double getBudgetYearThree() {
      return budgetYearThree;
  }
  public void setBudgetYearThree(Double budgetYearThree) {
      this.budgetYearThree = budgetYearThree;
  }
  @XmlElement(name = "BudgetYearFour")
  public Double getBudgetYearFour() {
      return budgetYearFour;
  }
  public void setBudgetYearFour(Double budgetYearFour) {
      this.budgetYearFour = budgetYearFour;
  }
  @XmlElement(name = "BudgetYearFive")
  public Double getBudgetYearFive() {
      return budgetYearFive;
  }
  public void setBudgetYearFive(Double budgetYearFive) {
      this.budgetYearFive = budgetYearFive;
  }
  
  
  
  }
  </code></pre>
  
  <p>XML example:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;ProgramElementList xmlns="http://www.dtic.mil/comptroller/xml/schema/022009/r2" targetSchemaVersion="1.0"&gt;
  &lt;ProgramElement monetaryUnit="Millions" classification="UNCLASSIFIED"&gt;
      &lt;ProgramElementNumber&gt;0601110D8Z&lt;/ProgramElementNumber&gt;
      &lt;ProgramElementTitle&gt;Basic Research Initiatives&lt;/ProgramElementTitle&gt;
      &lt;R1LineNumber&gt;3&lt;/R1LineNumber&gt;
      &lt;BudgetYear&gt;2017&lt;/BudgetYear&gt;
      &lt;BudgetCycle&gt;PB&lt;/BudgetCycle&gt;
      &lt;SubmissionDate&gt;2016-02&lt;/SubmissionDate&gt;
      &lt;ServiceAgencyName&gt;Office of the Secretary Of Defense&lt;/ServiceAgencyName&gt;
      &lt;AppropriationCode&gt;0400&lt;/AppropriationCode&gt;
      &lt;AppropriationName&gt;Research, Development, Test Evaluation, Defense-Wide&lt;/AppropriationName&gt;
      &lt;BudgetActivityNumber&gt;1&lt;/BudgetActivityNumber&gt;
      &lt;BudgetActivityTitle&gt;Basic Research&lt;/BudgetActivityTitle&gt;
      &lt;ProgramElementFunding&gt;
          &lt;PriorYear&gt;41.054&lt;/PriorYear&gt;
          &lt;CurrentYear&gt;71.940&lt;/CurrentYear&gt;
          &lt;BudgetYearOne&gt;36.654&lt;/BudgetYearOne&gt;
          &lt;BudgetYearOneBase&gt;36.654&lt;/BudgetYearOneBase&gt;
          &lt;BudgetYearTwo&gt;40.649&lt;/BudgetYearTwo&gt;
          &lt;BudgetYearThree&gt;42.988&lt;/BudgetYearThree&gt;
          &lt;BudgetYearFour&gt;45.607&lt;/BudgetYearFour&gt;
          &lt;BudgetYearFive&gt;46.500&lt;/BudgetYearFive&gt;
          &lt;CostToComplete&gt;Continuing&lt;/CostToComplete&gt;
          &lt;TotalCost&gt;Continuing&lt;/TotalCost&gt;
      &lt;/ProgramElementFunding&gt;
  &lt;/ProgramElement&gt;
  </code></pre>
  
  <p></p>