<div dir="ltr">    TAO VERSION: 2.2.6<br>    ACE VERSION: 6.2.6<br><br>    HOST MACHINE and OPERATING SYSTEM:<br>        Windows XP 32 bit,  winsock: ws2_32.dll version 5.1.2600.5512 <br>        problem was also reproduced with tao 2.2.1 on Windows Server 2012 R2 64bit.<br>        Source comparison shows that the problem should exist in the latest version (2.3.3) as well.<br><br><br>    COMPILER NAME AND VERSION (AND PATCHLEVEL):<br>        Microsoft visual studio 2010, service pack 1, 32 bit.<br><br>    THE $ACE_ROOT/ace/config.h FILE : <br>        #include "ace/config-win32.h"<br><br>    CONTENTS OF $ACE_ROOT/bin/MakeProjectCreator/config/default.features<br>    (used by MPC when you generate your own makefiles): <br>        (did not find such file)<br><br>    AREA/CLASS/EXAMPLE AFFECTED:<br>    FT_NAMING/NamingManager/ load balancing example<br><br>    Example fails to execute: $ACE_ROOT/TAO/orbsvcs/tests/FT_Naming/Load_Balancing (server project)<br><br><br>    DOES THE PROBLEM AFFECT:<br>        EXECUTION<br><br>The problem affects TAO ft_naming service, when it is used with load balancing (object groups) feature. <br>The problem affects tao sample (FT_Naming\load_balancing), and my custom application that uses the same service.<br><br>    SYNOPSIS:<br>Call to FT_Naming::NamingManager's add_member method fails to add member to group with exception PortableGroup::ObjectNotAdded.<br><br>    DESCRIPTION:<br>Server application that uses FT_Naming service with object groups receives exception PortableGroup::ObjectNotAdded when adding first member to object group by  call <br>to FT_Naming::NamingManager's add_member method. <br>NamingManager object (reference) was returned by orb.resolve_initial_references("NamingManager") and narrowed by FT_Naming::NamingManager::_narrow.<br>Object group was initially created with a call to create_object_group.<br><br>tao_ft_naming.exe shows the following output: <br>   TAO_FT_Naming_Manager::add_member - Issue with IOR of group or member.<br><br><br>    REPEAT BY:<br><br>0) build ft_naming load balancing sample from distribution:<br>   ace_wrappers\TAO\orbsvcs\tests\ft_naming\Load_Balancing\Load_Balancing_vc10.sln<br>1) launch tao_ft_naming <br>2) launch server.exe  (built sample server)<br>( i launched tao_ft_naming service with specified endpoint, and then provided that endpoint to server application.<br>tao_ft_naming  -ORBListenEndpoints iiop://localhost:9809 -d<br>server -ORBInitRef NameService=corbaloc:iiop:localhost:9809/NameService  -ORBInitRef NamingManager=corbaloc:iiop:localhost:9809/NamingManager <br>)<br>3) server fails to execute and  exits with error message <br>(1900|2896) EXCEPTION, Exception raised while registering servant<br>user exception, ID 'IDL:<a href="http://omg.org/PortableGroup/ObjectNotAdded:1.0">omg.org/PortableGroup/ObjectNotAdded:1.0</a>'<br><br><br>   exception occurs while calling naming manager add_member method, it is called from LB_server::register_servant.File lb_server.cpp, line 208.<br><br>   this->object_group_ =<br>        this->naming_manager_->add_member (this->object_group_.in (),<br>                                           location,<br>                                           <a href="http://basic.in">basic.in</a> ());<br><br><br><br>    SAMPLE FIX/WORKAROUND:<br><br><br>Real exception occurs in process tao_ft_naming, source file IORManipulation.cpp (IORManipulation project), <br>method TAO_IOR_Manipulation_impl::merge_iors, line 70 (after comparing type ids in merged iors).<br><br><br>IORManipulatuin.cpp<br><br>      // If the object type_id's differ then raise an exception.<br>      if (<a href="http://id.in">id.in</a> () && iors[i]->_stubobj ()-><a href="http://type_id.in">type_id.in</a> () &&<br>          ACE_OS::strcmp (<a href="http://id.in">id.in</a> (), iors[i]->_stubobj ()-><a href="http://type_id.in">type_id.in</a> ()))<br>          throw TAO_IOP::Invalid_IOR (); <br>//!!!!    ^^^^^^^^^^^^    exception is thrown in the previous line<br><br>The problem is that the only object in group after its creation is simply corba object.<br>And when the new real object is added (iors are merged), type of the new object is compared with corba object type (the first member). and the exception is thrown because the types are different. (in fact they should not be compared with corba object's type)<br>The first corba object does not have a profile at the moment of merging iors. <br>So the solution can be in selecting type id to compare not from the first object (ior), but from the first ior that has profile.<br><br>To solve the problem i removed lines 52, 53 (IORManipulation.cpp)<br><br>  CORBA::String_var id =<br>    CORBA::string_dup (iors[0]->_stubobj ()-><a href="http://type_id.in">type_id.in</a> ());<br><br><br>and changed lines 34-37 from<br><br>  for (i = 0; i < iors.length (); i++)<br>    {<br>      count += iors[i]->_stubobj ()->base_profiles ().profile_count ();<br>    }<br><br>to the following (to set id to the type_id of the first ior with non zero profile count)<br><br>  CORBA::String_var id;// type id to compare with<br><br>  for (i = 0; i < iors.length (); i++)<br>    {<br>      int n_profiles = iors[i]->_stubobj ()->base_profiles ().profile_count ();<br>      count += n_profiles;<br>      if (n_profiles && !<a href="http://id.in">id.in</a>())<br>        id = CORBA::string_dup (iors[i]->_stubobj ()-><a href="http://type_id.in">type_id.in</a> ());<br>    }<br><br>this code change solved the problem. <br>Perhaps we can also change the cycle that merges profiles to start with 0 index and to do merging only when profile count is not empty (but the service works without this extended change, because in this situation exactly the first ior has no profile).<br><br><br>real stack while debugging tao_ft_naming<br><br>    TAO_IORManipd.dll!TAO_IOR_Manipulation_impl::merge_iors(const TAO_IOP::TAO_IOR_Manipulation::IORList & iors)  Line 72    C++<br>     TAO_PortableGroupd.dll!TAO::PG_Object_Group_Manipulator::merge_iors(TAO_IOP::TAO_IOR_Manipulation::IORList & list)  Line 130 + 0x29 bytes    C++<br>     TAO_PortableGroupd.dll!TAO::PG_Object_Group::add_member_to_iogr(CORBA::Object * member)  Line 207 + 0xf bytes    C++<br>     TAO_PortableGroupd.dll!TAO::PG_Object_Group::add_member(const CosNaming::Name & the_location, CORBA::Object * member)  Line 269 + 0x13 bytes    C++<br>     TAO_FT_Naming_Servd.dll!TAO_FT_Naming_Manager::add_member(CORBA::Object * object_group, const CosNaming::Name & the_location, CORBA::Object * member)  Line 433 + 0x17 bytes    C++<br>     TAO_PortableGroupd.dll!POA_PortableGroup::add_member_ObjectGroupManager::execute()  Line 3099 + 0x23 bytes    C++<br>     TAO_PortableServerd.dll!TAO::Upcall_Wrapper::upcall(TAO_ServerRequest & server_request, TAO::Argument * const * args, unsigned int nargs, TAO::Upcall_Command & command, TAO::Portable_Server::Servant_Upcall * servant_upcall, CORBA::TypeCode * const * exceptions, unsigned int nexceptions)  Line 109 + 0xf bytes    C++<br>     TAO_PortableGroupd.dll!POA_PortableGroup::ObjectGroupManager::add_member_skel(TAO_ServerRequest & server_request, TAO::Portable_Server::Servant_Upcall * servant_upcall, TAO_ServantBase * servant)  Line 3165 + 0x2a bytes    C++<br>     TAO_PortableServerd.dll!TAO_ServantBase::synchronous_upcall_dispatch(TAO_ServerRequest & req, TAO::Portable_Server::Servant_Upcall * servant_upcall, TAO_ServantBase * derived_this)  Line 574 + 0x11 bytes    C++<br>     TAO_FtNamingd.dll!POA_FT_Naming::NamingManager::_dispatch(TAO_ServerRequest & req, TAO::Portable_Server::Servant_Upcall * servant_upcall)  Line 746 + 0x51 bytes    C++<br>     TAO_PortableServerd.dll!TAO_Object_Adapter::do_dispatch(TAO_ServerRequest & req, TAO::Portable_Server::Servant_Upcall & upcall)  Line 1198 + 0x4b bytes    C++<br>     TAO_PortableServerd.dll!TAO_Object_Adapter::dispatch_servant(const TAO::ObjectKey & key, TAO_ServerRequest & req, TAO_Pseudo_Out_T<CORBA::Object> forward_to)  Line 353 + 0x1a bytes    C++<br>     TAO_PortableServerd.dll!TAO_Object_Adapter::dispatch(TAO::ObjectKey & key, TAO_ServerRequest & request, TAO_Pseudo_Out_T<CORBA::Object> forward_to)  Line 766 + 0x28 bytes    C++<br>     TAOd.dll!TAO_Adapter_Registry::dispatch(TAO::ObjectKey & key, TAO_ServerRequest & request, TAO_Pseudo_Out_T<CORBA::Object> forward_to)  Line 110 + 0x33 bytes    C++<br>     TAOd.dll!TAO_Request_Dispatcher::dispatch(TAO_ORB_Core * orb_core, TAO_ServerRequest & request, TAO_Pseudo_Out_T<CORBA::Object> forward_to)  Line 22    C++<br>     TAOd.dll!TAO_GIOP_Message_Base::process_request(TAO_Transport * transport, TAO_InputCDR & cdr, TAO_OutputCDR & output, TAO_GIOP_Message_Generator_Parser * parser)  Line 1018    C++<br>     TAOd.dll!TAO_GIOP_Message_Base::process_request_message(TAO_Transport * transport, TAO_Queued_Data * qd)  Line 737 + 0x1e bytes    C++<br>     TAOd.dll!TAO_Transport::process_parsed_messages(TAO_Queued_Data * qd, TAO_Resume_Handle & rh)  Line 2502 + 0x17 bytes    C++<br>     TAOd.dll!TAO_Transport::handle_input_parse_data(TAO_Resume_Handle & rh, ACE_Time_Value * max_wait_time)  Line 2426 + 0x13 bytes    C++<br>     TAOd.dll!TAO_Transport::handle_input(TAO_Resume_Handle & rh, ACE_Time_Value * max_wait_time)  Line 1760 + 0x10 bytes    C++<br>     TAOd.dll!TAO_Connection_Handler::handle_input_internal(void * h, ACE_Event_Handler * eh)  Line 292 + 0x29 bytes    C++<br>     TAOd.dll!TAO_Connection_Handler::handle_input_eh(void * h, ACE_Event_Handler * eh)  Line 251 + 0x10 bytes    C++<br>     TAOd.dll!TAO_IIOP_Connection_Handler::handle_input(void * h)  Line 408    C++<br>     ACEd.dll!ACE_TP_Reactor::dispatch_socket_event(ACE_EH_Dispatch_Info & dispatch_info)  Line 545 + 0xe bytes    C++<br>     ACEd.dll!ACE_TP_Reactor::handle_socket_events(int & event_count, ACE_TP_Token_Guard & guard)  Line 415 + 0xc bytes    C++<br>     ACEd.dll!ACE_TP_Reactor::dispatch_i(ACE_Time_Value * max_wait_time, ACE_TP_Token_Guard & guard)  Line 244 + 0x10 bytes    C++<br>     ACEd.dll!ACE_TP_Reactor::handle_events(ACE_Time_Value * max_wait_time)  Line 173 + 0x10 bytes    C++<br>     ACEd.dll!ACE_Reactor::handle_events(ACE_Time_Value * max_wait_time)  Line 188 + 0x27 bytes    C++<br>     TAOd.dll!TAO_ORB_Core::run(ACE_Time_Value * tv, int perform_work)  Line 2301 + 0xf bytes    C++<br>     TAOd.dll!CORBA::ORB::run(ACE_Time_Value * tv)  Line 189    C++<br>     TAOd.dll!CORBA::ORB::run()  Line 175    C++<br>     tao_ft_naming.exe!ORB_Runner::svc()  Line 133 + 0x15 bytes    C++<br>     tao_ft_naming.exe!TAO_FT_Naming_Service::run()  Line 155 + 0x8 bytes    C++<br>     tao_ft_naming.exe!ace_main_i(int argc, char * * argv)  Line 55    C++<br>     tao_ft_naming.exe!ACE_Main::run_i(int argc, char * * argv)  Line 40 + 0x30 bytes    C++<br>     ACEd.dll!ACE_Main_Base::run(int argc, char * * argv)  Line 88 + 0x17 bytes    C++<br>     tao_ft_naming.exe!main(int argc, char * * argv)  Line 40 + 0x5f bytes    C++<br>     tao_ft_naming.exe!__tmainCRTStartup()  Line 555 + 0x19 bytes    C<br>     tao_ft_naming.exe!mainCRTStartup()  Line 371    C<br><br><br>There is also related problem in the code of the example project <br>(ace_wrappers\TAO\orbsvcs\tests\ft_naming\Load_Balancing\). <br><br>    In the sample server the object group is bound in name service at first and then it is filled with objects. <br>Because of this exact sequence client get the "old" initial object group reference and fails to cast it to required object reference via Test::Basic::_narrow.<br>        To make the sample work we need to bind (rebind) group in server only after the population of the group. <br><br>Move (put) the following code right before orb->run() (and not before adding group members).<br><br>      CosNaming::Name name (1);<br>      name.length (1);<br>      name[0].id = CORBA::string_dup ("basic_name");<br>      try {<br>        (lb_server.name_svc ())->rebind (name, lb_server.object_group ());<br>      }<br>      catch (const CORBA::Exception& ex)<br>      {<br>        ex._tao_print_exception ("Unable to bind object group in name service.\n");<br>        return 1;<br>      }<br><br>Thank you for your attention.<br><br></div>