j'attendre le test suivant pour travailler avec JAXB RI 2.2.1.1 de Sun, mais il échoue avec un NullPointerException dans la construction du JAXBContext:champs de triage JAXB dont le type est un paramètre de type générique
public class GenericFieldMarshallTest {
public static class CustomType {
}
public static class CustomTypeAdapter extends XmlAdapter<String, CustomType> {
@Override
public String marshal(CustomType v) throws Exception {
return "CustomType";
}
@Override
public CustomType unmarshal(String v) throws Exception {
return new CustomType();
}
}
@XmlJavaTypeAdapter(type = CustomType.class, value = CustomTypeAdapter.class)
public static class RootElement<ValueType> {
@XmlValue public ValueType value;
}
@XmlRootElement(name = "root")
public static class CustomRootElement extends RootElement<CustomType> {
public CustomRootElement() {
value = new CustomType();
}
}
@Test
public void test() throws Exception {
JAXBContext context = JAXBContext.newInstance(CustomRootElement.class,
CustomType.class, RootElement.class);
StringWriter w = new StringWriter();
context.createMarshaller().marshal(new CustomRootElement(), w);
assertThat(w.toString(), equalTo("<root>CustomType</root>"));
}
}
L'exception je reçois est:
java.lang.NullPointerException
at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor.get(TransducedAccessor.java:165)
at com.sun.xml.bind.v2.runtime.property.ValueProperty.<init>(ValueProperty.java:77)
at com.sun.xml.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:106)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:179)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:515)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:166)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:515)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:330)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1140)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:202)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:363)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
la cause semble être que JAXB ne sait pas comment le maréchal type déclaré de mon champ (? que je pense est effacée à l'objet lors de l'exécution), même si lors de l'exécution, je ne jamais définissez le champ sur les types connus de JAXB. Comment puis-je marshaler un champ de type générique? (Le remplacement de @XmlValue par @XmlAttribute ne corrige pas l'exception, pas plus que le changement du type déclaré du champ en objet, bien que tout fonctionne bien si le champ est déclaré en tant que chaîne, sauf que la chaîne n'est pas assignable Le placement de @XmlJavaTypeAdapter ne fait aucune différence: dans mon code actuel, il est défini au niveau du package dans package-info.java.)
Vous avez raison à propos de l'ordre des types de XmlAdapter, je voulais que ce soit l'inverse. C'était une erreur de transcription quand j'ai écrit le faux exemple pour ma question. J'ai corrigé ceci dans ma question. Toutefois, aucune de vos autres suggestions ne génère de code de travail pour moi. Le placement de l'annotation @XmlJavaTypeAdapter est arbitraire; dans mon code actuel, il est au niveau du paquet dans package-info.class. J'ai essayé d'ajouter les autres classes impliquées dans l'appel JAXBContext.newInstance() au cas où JAXB ne les trouve pas lui-même, mais cela ne fait pas non plus de différence avec le problème. – DanC
Si vous avez une version de travail du test dans ma question, pouvez-vous la mettre dans un pastebin et la lier ici, afin que nous puissions voir ce que vous avez changé pour que cela fonctionne? – DanC
J'ai édité le post. Vous n'avez pas besoin d'apporter des dépendances externes comme pastebin dans ceci. J'espère que cela fonctionne pour vous parce que j'ai utilisé JAXB comme il est distribué avec le JDK. – musiKk