On Fri, 2010-07-09 at 13:26 +0200, Akos Marton wrote:
> You had better send the corresponding code of the certain stack-trace.
> -can be interesting.
This is a bit more complicated because the code lives in multiple source
files ...
Initially I was rather thinking about "how is it supposed to work"?
Anyway, here is something like an "aggregated source code":
// My "business logic" which is a non-static C++ method of an C++
// object:
axiom_node_t * SoapSrv::invokeFunc(const axutil_env_t * env,
axiom_node_t * node)
{
if(axiom_node_get_node_type(node, env) == AXIOM_ELEMENT)
{
axiom_element_t * element = (axiom_element_t *)
axiom_node_get_data_element(node, env);
if(element != NULL)
{
axis2_char_t * op_name = axiom_element_get_localname(element,
env);
if(op_name == NULL)
{
// no server function ... log error
return NULL;
}
axiom_node_t * respNode = NULL;
DataObjectPtr req = dataObjFromAxiom(node);
DataObjectPtr resp = ... do something(op_name, req);
respNode = dataObjToAxiom(resp);
if(respNode == NULL)
{
// log error
}
return respNode;
}
}
return NULL;
}
// To call the non-static method above I have wrapped this in
// a separate static function, which is registered with the server
// skeleton:
extern "C" axiom_node_t * AXIS2_CALL soapSrvInvoke(
axis2_svc_skeleton_t * skel,
const axutil_env_t * env,
axiom_node_t * node,
axis2_msg_ctx_t * msg_ctx)
{
return SoapSrv::getInstance()->invoke(skel, env, node, msg_ctx);
}
// and (this is actually not needed anymore but should not hurt):
axiom_node_t * SoapSrv::invoke(axis2_svc_skeleton_t * svc_skeleton,
const axutil_env_t * env,
axiom_node_t * node,
axis2_msg_ctx_t * msg_ctx)
{
return SoapSrv::getInstance()->invokeFunc(env, node);
}
// The axiom to SDO conversion:
axiom_node_t * Soap::dataObjToAxiom(DataObjectPtr o)
{
if(m_ax == NULL)
{
m_ax = AxiomHelper::getHelper(getEnv());
}
axiom_document_t * doc = m_ax->toAxiomDoc(o);
axiom_node_t * ret = (doc == NULL) ? NULL :
axiom_document_get_root_element(doc, m_ax->getEnv());
return ret;
}
DataObjectPtr Soap::dataObjFromAxiom(axiom_node_t * n)
{
if(m_ax == NULL)
{
m_ax = AxiomHelper::getHelper(getEnv());
}
return m_ax->toSdo(n, m_mdg);
}
Finally, the SDO AxiomHelper is attached.
Many thx!!
tge
>
> On Fri, Jul 9, 2010 at 1:02 PM, Thomas Gentsch <[email protected]> wrote:
> >
> > Hi all,
> >
> > I encountered a problem which I'm not sure how to handle - whether it is
> > my own fault because I did something wrong?
> >
> > I have a Axis2c server, which generally works nicely. The actual service
> > deals with Tuscany SDO objects, so I transform the Axiom objects to/from
> > SDOs when processing a request (this is actually a detail which should
> > not matter as the question is more general):
> >
> > In my service, I have something like this (following the example here:
> > http://www.dimuthu.org/blog/2008/10/02/understanding-apache-axis2c-services)
> >
> >> Service logic
> >> Just create a function with the following format.
> >> axiom_node_t *axis2_echo_echo(
> >> const axutil_env_t * env,
> >> axiom_node_t * input_node) {
> >>
> >> /* Write your business logic Right Here */
> >> }
> >> Here you extract out the input parameters from the the input_node and
> >> build the return node based on your output parameters. (Note that even
> >> though this is an echo example you can’t return the same input node as
> >> the output node, instead you have to replicate the input node and
> >> return it to avoid the double freeing)
> >
> > So I create a returned axiom_node_t but eventually end up with a memory
> > leak:
> > ------------------
> > ==3461== 20,164 (40 direct, 20,124 indirect) bytes in 1 blocks are
> > definitely lost in loss record 975 of 980
> > ==3461== at 0x4025C1C: malloc (vg_replace_malloc.c:195)
> > ==3461== by 0x47C1CFC: axutil_allocator_malloc_impl (allocator.c:75)
> > ==3461== by 0x47A2E1C: axiom_stax_builder_create
> > (om_stax_builder.c:70)
> > ==3461== by 0x4712A66:
> > commonj::sdo_axiom::AxiomHelper::toAxiomDoc(commonj::sdo::RefCountingPointer<commonj::sdo::DataObject>,
> > char const*, char const*) (sdo_axiom.cpp:146)
> > ==3461== by 0x4438CB8:
> > dataObjToAxiom(commonj::sdo::RefCountingPointer<commonj::sdo::DataObject>)
> > (in /opt/bes/itm/modules/libimsoap.so)
> > ==3461== by 0x4439839: invokeFunc(axutil_env const*, axiom_node*)
> > (im_soapsrv.cpp:160)
> > ==3461== by 0x4439396: invoke(axis2_svc_skeleton*, axutil_env const*,
> > axiom_node*, axis2_msg_ctx*) (im_soapsrv.cpp:79)
> > ==3461== by 0x4C31C8D: soapSrvInvoke (im_soapsrvax.cpp:37)
> > ==3461== by 0x474B0D6:
> > axis2_raw_xml_in_out_msg_recv_invoke_business_logic_sync
> > (raw_xml_in_out_msg_recv.c:209)
> > ==3461== by 0x474A433: axis2_msg_recv_invoke_business_logic
> > (msg_recv.c:481)
> > ==3461== by 0x474AB34: axis2_msg_recv_receive_impl (msg_recv.c:403)
> > ==3461== by 0x474A4B3: axis2_msg_recv_receive (msg_recv.c:520)
> > ------------------
> >
> > Who is going to free the axiom_node_t I return? In theory this must
> > happen inside of Axis2c when serializing the data to the network, right?
> > So, there is actually nothing I can do?
> > Under which circumstances might this not be done?
> > Am I possibly doing something wrong?
> >
> >
> > Secondly, how is it supposed to work the other way around? In my
> > service, I receive an axiom node, transform it to a SDO etc.
> > Who is in charge of freeing the original axiom_node_t?
> > I don't do it in my code, so the result is another memory leak:
> >
> > -----------------------
> > ==3461== 8,737 (56 direct, 8,681 indirect) bytes in 1 blocks are
> > definitely lost in loss record 970 of 980
> > ==3461== at 0x4025C1C: malloc (vg_replace_malloc.c:195)
> > ==3461== by 0x47C1CFC: axutil_allocator_malloc_impl (allocator.c:75)
> > ==3461== by 0x47A022B: axiom_output_create (om_output.c:79)
> > ==3461== by 0x4712381:
> > commonj::sdo_axiom::AxiomHelper::toSdo(axiom_node*,
> > commonj::sdo::RefCountingPointer<commonj::sdo::DataFactory>, char
> > const*) (sdo_axiom.cpp:214)
> > ==3461== by 0x4438D9F: dataObjFromAxiom(axiom_node*)
> > (in /opt/bes/itm/modules/libimsoap.so)
> > ==3461== by 0x44397C0: invokeFunc(axutil_env const*, axiom_node*)
> > (im_soapsrv.cpp:152)
> > ==3461== by 0x4439396: invoke(axis2_svc_skeleton*, axutil_env const*,
> > axiom_node*, axis2_msg_ctx*) (im_soapsrv.cpp:79)
> > ==3461== by 0x4C31C8D: soapSrvInvoke (im_soapsrvax.cpp:37)
> > ==3461== by 0x474B0D6:
> > axis2_raw_xml_in_out_msg_recv_invoke_business_logic_sync
> > (raw_xml_in_out_msg_recv.c:209)
> > ==3461== by 0x474A433: axis2_msg_recv_invoke_business_logic
> > (msg_recv.c:481)
> > ==3461== by 0x474AB34: axis2_msg_recv_receive_impl (msg_recv.c:403)
> > ==3461== by 0x474A4B3: axis2_msg_recv_receive (msg_recv.c:520)
> > -----------------------
> >
> > Any hints are greatly appreciated!!
> >
> > Many thx + regards,
> > tge
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [email protected]
> > For additional commands, e-mail: [email protected]
> >
> >
>
>
>
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/* $Rev: 498972 $ $Date: 2007-01-23 10:06:47 +0000 (Tue, 23 Jan 2007) $ */
#if defined(WIN32) || defined (_WINDOWS)
#pragma warning(disable: 4786)
#endif
#include "sdo_axiom.h"
using namespace commonj::sdo;
using namespace std;
namespace commonj
{
namespace sdo_axiom
{
int AxiomHelper::axiswritercount = 0;
AxiomHelper* AxiomHelper::getHelper(axutil_env_t * env)
{
return new AxiomHelper(env);
}
void AxiomHelper::releaseHelper(AxiomHelper* h)
{
if (h) delete h;
}
void AxiomHelper::deleteEnv()
{
if (the_env && (! privateEnv)) axutil_env_free(the_env);
}
void AxiomHelper::createEnv()
{
the_env = axutil_env_create_all("tuscany_sdo_axiom.log",AXIS2_LOG_LEVEL_WARNING);
if (the_env == 0) return;
return;
}
AxiomHelper::AxiomHelper(axutil_env_t * env) : the_env(env), privateEnv(false)
{
if(the_env == 0)
{
privateEnv = true;
createEnv();
}
}
AxiomHelper::~AxiomHelper()
{
deleteEnv();
}
axutil_env_t* AxiomHelper::getEnv()
{
return the_env;
}
axiom_node_t* AxiomHelper::toAxiomNode(DataObjectPtr dob,
const char* targetNamespaceURI, const char* elementName)
{
axiom_document_t* doc = toAxiomDoc(dob,
targetNamespaceURI, elementName);
if (!doc)
{
return 0;
}
axiom_node_t* root_node =
axiom_document_get_root_element(doc, the_env);
if (!root_node)
{
cout << "No Root Element in the document" << endl;
return 0;
}
return root_node;
}
axiom_document_t* AxiomHelper::toAxiomDoc(DataObjectPtr dob,
const char* targetNamespaceURI, const char* elementName)
{
DataFactoryPtr df = dob->getDataFactory();
XSDHelperPtr xs = HelperProvider::getXSDHelper(df);
XMLHelperPtr xm = HelperProvider::getXMLHelper(df);
if (!the_env)
{
cout << "No Axis Environment" << endl;
return 0;
}
XMLDocumentPtr doc = xm->createDocument(
dob,
targetNamespaceURI,
elementName);
char * str = xm->save(doc);
//if (str) {
// cout << "toAxiomDoc " << str << endl;
//}
axiom_xml_reader_t * reader =
axiom_xml_reader_create_for_memory(the_env,
(void*)str,
strlen(str),
(const axis2_char_t *)"UTF-8",
AXIS2_XML_PARSER_TYPE_BUFFER);
if (!reader)
{
cout << "No Axis Reader" << endl;
return 0;
}
axiom_stax_builder_t* builder =
axiom_stax_builder_create(the_env, reader);
if (!builder)
{
cout << "No Axis Builder" << endl;
axiom_xml_reader_free(reader, the_env);
return 0;
}
axiom_document_t* document =
axiom_stax_builder_get_document(builder, the_env);
if (!document)
{
cout << "No Axis Document" << endl;
axiom_stax_builder_free(builder, the_env);
return 0;
}
axiom_node_t* root_node =
axiom_document_get_root_element(document, the_env);
if (!root_node)
{
cout << "No Root Element in the document" << endl;
axiom_stax_builder_free(builder, the_env);
return 0;
}
axiom_document_build_all(document, the_env);
return document;
}
DataObjectPtr AxiomHelper::toSdo(axiom_document_t* document,
DataFactoryPtr factory,
const char* targetNamespaceURI)
{
if (!the_env)
{
cout << "No Axis Environment" << endl;
return 0;
}
axiom_node_t* root_node =
axiom_document_get_root_element(document, the_env);
return toSdo(root_node,factory, targetNamespaceURI);
}
DataObjectPtr AxiomHelper::toSdo(axiom_node_t* root_node,
DataFactoryPtr factory,
const char* targetNamespaceURI)
{
if (!the_env)
{
cout << "No Axis Environment" << endl;
return 0;
}
XMLHelperPtr helper = HelperProvider::getXMLHelper(factory);
axiom_xml_writer_t* writer = axiom_xml_writer_create_for_memory(
the_env, NULL, AXIS2_TRUE, 0,
AXIS2_XML_PARSER_TYPE_BUFFER);
axiom_output_t* output = axiom_output_create(the_env, writer);
if (!root_node)
{
cout << "No Root Element in the document" << endl;
axiom_output_free(output, the_env);
return 0;
}
axiom_node_serialize(root_node, the_env, output);
axis2_char_t* buffer = (axis2_char_t*)axiom_xml_writer_get_xml(writer, the_env);
// cout << "toSDO: '" << buffer << "'" << endl;
XMLDocumentPtr theXMLDocument = helper->load(buffer, targetNamespaceURI);
if (theXMLDocument != 0)
{
return theXMLDocument->getRootDataObject();
}
cout << "The XML document returned from load was zero" << endl;
return 0;
}
void AxiomHelper::output(axiom_document_t* document)
{
if (!the_env)
{
cout << "No Axis Environment" << endl;
return;
}
axiom_xml_writer_t* writer = axiom_xml_writer_create_for_memory(
the_env, NULL, AXIS2_TRUE, 0,
AXIS2_XML_PARSER_TYPE_BUFFER);
axiom_output_t* output = axiom_output_create(the_env, writer);
axiom_node_t* root_node =
axiom_document_get_root_element(document, the_env);
if (!root_node)
{
cout << "No Root Element in the document" << endl;
axiom_output_free(output, the_env);
return;
}
axiom_node_serialize(root_node, the_env, output);
axis2_char_t* buffer = (axis2_char_t*)axiom_xml_writer_get_xml(writer, the_env);
printf("Output XML:n %s ", buffer);
axiom_output_free(output, the_env);
return;
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]