[ http://issues.apache.org/jira/browse/AXISCPP-940?page=comments#action_12367637 ]
Adrian Dick commented on AXISCPP-940: ------------------------------------- The code snippet you provide from the wrapper was to be consistent with the client stub code. The reason for this code is to overcome a problem experienced by a number of users in Windows, where certain combinations of the runtime library flag can prevent the user application from deleting data created within the engine. Therefore, the generated code creates a copy in the user application heap, and make the call back (Axis::AxisDelete) for the axis engine to delete the storage it previously allocated. However, due to some recent changes I have made (AXISCPP-935) the service DLL must be built with the correct runtime library flag (/MD), which makes the above irrelevant. That said, this could potentially be overcome by introducing an Axis::AxisCreate method - but if we were to go in that direction it would be a good time to consider your suggestion of some form of auto pointer. As for who should be delete what and when. I think there a pros and cons which ever route we take. The current situation is: - Input parameters must be deleted by the service impl. - Output parameter will be deleted by the axis engine (or generated code) Your suggestion would be nice and symmetric: - Input and output parameters will be deleted by the axis engine (or generated code) However, service writers will need to take care that any input data is copied in a manner which won't be affected by the subsequent delete. For example, most of the existing testcases simply return the input, with your proposal they would need to return a deep copy of the input. > WSDL2Ws generated wrapper has memory leak in INPUT parameters > ------------------------------------------------------------- > > Key: AXISCPP-940 > URL: http://issues.apache.org/jira/browse/AXISCPP-940 > Project: Axis-C++ > Type: Bug > Components: WSDL processing - Doc > Versions: 1.6 Final > Environment: Platform independent > java -fullversion "1.5.0_06-b05" using axisjava 1.3. > Found in SVN revision 380281 (Feb 23 2006) > Reporter: Emanuel Norrbin > > I generate server side stubs for C++ with this command: > java -cp "%AXIS_CPP_CLASSPATH%" org.apache.axis.wsdl.wsdl2ws.WSDL2Ws -o. > -lc++ -sserver <wsdl-file> > and the generated "Wrapper" class has the following code snippet: > xsd__string v0 = NULL; > xsd__string value0 = pIWSDZ->getElementAsString("in0",0); > if ( value0 ) > { > v0 = new char[ strlen( value0) + 1 ]; > strcpy( v0, value0); > Axis::AxisDelete( (void *) value0, XSD_STRING ); > } > The string pointed to in v0 is never deleted. Is the client implementation > code supposed to do this? That is a hassle and very error prone, it is better > if the implementater does not have to worry about deallocating memory that > was allocated by axis or by axis generated code. And why is a copy made in > the first place when value0 could have been used directly? > A fix would be to include a call to > Axis::AxisDelete( v0, XSD_STRING ); > before the call to pIWSSZ->addOutputCmplxParam. > this, however is not exception safe. A better approach would be to use a > smart pointer or similar. Unfortunately std::auto_ptr can not be used because > it does not support delete[]. > You could consider introducing a class that looks something like this: > class AutoAxisDelete { > public: > AutoAxisDelete(void* pValue, XSDTYPE type) : m_pValue(pValue), > m_type(type) {} > ~AutoAxisDelete(void) { > if ( m_pValue ) { > Axis::AxisDelete(m_pValue, m_type); > m_pValue = 0; > } > } > private: > void* m_pValue; > XSDTYPE m_type; > }; > and then define a variable that "owns" that memory until it goes out of scope: > AutoAxisDelete adopt_v0(v0, XSD_STRING); > Then that memory will be deleted in the end no matter how the method returns. > Please consider fixing this issue or explain what a web service implementer > is supposed to do... > /Thanks for all your efforts! > Emanuel > To reproduce this issue you can use this wsdl file: > <?xml version="1.0" encoding="UTF-8"?> > <wsdl:definitions > targetNamespace="urn:org.jitterbit.integration.server.implementation.webservice.interchange.db.DatabaseInfoProvider" > xmlns:apachesoap="http://xml.apache.org/xml-soap" > xmlns:impl="urn:org.jitterbit.integration.server.implementation.webservice.interchange.db.DatabaseInfoProvider" > > xmlns:intf="urn:org.jitterbit.integration.server.implementation.webservice.interchange.db.DatabaseInfoProvider" > xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" > xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" > xmlns:xsd="http://www.w3.org/2001/XMLSchema"> > <!--WSDL created by Apache Axis version: 1.3 > Built on Oct 05, 2005 (05:23:37 EDT)--> > <wsdl:types> > <schema elementFormDefault="qualified" > targetNamespace="urn:org.jitterbit.integration.server.implementation.webservice.interchange.db.DatabaseInfoProvider" > xmlns="http://www.w3.org/2001/XMLSchema"> > <element name="getDatabaseObjects"> > <complexType> > <sequence> > <element name="user" type="xsd:string"/> > <element name="pwd" type="xsd:string"/> > <element name="connect" type="xsd:string"/> > <element name="sourceGuid" type="xsd:string"/> > <element name="targetGuid" type="xsd:string"/> > <element maxOccurs="unbounded" name="objTypes" type="xsd:string"/> > <element name="searchString" type="xsd:string"/> > </sequence> > </complexType> > </element> > <element name="getDatabaseObjectsResponse"> > <complexType> > <sequence> > <element name="getDatabaseObjectsReturn" type="impl:WsDatabaseInfo"/> > </sequence> > </complexType> > </element> > <complexType name="WsDatabaseColumn"> > <sequence> > <element name="name" nillable="true" type="xsd:string"/> > <element name="type" nillable="true" type="xsd:string"/> > <element name="defaultValue" nillable="true" type="xsd:string"/> > <element name="isPrimaryKey" nillable="true" type="xsd:boolean"/> > <element name="isNullable" nillable="true" type="xsd:boolean"/> > </sequence> > </complexType> > <complexType name="ArrayOfWsDatabaseColumn"> > <sequence> > <element maxOccurs="unbounded" minOccurs="0" name="item" > type="impl:WsDatabaseColumn"/> > </sequence> > </complexType> > <complexType name="WsDatabaseObject"> > <sequence> > <element name="sObjectType" nillable="true" type="xsd:string"/> > <element name="sObjectName" nillable="true" type="xsd:string"/> > <element name="Columns" nillable="true" > type="impl:ArrayOfWsDatabaseColumn"/> > </sequence> > </complexType> > <complexType name="ArrayOfWsDatabaseObject"> > <sequence> > <element maxOccurs="unbounded" minOccurs="0" name="item" > type="impl:WsDatabaseObject"/> > </sequence> > </complexType> > <complexType name="WsDatabaseInfo"> > <sequence> > <element name="dbInfo" nillable="true" > type="impl:ArrayOfWsDatabaseObject"/> > </sequence> > </complexType> > <element name="getTableInfo"> > <complexType> > <sequence> > <element name="user" type="xsd:string"/> > <element name="pwd" type="xsd:string"/> > <element name="connect" type="xsd:string"/> > <element name="sourceGuid" type="xsd:string"/> > <element name="targetGuid" type="xsd:string"/> > <element maxOccurs="unbounded" name="tableNames" type="xsd:string"/> > </sequence> > </complexType> > </element> > <element name="getTableInfoResponse"> > <complexType> > <sequence> > <element name="getTableInfoReturn" type="impl:WsDatabaseInfo"/> > </sequence> > </complexType> > </element> > <element name="getDrivers"> > <complexType> > <sequence> > <element name="in0" type="xsd:string"/> > <element name="in1" type="xsd:string"/> > </sequence> > </complexType> > </element> > <element name="getDriversResponse"> > <complexType> > <sequence> > <element name="getDriversReturn" type="impl:WsDatabaseDriverInfo"/> > </sequence> > </complexType> > </element> > <complexType name="ArrayOf_xsd_string"> > <sequence> > <element maxOccurs="unbounded" minOccurs="0" name="item" > type="xsd:string"/> > </sequence> > </complexType> > <complexType name="WsDatabaseDriverInfo"> > <sequence> > <element name="names" nillable="true" type="impl:ArrayOf_xsd_string"/> > <element name="quoteBegin" nillable="true" > type="impl:ArrayOf_xsd_string"/> > <element name="quoteEnd" nillable="true" type="impl:ArrayOf_xsd_string"/> > </sequence> > </complexType> > </schema> > </wsdl:types> > <wsdl:message name="getTableInfoResponse"> > <wsdl:part element="impl:getTableInfoResponse" name="parameters"/> > </wsdl:message> > <wsdl:message name="getTableInfoRequest"> > <wsdl:part element="impl:getTableInfo" name="parameters"/> > </wsdl:message> > <wsdl:message name="getDatabaseObjectsResponse"> > <wsdl:part element="impl:getDatabaseObjectsResponse" name="parameters"/> > </wsdl:message> > <wsdl:message name="getDatabaseObjectsRequest"> > <wsdl:part element="impl:getDatabaseObjects" name="parameters"/> > </wsdl:message> > <wsdl:message name="getDriversRequest"> > <wsdl:part element="impl:getDrivers" name="parameters"/> > </wsdl:message> > <wsdl:message name="getDriversResponse"> > <wsdl:part element="impl:getDriversResponse" name="parameters"/> > </wsdl:message> > <wsdl:portType name="DatabaseInfoProvider"> > <wsdl:operation name="getDatabaseObjects"> > <wsdl:input message="impl:getDatabaseObjectsRequest" > name="getDatabaseObjectsRequest"/> > <wsdl:output message="impl:getDatabaseObjectsResponse" > name="getDatabaseObjectsResponse"/> > </wsdl:operation> > <wsdl:operation name="getTableInfo"> > <wsdl:input message="impl:getTableInfoRequest" > name="getTableInfoRequest"/> > <wsdl:output message="impl:getTableInfoResponse" > name="getTableInfoResponse"/> > </wsdl:operation> > <wsdl:operation name="getDrivers"> > <wsdl:input message="impl:getDriversRequest" > name="getDriversRequest"/> > <wsdl:output message="impl:getDriversResponse" > name="getDriversResponse"/> > </wsdl:operation> > </wsdl:portType> > <wsdl:binding name="konga_database_infoproviderSoapBinding" > type="impl:DatabaseInfoProvider"> > <wsdlsoap:binding style="document" > transport="http://schemas.xmlsoap.org/soap/http"/> > <wsdl:operation name="getDatabaseObjects"> > <wsdlsoap:operation > soapAction="konga_database_infoprovider#getDatabaseObjects"/> > <wsdl:input name="getDatabaseObjectsRequest"> > <wsdlsoap:body use="literal"/> > </wsdl:input> > <wsdl:output name="getDatabaseObjectsResponse"> > <wsdlsoap:body use="literal"/> > </wsdl:output> > </wsdl:operation> > <wsdl:operation name="getTableInfo"> > <wsdlsoap:operation > soapAction="konga_database_infoprovider#getTableInfo"/> > <wsdl:input name="getTableInfoRequest"> > <wsdlsoap:body use="literal"/> > </wsdl:input> > <wsdl:output name="getTableInfoResponse"> > <wsdlsoap:body use="literal"/> > </wsdl:output> > </wsdl:operation> > <wsdl:operation name="getDrivers"> > <wsdlsoap:operation > soapAction="konga_database_infoprovider#getDrivers"/> > <wsdl:input name="getDriversRequest"> > <wsdlsoap:body use="literal"/> > </wsdl:input> > <wsdl:output name="getDriversResponse"> > <wsdlsoap:body use="literal"/> > </wsdl:output> > </wsdl:operation> > </wsdl:binding> > <wsdl:service name="DatabaseInfoProviderService"> > <wsdl:port binding="impl:konga_database_infoproviderSoapBinding" > name="konga_database_infoprovider"> > <wsdlsoap:address > location="http://localhost/axis/konga_database_infoprovider"/> > </wsdl:port> > </wsdl:service> > </wsdl:definitions> -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/jira/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira
