Java SE 8 Update 92 では動いていたのに、Update 102 にしたら JAXB で XML を unmarshal したときにプロパティに値がセットされなくなるパターンがあるというお話。
自分は、RSS のパースではまりました。
どんなコード?
下記のようなデフォルト名前空間がついた XML があります。
(これの場合、xmlns="http://purl.org/rss/1.0/" がデフォルト名前空間の指定)
<?xml version="1.0" encoding="UTF-8"?> <rdf:RDF xmlns="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > <title>Sample RSS</title> </rdf:RDF>
この XML を下記のコードで unmarshal してオブジェクトに格納しようとした場合、Update 92 では title プロパティに "Sample RSS" がセットされるのですが、Update 102 では値がセットされずに null になります。
import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; public class JDK8165299 { public static void main(String[] args) throws JAXBException { JAXBContext context = JAXBContext.newInstance(Rss.class); Unmarshaller unmarshaller = context.createUnmarshaller(); Rss rss = (Rss) unmarshaller.unmarshal(new java.io.File("rss.xml")); System.out.println(rss.title); } @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "RDF", namespace = "http://www.w3.org/1999/02/22-rdf-syntax-ns#") public static class Rss { @XmlElement(name = "title") public String title; } }
なんで?
最初にも書いた通り、XML にデフォルト名前空間が指定されています。
その場合、Java SE 8 Update 92 まで誤って XmlElement アノテーションに名前空間を指定していなくてもマッピングがされてしまっていました。
それが、Java SE 8 Update 102 で修正されたのが原因です*1。
なので、下記のように XmlElement に名前空間を指定すれば、Java SE 8 Update 102 でも title に値がマッピングされます。
@XmlElement(name = "title", namespace = "http://purl.org/rss/1.0/") public String title;
ちなみに、このデフォルト名前空間を指定していなくても誤ってマッピングされる事象は Java SE 8 (First Release) 〜 Update 92 までの間で発生します。
Java SE 7 Update 79 だと、事象は発生しません。なんでやねん。