Bug 1127320

Summary: [GSS] (6.3.1) JAXB: Unmarshaller sets the incorrect element as nil
Product: [JBoss] JBoss Enterprise Application Platform 6 Reporter: Kyle Lape <klape>
Component: XML FrameworksAssignee: Navin Surtani <nsurtani>
Status: CLOSED CURRENTRELEASE QA Contact: Pavel Slavicek <pslavice>
Severity: unspecified Docs Contact: Tom WELLS <twells>
Priority: unspecified    
Version: 6.3.0CC: bbaranow, bmaxwell, cdewolf, jason.greene, jawilson, jbliznak, lcarlon, myarboro, nsurtani, pslavice, twells
Target Milestone: CR1Keywords: Triaged
Target Release: EAP 6.3.1   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Cause: JAXB has an internal 'nil' state that does not always get set back to 'false' at the appropriate time. Consequence: Certain elements that use the internal 'nil' field are erroneously set as nil even when they are not. Fix: Patch the bug so that JAXB will reset the 'nil' field properly. Result: Fields that were previously set to nil in error are no longer set to nil.
Story Points: ---
Clone Of: 1127318
: 1127946 (view as bug list) Environment:
Last Closed: 2014-10-13 18:36:49 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1127318    
Bug Blocks: 1102082, 1127327, 1127946    

Description Kyle Lape 2014-08-06 16:08:08 UTC
Upstream Jira link: https://java.net/jira/browse/JAXB-1028

Given the following schema: 

<xs:schema xmlns:tns="http://jaxb.gss.redhat.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0" targetNamespace="http://jaxb.gss.redhat.com/">
  <xs:element name="team" type="tns:team"/>
  <xs:complexType name="team">
    <xs:sequence>
      <xs:element ref="tns:abstractName"/>
      <xs:element ref="tns:member"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element abstract="true"  name="abstractName" nillable="false"/>
  <xs:element abstract="false" name="name"         nillable="true" substitutionGroup="tns:abstractName" type="xs:string"/>
  <xs:element abstract="true"  name="member"       nillable="false"/>
  <xs:element abstract="false" name="programmer"   nillable="true" substitutionGroup="tns:member" type="xs:string"/>
</xs:schema>

And the following XML:

<team xmlns="http://jaxb.gss.redhat.com/">
  <name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
  <programmer>Kyle</programmer>
</team>

A JAXB unmarshaller will mark the <programmer> element as nil, yet still have the value of "Kyle" associated with the JAXBElement.

Code to test:

package com.redhat.gss.jaxb;

import java.net.URL;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;

public class Test {
  private static JAXBContext ctx = null;

  public static void main(String[] args) throws Exception {
    ctx = JAXBContext.newInstance(ObjectFactory.class, Team.class, String.class);
    URL inputUrl = Test.class.getResource("/no-nil.xml");
    System.out.println("Non-nil test.");
    doTest(inputUrl);
    System.out.println("\nNil test.  Member should NOT be nil");
    inputUrl = Test.class.getResource("/nil.xml");
    doTest(inputUrl);
  }

  public static void doTest(URL inputUrl) throws Exception {
    Unmarshaller unm = ctx.createUnmarshaller();
    Object o = unm.unmarshal(inputUrl);
    Team team = ((JAXBElement<Team>)o).getValue();
    System.out.println("Name: " + team.getAbstractName().getValue());
    System.out.println("Name nil? " + (team.getAbstractName().isNil() ? "YES" : "NO"));
    System.out.println("Member: " + team.getMember().getValue());
    System.out.println("Member nil? " + (team.getMember().isNil() ? "YES" : "NO"));
  }
}

Comment 2 Jan Blizňák 2014-09-01 17:36:41 UTC
Verified on 6.3.1.CP.CR1