アンマーシャリング中の ElementNSImpl から独自の型への断続的な ClassCastException
-
22-08-2019 - |
質問
ClassCastExceptions が発生するという、追跡が非常に難しい問題が発生しています。 時々 整列化されていないオブジェクトのリストを反復処理しようとしているとき。重要な点は 時々, 、再起動後、特定のコードは正常に動作します。これは、同時実行性/タイミング/競合状態の方向を指しているようです。JAXBContext も、マーシャラとアンマーシャラも同時に使用されていないことが確認できます。ロックを通じてそれらへのアクセスをシリアル化するところまで行きました。
ただし、個々のバンドルが Spring DM を通じて非同期に初期化される OSGi プラットフォーム上で実行しているため、2 つの異なるバンドルが同時に JAXBContext を作成している可能性があります。
いずれにせよ、これらの原因についての説明へのヒントをいただければ幸いです。 間欠 クラスキャスト例外。断続的は、コード自体は通常は正常に動作しているが、何らかの外部要因が動作に影響を与えているようであることを示しているため、重要です。
例外の具体的な例を次に示します (会社固有のものを削除したことに注意してください)。
Caused by: java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to com.foobar.TunnelType
at com.foobar.NetMonitorImpl.getVpnStatus(NetMonitorImpl.java:180)
180 行目のメソッドは、アンマーシャリングされたオブジェクト内の TunnelType オブジェクトのコレクションをループする for() コンストラクトです (ちなみに、アンマーシャリングは正常に機能します)。
実際のオブジェクトのアンマーシャリングがうまくいったとすると、JAXB が ElementNSImpl オブジェクトをネストされたコレクション内に残すことは物理的に可能でしょうか?
実行時環境:
- JAXB 2.1
- OSGi
- 春のDM
- JAXBContext は、マーシャリング/アンマーシャリングされるクラスを含むバンドルの ClassLoader で初期化されます。
解決 3
絶望のうち、我々はいくつかの競合状態のための唯一の残りの可能性として、これを見て、JAXBContext.class
のオブジェクトで同期をとることになって、少なくとも我々は再びこの問題を再現することができていません。ここで重要なコードです:
synchronized (JAXBContext.class) {
context = JAXBContext.newInstance(packageList, classLoader);
}
他のヒント
私はJAXBContextのを伝えるのを忘れた場合にのみ、この例外を取得します それは扱うことができに関するすべての-整列化する種類ます。
JAXBContext.newInstance(MyClass1.class,MyClass2.class, [...]);
ここで提案のアプローチのどちらも私のためにそれをやりました。しかし、これは
私の問題を解決しました@XmlAnyElement(lax = true)
public List<Foo> foos;
SYNCHRONIZED句は、上記にも私のために問題を解決しますが、コンテキストはローカル変数であるべきではないように思えます。その代わりに、インスタンス変数、または静的である必要があります。私はそれが欲しいのですか私のコードをリファクタリングすることができませんでしたので、代わりに私は完璧ではない静的初期化子、にコンテキストを移動しますが、動作しているようです。
private static Unmarshaller um;
static{
try {
final JAXBContext ctx = JAXBContext.newInstance(ObjectFactory.class.getPackage().getName());
um = ctx.createUnmarshaller();
} catch (final JAXBException e) {
e.printStackTrace();
}
}