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 <t...@e-tge.de> 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: c-user-unsubscr...@axis.apache.org
> > For additional commands, e-mail: c-user-h...@axis.apache.org
> >
> >
> 
> 
> 


/*
 * 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: c-user-unsubscr...@axis.apache.org
For additional commands, e-mail: c-user-h...@axis.apache.org

Reply via email to