2013-02-15 10 views
5

Sto tentando di annotare una classe java per creare uno schema JAXB con un elemento che ha un attributo di valore. Il codice è qui sotto:Attributo JAXB con tipo di oggetto che genera un'eccezione di puntatore nullo?

@XmlAttribute(name="value") 
    public Object getSettingValue() { 
     return this.settingValue; 
    } 

    public void setSettingValue(final Object settingValue) { 
     this.settingValue = settingValue; 
    } 

Quando provo a generare lo schema (utilizzando l'implementazione non Moxy di Eclipse), ottengo questa eccezione puntatore nullo:

Exception in thread "main" java.lang.NullPointerException 
    at com.sun.xml.internal.bind.v2.runtime.reflect.TransducedAccessor.get(TransducedAccessor.java:154) 
    at com.sun.xml.internal.bind.v2.runtime.property.AttributeProperty.<init>(AttributeProperty.java:56) 
    at com.sun.xml.internal.bind.v2.runtime.property.PropertyFactory.create(PropertyFactory.java:93) 
    at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.<init>(ClassBeanInfoImpl.java:145) 
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getOrCreate(JAXBContextImpl.java:479) 
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:305) 
    at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1100) 
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:143) 
    at com.sun.xml.internal.bind.v2.ContextFactory.createContext(ContextFactory.java:110) 
    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:376) 
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574) 
    at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522) 
    at org.eclipse.jpt.jaxb.core.schemagen.Main.buildJaxbContext(Main.java:95) 
    at org.eclipse.jpt.jaxb.core.schemagen.Main.generate(Main.java:76) 
    at org.eclipse.jpt.jaxb.core.schemagen.Main.execute(Main.java:62) 
    at org.eclipse.jpt.jaxb.core.schemagen.Main.main(Main.java:47) 

quando ho fatto di questo un @XmlElement invece di un attributo, lo schema è stato generato senza problemi, quindi deve avere a che fare con questo. Qualche idea?

+0

La proprietà deve essere di tipo 'Object' oppure è possibile modificarla come' String'? –

+0

@BlaiseDoughan Passeremo in oggetti di vario tipo: Integer, Boolean o String (e forse altri tipi mentre estendiamo la nostra applicazione). Non so se potremmo cambiarlo in String. Potremmo eventualmente creare un setter separato che prenderebbe una stringa. – chama

+1

@BlaiseDoughan Sono stato in grado di cambiarlo in stringa e quindi trasmetterlo tramite il mio metodo reale. Grazie! – chama

risposta

3

Il NullPointerException che state vedendo sembra essere dovuto ad un bug nell'implementazione di riferimento JAXB. Puoi inserire un bug usando il seguente link.

Un'eccezione simile non si verifica quando si utilizza EclipseLink JAXB (MOXy) come provider JAXB.

Soluzione

Si potrebbe modificare la proprietà di essere di tipo String invece. Una proprietà di tipo Object non eseguirà comunque il round trip in quanto, diversamente dagli elementi, gli attributi non hanno alcun meccanismo per includere le informazioni di digitazione.


Quando ho fatto di questo un @XmlElement invece di un attributo, lo schema è stato generato senza problemi, quindi deve avere a che fare con questo.

Java Model (Root)

oggetto è un tipo di proprietà valido quando mappata a un elemento XML.

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Root { 

    private Object settingValue; 

    public Object getSettingValue() { 
     return settingValue; 
    } 

    public void setSettingValue(final Object settingValue) { 
     this.settingValue = settingValue; 
    } 

} 

Ciò è perché l'elemento XML può contenere digitare le informazioni sotto forma di un attributo xsi:type.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root> 
    <settingValue 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     xsi:type="xs:int">123</settingValue> 
</root> 
+0

Siamo spiacenti, ma non penso che sia un bug. Gli attributi Xml non possono avere tipi complessi. Vedi la mia risposta. – Puce

+0

@Puce - 'String',' Integer', 'Date' sono tutte istanze di' Object' che non corrispondono a tipi complessi in XML e possono essere rappresentati come attributi in XML. Per lo meno è un bug che viene lanciato un NPE invece di un'eccezione migliore. –

+0

Bene, l'NPE non è bello, sono d'accordo, ma gli attributi possono avere solo tipi che si associano ai tipi built-in, ad es. String, Integer, Date o types che si associano a tipi semplici. Ma non tipi complessi. Questo perché XML/XSD consente solo tipi built-in e tipi semplici per attributi. – Puce

1

I tipi di attributo devono associarsi ai tipi di dati incorporati dello schema o ai tipi semplici dello schema.

Il tipo Oggetto non corrisponde a questi criteri.

http://www.w3schools.com/schema/el_attribute.asp

http://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlAttribute.html

+0

Quello che stai dicendo è che un XmlAttriubte può essere di qualsiasi tipo purché quel tipo possa essere mappato su Xml (usando JAXB), ma l'oggetto non può essere mappato? – chama

+0

Non l'ho provato in dettaglio ma, a quanto ho capito, puoi usare i tipi che mappano per costruire in tipi come int, booleano, BigInteger, data/ora/dataTime ecc. O un tipo con una singola proprietà, che è annotato con @XmlValue: http://fusesource.com/docs/esb/4.2/jaxws/JAXWSCustomTypeMappingSimple.html – Puce

Problemi correlati