History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: XFIRE-406
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Critical Critical
Assignee: Dan Diephouse
Reporter: Stefan Freyr Stefansson
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
XFire

XFire attempts to instantiate abstract classes when parsing a response

Created: 12/May/06 12:17 PM   Updated: 13/Jul/06 02:49 PM
Component/s: None
Affects Version/s: 1.1
Fix Version/s: 1.2-RC

Time Tracking:
Not Specified

Environment: N/A


 Description  « Hide
I have the following complex types in a WSDL that I'm using to generate classes from with the wsgen Ant task.

First the abstract base type:

<s:complexType name="RootEntityType" abstract="true">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="UserDefinedName" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="Description" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="ObjectID" type="s:string" />
        </s:sequence>
      </s:complexType>

Then the abstract sub type:

<s:complexType name="PartyType" abstract="true">
        <s:complexContent mixed="false">
          <s:extension base="s2:RootEntityType">
            <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="PartyId" type="s2:PartyId" />
              <s:element minOccurs="0" maxOccurs="1" name="IndividualValidFor" type="s2:IndividualValidFor" />
              <s:element minOccurs="0" maxOccurs="1" name="LanguageAbilities" type="s2:LanguageAbilities" />
              <s:element minOccurs="0" maxOccurs="1" name="PartyRoles" type="s2:PartyRoles" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>

And finally the concrete sub-type:

<s:complexType name="IndividualType">
        <s:complexContent mixed="false">
          <s:extension base="s2:PartyType">
            <s:sequence>
              <s:element minOccurs="0" maxOccurs="1" name="individualGender" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" name="individualPlaceOfBirth" type="s:string" />
              <s:element minOccurs="0" maxOccurs="1" name="individualNationality" type="s:string" />
              <s:element minOccurs="0" maxOccurs="1" name="individualMaritalStatus" type="s:int" />
              <s:element minOccurs="0" maxOccurs="1" name="skillSetOfIndividual" type="s2:skillSetOfIndividual" />
              <s:element minOccurs="0" maxOccurs="1" name="disabilitiesOfIndividual" type="s2:disabilitiesOfIndividual" />
              <s:element minOccurs="0" maxOccurs="1" name="IndividualINamedUsing" type="s2:IndividualNameType" />
              <s:element minOccurs="0" maxOccurs="1" name="IndividualIdentifiedBy" type="s2:IndividualIdentificationType" />
            </s:sequence>
          </s:extension>
        </s:complexContent>
      </s:complexType>

Then I have an operation defined that uses the abstract type (PartyType) as a part of its return value:

<s:complexType name="GetPartyByPartyIDResponse">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="Party" type="s2:PartyType" />
        </s:sequence>
      </s:complexType>

But in reality the webservice actually returns the IndividualType (which makes sense since PartyType is abstract).

When I call this web service using the generated classes from XFire's genws task I get the following error:

.. org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: Could not unmarshall type.
org.codehaus.xfire.fault.XFireFault: Could not unmarshall type.
	at org.codehaus.xfire.jaxb2.JaxbType.readObject(JaxbType.java:58)
	at org.codehaus.xfire.aegis.AegisBindingProvider.readParameter(AegisBindingProvider.java:91)
	at org.codehaus.xfire.service.binding.AbstractBinding.read(AbstractBinding.java:208)
	at org.codehaus.xfire.service.binding.DocumentBinding.readMessage(DocumentBinding.java:32)
	at org.codehaus.xfire.soap.handler.SoapBodyHandler.invoke(SoapBodyHandler.java:42)
	at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:98)
	at org.codehaus.xfire.client.Client.onReceive(Client.java:448)
	at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:174)
	at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:66)
	at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
	at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:98)
	at org.codehaus.xfire.client.Client.invoke(Client.java:359)
	at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
	at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
	at $Proxy12.GetPartyByPartyID(Unknown Source)
	at ProductTest.main(ProductWsTest.java:52)
	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:585)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[javax.xml.bind.UnmarshalException: Unable to create an instance of com.company.schemas.sid.tmf.commonbusinessentities._2005_10.PartyType
 - with linked exception:
[java.lang.InstantiationException]]
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:395)
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:334)
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:311)
	at org.codehaus.xfire.jaxb2.JaxbType.readObject(JaxbType.java:48)
	... 20 more
Caused by: javax.xml.bind.UnmarshalException: Unable to create an instance of com.company.schemas.sid.tmf.commonbusinessentities._2005_10.PartyType
 - with linked exception:
[java.lang.InstantiationException]
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:523)
	at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:199)
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:490)
	at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:145)
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:367)
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:345)
	at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:35)
	at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:189)
	at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:123)
	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:332)
	... 22 more
12.5.2006 14:06:57 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: I/O exception (java.net.ConnectException) caught when processing request: Connection refused
12.5.2006 14:06:57 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: Retrying request
12.5.2006 14:06:57 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: I/O exception (java.net.ConnectException) caught when processing request: Connection refused
12.5.2006 14:06:57 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: Retrying request
12.5.2006 14:06:57 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: I/O exception (java.net.ConnectException) caught when processing request: Connection refused
12.5.2006 14:06:57 org.apache.commons.httpclient.HttpMethodDirector executeWithRetry
INFO: Retrying request
org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: Couldn't send message.
org.codehaus.xfire.fault.XFireFault: Couldn't send message.
	at org.codehaus.xfire.fault.XFireFault.createFault(XFireFault.java:89)
	at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:30)
	at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:98)
	at org.codehaus.xfire.client.Client.invoke(Client.java:359)
	at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
	at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
	at $Proxy15.GetVODOffers(Unknown Source)
	at ProductWsTest.main(ProductWsTest.java:101)
	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:585)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Caused by: org.codehaus.xfire.XFireException: Couldn't send message.
	at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:179)
	at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:66)
	at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
	... 11 more
