2

JAXB (Hibernate が dom4j で提供)、Hibernate (4.1.3)、および Eclipse (4.2) プラグインを組み合わせようとしています。

私の「コア」プラグインには、特定の pojo (別のプラグインから @XmlRootElement と残りのアノテーションが付けられたもの) を受け取り、それを XML に、またはその逆に変換する XMLUserType が含まれています。アンマーシャリングは、このコードで正常に機能します (cls は、パラメーターによって文字列ごとに指定されるクラスです。

public Object fromXMLString(final String xml) {
    if (null != xml) {
        final ClassLoader cl = Thread.currentThread().getContextClassLoader();
        try {
            Thread.currentThread().setContextClassLoader(cls.getClassLoader());

            final JAXBContext jc = JAXBContext.newInstance(cls);
            final Unmarshaller unmarshaller = jc.createUnmarshaller();

            final StreamSource sr = new StreamSource(new StringReader(xml));
            final JAXBElement<?> element = unmarshaller.unmarshal(sr, cls);
            return cls.cast(element.getValue());
        } catch (final JAXBException e) {
            e.printStackTrace();
        } finally {
            Thread.currentThread().setContextClassLoader(cl);
        }
    }
    return null;
}

/** {@inheritDoc} */
@Override
public void setParameterValues(final Properties parameters) {
    final String clsName = (String) parameters.get("ClassType");
    try {
        this.cls = Thread.currentThread().getContextClassLoader().loadClass(clsName);
    } catch (final ClassNotFoundException e) {
        e.printStackTrace();
    }
}

残念ながら、マーシャリングは失敗するだけで、その理由はわかりません。

public static Document convertToXML(final Object pojo, final Class<?> type) throws SystemException {
    Document ret = null;
    final ClassLoader cl = Thread.currentThread().getContextClassLoader();
    try {
        Thread.currentThread().setContextClassLoader(type.getClassLoader());
        final JAXBContext jc = JAXBContext.newInstance(type);
        final Marshaller marshaller = jc.createMarshaller();
        final DocumentResult dr = new DocumentResult();

        marshaller.marshal(pojo, dr);

        final Document document = dr.getDocument();
        ret = document;
    } catch (final JAXBException e) {
        e.printStackTrace();
    } finally {
        Thread.currentThread().setContextClassLoader(cl);
    }
    return ret;
}

ClassLoader が設定されているかどうかは関係ありません。次の例外で常に失敗します。

Caused by: com.sun.istack.internal.SAXException2: unable to marshal type 
"packagingdetails.PackagingDetails" as an element because it is missing an 
@XmlRootElement annotation

理由は次のいずれかであると私は信じています: 1. 注釈はプロキシによって表されているため、解決できません 2. ClassLoader が問題を引き起こしています...

1.について:私はそれに気付きました(私はそれを使用してXmlRootElementの名前を取得してJAXBElementを作成しようとしましたが、これは実行可能ではないようです...;私のJAXBTypeは汎用のままにする必要があります)

final Annotation[] annotations = type.getAnnotations();
XmlRootElement xmlRootElement = null;
for (final Annotation a : annotations) {
    if (XmlRootElement.class.isAssignableFrom(a.annotationType())) {
        xmlRootElement = (XmlRootElement) a;
        break;
    }
}

いつも失敗…

アイデアはありますか?

ありがとうマティアス

4

1 に答える 1

0

javax.xml.bindパッケージまたは JAXB パブリック API バンドルをファイルにインポートしていることを確認する必要がありMETA-INF/MANIFEST.MFます。

OSGi の例 (JAXB (JSR-222) プロバイダーとして使用される MOXy)

于 2013-02-26T11:09:36.040 に答える