EclipseLink Moxy の javax.xml.bind.Binder 実装に問題があります。DOM ドキュメント インスタンスからオブジェクトを非整列化すると、結合クラスで注釈が付けられた非整列化コールバック メソッド(私の場合は afterUnmarshal) が呼び出されません。
問題は、Binder によって使用されるorg.eclipse.persistence.oxm.XMLUnmarshallerインスタンスにあるようです。コールバック メソッドの呼び出しを担当する unmarshalListener は常に null です。このコードは問題を示しています:
//Instantiate a JAXBContext
JAXBContext context = JAXBContext.newInstance(MyObject.class);
//Create a "standard" unmarshaller
JAXBUnmarshaller standardUnmarshaller = (JAXBUnmarshaller) context.createUnmarshaller();
//assertion is ok
assert standardUnmarshaller.getXMLUnmarshaller().getUnmarshalListener() != null;
//Create a Binder
XMLBinder xmlBinder = ((JAXBBinder) context.createBinder()).getXMLBinder();
//Use reflection tricks to get the unmarshaller (fest-reflect is used for conciseness)
XMLUnmarshaller binderUnmarshaller = Reflection.field("unmarshaller").ofType(XMLUnmarshaller.class).in(xmlBinder).get();
//assertion error here
assert binderUnmarshaller.getUnmarshalListener() != null;
org.eclipse.persistence.jaxb.JAXBUnmarshalListenerは、Binder コンテキストに存在しない javax.xml.bind.Unmarshaller インスタンスなしではインスタンス化できないため、これを簡単に修正することはできません。JAXBUnmarshalListener を置き換えるために Moxy で利用できる XMLUnmarshalListener 実装は他にありません。
「標準」の JAXB unmarshaller から JAXBUnmarshalListener インスタンスを再利用することで構成されるこの回避策を思いつきました。:
//Instantiate a JAXBContext
JAXBContext context = JAXBContext.newInstance(MyObject.class);
//Create a Binder
JAXBBinder binder = (JAXBBinder) context.createBinder();
//Create an standard unmarshaller to reuse its unmarshalListener
JAXBUnmarshaller standardUnmarshaller = (JAXBUnmarshaller) context.createUnmarshaller();
//Use reflection for setting the binder's unmarshallerListener (fest-reflect again)
XMLUnmarshaller unmarshaller = Reflection.field("unmarshaller").ofType(XMLUnmarshaller.class).in(binder.getXMLBinder()).get();
unmarshaller.setUnmarshalListener(standardUnmarshaller.getXMLUnmarshaller().getUnmarshalListener());
//my unmarshal callbacks are called now
MyObject myObject = binder.unmarshal(domDocument);
問題はマーシャリング メソッドでも同じだと思いますが、マーシャリング コールバックを使用しないため、このケースは調査しませんでした。
javax.xml.bind.Binder の JAXB RI 実装をテストしたところ、コールバック メソッドが正しく呼び出されました。ただし、元の DOM ドキュメントのコメント ノードが保持されないため、RI を使用することはできません。
Moxy の構成に何かミスがありましたか、それとも実装のバグですか? バグの場合、私が使用したものよりも簡単な回避策はありますか?