2011-09-14 38 views
5

Tôi đang chạy vào lỗi Unmarshalling JAXB như dưới đây. Các foo.bar.Base là một lớp trừu tượng, với một chú thích @XmlSeeAlso, trong đó liệt kê foo.bar.SubBase (là một lớp con cụ thể của foo.bar.Base)InstantiationException trong JAXB Unmarshalling (lớp cơ sở trừu tượng, với lớp con bê tông @XmlSeeAlso)

Cả hai lớp trên đều có thể truy cập tĩnh từ một lớp học chính/entry: com.example.Request

các JAXBContext là tạo ra bằng cách sử dụng gói chuỗi biến viz:

JAXBContext.newInstance("com.example",...); 

các tạo JAXBContext trên liệt kê một cách chính xác tất cả ba lớp: com.example.Request, foo.bar.Base and foo.bar.SubBase as "classes known to this JAXBContext"

Nhưng nó không thành công trong thời gian chạy trong cuộc gọi bất thường dưới đây .. Tôi không thể tìm ra những gì là sai ở đây.

unmarshaller.unmarshal(<some-DOM-Element-Instance>, com.example.Request.class); 

Mọi con trỏ sẽ được đánh giá cao! Cảm ơn!

Các stacktrace là:

Caused by: javax.xml.bind.UnmarshalException: Unable to create an instance of foo.bar.Base - with linked exception: [java.lang.InstantiationException] 

    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:642) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:254) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:609) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:181) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.XsiTypeLoader.startElement(XsiTypeLoader.java:76) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.ProxyLoader.startElement(ProxyLoader.java:55) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:481) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:459) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:71) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:148) 

    at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:239) 

    at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:276) 

    at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:245) 

    at com.sun.xml.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:122) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:314) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:293) 

Caused by: java.lang.InstantiationException 

    at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:30) 

    at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 

    at com.sun.xml.bind.v2.ClassFactory.create0(ClassFactory.java:123) 

    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.createInstance(ClassBeanInfoImpl.java:261) 

    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:603) 

    ... 69 more 

EDIT @Blaise và @Ross

Thank you very much Blaise và Ross cho con trỏ của bạn. Tôi nghĩ tôi nên bao gồm lược đồ đang được giải quyết, ở đây. Giản đồ có liên quan như sau:

<xs:complexType name="Request"> 
        <xs:sequence> 
         <xs:element name="selectedBase" form="unqualified" nillable="true" type="xs:anyType" minOccurs="0"/> 
         <xs:element name="selectedSubBase" form="unqualified" nillable="true" type="ns1:SubBase" minOccurs="0"/> 
        </xs:sequence> 
       </xs:complexType> 


<xs:complexType name="Base"> 
       <xs:sequence> 
        <xs:element name="ID" form="unqualified" nillable="true" type="xs:string" minOccurs="0"/> 
       </xs:sequence> 
      </xs:complexType> 
      <xs:complexType name="SubBase"> 
       <xs:complexContent> 
        <xs:extension base="ns1:Base"> 
         <xs:sequence> 
          <xs:element name="subBaseElement" form="unqualified" nillable="true" type="xs:anyType" minOccurs="0"/> 
         </xs:sequence> 
        </xs:extension> 
       </xs:complexContent> 
      </xs:complexType> 

Vì vậy, các giản đồ không có định nghĩa nhóm thay thế (vì vậy tôi đoán @XmlElementRef không áp dụng ở đây, hoặc sẽ nó vẫn hoạt động?), Nhưng đang sử dụng phần mở rộng. Các tải trọng sẽ là:

<ns:Request> 
     <selectedBase>123</selectedBase> 
     <selectedSubBase> 
      <ID>321</ID> 
      <subBaseElement>123</subBaseElement> 
     </selectedSubBase> 
     </ns:Request> 

Vì vậy, yếu tố trong occuring tải trọng là <selectedSubBase> và không <selectedBase xsi:type="ns:SubBase"/>

Vì vậy mà chiến lược sẽ được áp dụng ở đây?

Trả lời

8

Chú thích @XmlSeeAlso được sử dụng làm cơ chế thuận tiện để thông báo cho JAXB của bạn rằng siêu dữ liệu cũng nên được tạo cho các lớp được tham chiếu. Trong khi nó thường được sử dụng để chỉ định các lớp con, nó không phải là một cơ chế để cấu hình các mối quan hệ thừa kế.

Vì JAXB đang cố gắng khởi tạo một thể hiện của lớp siêu trừu tượng (foo.bar.Base), có vẻ như thông điệp XML của bạn không chứa đủ thông tin để chỉ định đúng loại phụ sẽ không được sửa.

này có thể được thực hiện với sự xsi:type thuộc tính:

Bạn cũng có thể sử dụng các nhóm thay thế (@XmlElementRef), nơi tên phần tử được sử dụng để xác định phù hợp sub-type:

triển khai JAXB (như EclipseLink JAXB (MOXy)), cũng chứa phần mở rộng để xử lý thừa kế:

Và nếu bạn muốn bỏ qua mối quan hệ thừa kế hoàn toàn có thể sử dụng @XmlTransient chú thích:

+0

Hãy cẩn thận, thêm nguyên nhân @XmlElementRef http://stackoverflow.com/questions/790118/jaxb-types-problem – user293756

3

Bạn cần sử dụng XmlElementRef trên trường có chứa tham chiếu đến Base, để cho JAXB biết rằng nó nên xem xét các lớp con. JAXB rõ ràng đang cố gắng để khởi tạo lớp cơ sở của bạn (mà nó không thể làm, tất nhiên).

Have a look at XmlElementRef's docs.

-1

thử @XmlSeeAlso

@XmlSeeAlso({ExchangeFormat.class}) public abstract class MapperJsonXml <T> 


@XmlRootElement(name="ExchangeFormat") public class ExchangeFormat extends MapperJsonXml<ExchangeFormat> 

nó hoạt động

Các vấn đề liên quan