Caused by: java.net.ConnectException: Connection refused
	at java.net.PlainSocketImpl.socketConnect(Native Method)
	at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
	at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
	at java.net.Socket.connect(Socket.java:507)
	at java.net.Socket.connect(Socket.java:457)
	at java.net.Socket.<init>(Socket.java:365)
	at java.net.Socket.<init>(Socket.java:238)
	at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:79)
	at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:121)
	at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:706)
	at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:386)
	at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)
	at org.codehaus.xfire.transport.http.CommonsHttpMessageSender.send(CommonsHttpMessageSender.java:166)
	at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:168)
	... 13 more

Process finished with exit code 0

It seems that this error is caused by XFire trying to instantiate the abstract PartyType class when parsing the response but that is of course impossible since that class is abstract. Instead it should instantiate its subclass, IndividualType.



 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Dan Diephouse - 15/May/06 04:45 PM
I have this now fixed. I will get a snapshot deployed as soon as the codehaus servers are back online. This may be as late as Wednesday.

Stefan Freyr Stefansson - 29/Jun/06 09:07 AM
This is still an issue in XFire 1.1.2

org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: Could not unmarshall type.
org.codehaus.xfire.fault.XFireFault: Could not unmarshall type.
at org.codehaus.xfire.jaxb2.JaxbType.readObject(JaxbType.java:76)
at org.codehaus.xfire.aegis.AegisBindingProvider.readParameter(AegisBindingProvider.java:94)
at org.codehaus.xfire.service.binding.AbstractBinding.read(AbstractBinding.java:208)
at org.codehaus.xfire.service.binding.DocumentBinding.readMessage(DocumentBinding.java:32)
at org.codehaus.xfire.soap.handler.SoapBodyHandler.invoke(SoapBodyHandler.java:42)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:110)
at org.codehaus.xfire.client.Client.onReceive(Client.java:382)
at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:120)
at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:44)
at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:110)
at org.codehaus.xfire.client.Invocation.invoke(Invocation.java:75)
at org.codehaus.xfire.client.Client.invoke(Client.java:335)
at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
at $Proxy11.GetPartyByPartyID(Unknown Source)
at IpTvWsTest.main(IpTvWsTest.java:73)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
e.getClass().getName() = org.codehaus.xfire.XFireRuntimeException
e.getClass().getName() = org.codehaus.xfire.fault.XFireFault
e.getClass().getName() = javax.xml.bind.UnmarshalException
found jaxbexception
e.getClass().getName() = org.xml.sax.SAXParseException
e.getClass().getName() = org.xml.sax.SAXParseException
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Caused by: javax.xml.bind.UnmarshalException

  • with linked exception:
    [javax.xml.bind.UnmarshalException: Unable to create an instance of com.industria.schemas.sid.tmf.commonbusinessentities._2005_10.PartyType
  • with linked exception:
    [java.lang.InstantiationException]]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:395)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:334)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:311)
    at org.codehaus.xfire.jaxb2.JaxbType.readObject(JaxbType.java:63)
    ... 21 more
    Caused by: javax.xml.bind.UnmarshalException: Unable to create an instance of com.industria.schemas.sid.tmf.commonbusinessentities._2005_10.PartyType
  • with linked exception:
    [java.lang.InstantiationException]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:523)
    at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:199)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:490)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:145)
    at com.sun.xml.bind.v2.runtime.unmarshaller.XsiTypeLoader.startElement(XsiTypeLoader.java:36)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:367)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:345)
    at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:35)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:189)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:123)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:332)
    ... 23 more

Process finished with exit code 0


Stefan Freyr Stefansson - 30/Jun/06 06:51 AM
For the record, there is a "workaround". Dan already pointed this out to me but I had forgotten about it.

The workaround is to manually specify all the packages that are generated from the WSDL in your client creation code:

        FooClient foo = new FooClient();
        FooSoap fooSoap = foo.getFooSoap("http://123.123.123.123/services/FooService");

        Client client = ((XFireProxy) Proxy.getInvocationHandler(fooSoap)).getClient();

        List<String> pckgs = new ArrayList<String>();
        pckgs.add("com.foo.bar");
        pckgs.add("com.foo.smu");
        pckgs.add("com.foo.baz");
        pckgs.add("com.foo.fluffbunny");
        pckgs.add("com.external.company");
        client.setProperty(JaxbType.SEARCH_PACKAGES, pckgs);

This should prevent the client from trying to instantiate an abstract class for some reason.

I still don't consider this issue resolved... I would like to know whether it's possible to put this logic somehow into the generated code to relieve the developer of having to synchronize this manually. This is a potential source of very vague bugs unless the process is somehow automated.


Dan Diephouse - 30/Jun/06 09:34 AM
I think this is definitely possible. We can query jaxb to see the packages created I believe (although that may be wrong).

Dan Diephouse - 13/Jul/06 02:49 PM
So it turns out its not possible to figure out how the sub classes automagically, so I think we're stuck with the current solution. If anyone has any better ideas please let me know. In the mean time I've documented how this works here:

http://xfire.codehaus.org/JAXB+2.0