title: Constant TAO CORBA IOR
body: <p>How to configure TAO corba server so that IOR string of this server generated from object_to_string is constant? </p>
  
  <p>Each time the IOR string generated from object_to_string changes once server restarts. This is inconvenient since client has to update its cached server IOR string via reloading IOR file or namingservice accessing. As a result, it would be useful if server can generate a constant IOR string, no matter how many times it restarts. </p>
  
  <p>My corba server is based on ACE+TAO and i do remember TAO supports constant IOR string: the IOR string each time it generates are same, and the solution is add some configurations for server. But i could not remember these configurations now. </p>
  
  <p>=============================================
  <strong>UPDATE:</strong> </p>
  
  <p>In ACE_wrappers/TAO/tests/POA/Persistent_ID/server.cpp, i added a new function named testUniqe() which is similiar to creatPOA method. And the update file content is: </p>
  
  <pre><code>void testUniqu(CORBA::ORB_ptr orb_, PortableServer::POA_ptr poa_){
  
    CORBA::PolicyList policies (2);
    policies.length (2);          
                                                       //IOR is the same even it is SYSTEM_ID
    policies[0] =   poa_-&gt;create_id_assignment_policy (PortableServer::USER_ID); 
  
    policies[1] =   poa_-&gt;create_lifespan_policy (PortableServer::PERSISTENT);
    PortableServer::POAManager_var poa_manager = poa_-&gt;the_POAManager ();
    PortableServer::POA_ptr child_poa_ =   poa_-&gt;create_POA ("childPOA", poa_manager.in (), policies);
  
    // Destroy the policies
    for (CORBA::ULong i = 0;  i &lt; policies.length ();  ++i)  {
        policies[i]-&gt;destroy ();
      }
  
    test_i *servant =   new test_i (orb_, child_poa_);
  
    PortableServer::ObjectId_var oid = PortableServer::string_to_ObjectId("xushijie");
    child_poa_-&gt;activate_object_with_id (oid,  servant);
  
    PortableServer::ObjectId_var id =  poa_-&gt;activate_object (servant);
    CORBA::Object_var object = poa_-&gt;id_to_reference (id.in ());
  
    test_var test =  test::_narrow (object.in ());
    CORBA::String_var ior = orb_-&gt;object_to_string(test.in());
    std::cout&lt;&lt;ior.in()&lt;&lt;std::endl;
  
    poa_-&gt;the_POAManager()-&gt;activate();
    orb_-&gt;run();
  }
  
  int
  ACE_TMAIN (int argc, ACE_TCHAR *argv[])
  {
  
    try
      {
        CORBA::ORB_var orb =
          CORBA::ORB_init (argc, argv);
  
        int result = parse_args (argc, argv);
        CORBA::Object_var obj =
          orb-&gt;resolve_initial_references ("RootPOA");
  
        PortableServer::POA_var root_poa =
          PortableServer::POA::_narrow (obj.in ());
  
        PortableServer::POAManager_var poa_manager =
          root_poa-&gt;the_POAManager ();
        testUniqu(orb.in(), root_poa.in());
         orb-&gt;destroy ();
      }
    catch (const CORBA::Exception&amp; ex)
      {
        ex._tao_print_exception ("Exception caught");
        return -1;
      }
  
    return 0;
  }
  </code></pre>
  
  <p>The problem is that the output server IORs are still different once restart. I also compared this code to the one in Page 412(Advance Corba Programming), but still fail..</p>
  
  <p>///////////////////////////////////</p>
  
  <p>UPDATE:</p>
  
  <p>With "server  -ORBListenEndpoints iiop://:1234 > /tmp/ior1", the generated two IORs are: </p>
  
  <p>IOR:010000000d00000049444c3a746573743a312e300000000001000000000000007400000001010200150000007368696a69652d5468696e6b5061642d543431300000d2041b00000014010f0052535453f60054c6f80c000000000001000000010000000002000000000000000800000001000000004f41540100000018000000010000000100010001000000010001050901010000000000
  IOR:010000000d00000049444c3a746573743a312e300000000001000000000000007400000001010200150000007368696a69652d5468696e6b5061642d543431300000d2041b00000014010f0052535468f60054da280a000000000001000000010000000002000000000000000800000001000000004f41540100000018000000010000000100010001000000010001050901010000000000</p>
  
  <p>The result for tao_catior for ior1 and ior2: </p>
  
  <pre><code>ior1: 
  The Byte Order: Little Endian
  The Type Id:    "IDL:test:1.0"
  Number of Profiles in IOR:      1
  Profile number: 1
  IIOP Version:   1.2
      Host Name:  **
      Port Number:        1234
      Object Key len:     27
      Object Key as hex:
      14 01 0f 00 52 53 54 53 f6 00 54 c6 f8 0c 00 00
      00 00 00 01 00 00 00 01 00 00 00
      The Object Key as string:
      ....RSTS..T................
      The component &lt;1&gt; ID is 00 (TAG_ORB_TYPE)
              ORB Type: 0x54414f00 (TAO)
      The component &lt;2&gt; ID is 11 (TAG_CODE_SETS)
          Component length: 24
          Component byte order:   Little Endian
          Native CodeSet for char:  Hex - 10001   Description - ISO8859_1
          Number of CCS for char 1
          Conversion Codesets for char are:
          1)  Hex - 5010001       Description - UTF-8
          Native CodeSet for wchar:  Hex - 10109  Description - UTF-16
          Number of CCS for wchar 0
  ecoding an IOR:
  
  
  //ior2
  The Byte Order: Little Endian
  The Type Id:    "IDL:test:1.0"
  Number of Profiles in IOR:      1
  Profile number: 1
  IIOP Version:   1.2
      Host Name:  **
      Port Number:        1234
      Object Key len:     27
      Object Key as hex:
      14 01 0f 00 52 53 54 68 f6 00 54 da 28 0a 00 00
      00 00 00 01 00 00 00 01 00 00 00
      The Object Key as string:
      ....RSTh..T.(..............
      The component &lt;1&gt; ID is 00 (TAG_ORB_TYPE)
              ORB Type: 0x54414f00 (TAO)
      The component &lt;2&gt; ID is 11 (TAG_CODE_SETS)
          Component length: 24
          Component byte order:   Little Endian
          Native CodeSet for char:  Hex - 10001   Description - ISO8859_1
          Number of CCS for char 1
          Conversion Codesets for char are:
          1)  Hex - 5010001       Description - UTF-8
          Native CodeSet for wchar:  Hex - 10109  Description - UTF-16
          Number of CCS for wchar 0
  </code></pre>
  
  <p>The diff result is: </p>
  
  <pre><code>&lt;     14 01 0f 00 52 53 54 53 f6 00 54 c6 f8 0c 00 00 
  ---
  &gt;     14 01 0f 00 52 53 54 68 f6 00 54 da 28 0a 00 00 
  19c19
  &lt;     ....RSTS..T................
  ---
  &gt;     ....RSTh..T.(..............
  </code></pre>
  
  <p>Similar diff result is:</p>
  
  <pre><code>&lt;     14 01 0f 00 52 53 54 62 fd 00 54 2c 9a 0e 00 00 
  ---
  &gt;     14 01 0f 00 52 53 54 02 fd 00 54 f9 a9 09 00 00 
  19c19
  &lt;     ....RSTb..T,...............
  ---
  &gt;     ....RST...T................
  </code></pre>
  
  <p>The difference is in ObjectKey.</p>
  
  <p>============================================</p>
  
  <p>update: </p>
  
  <p>Instead of using above code, i find a better solution with helper TAO_ORB_Manager which is used NamingService and TAO/examples/Simple. TAO_ORB_Manager encapsulates API and generate persistent IORs, as example code in Simple.cpp: </p>
  
  <pre><code>  if (this-&gt;orb_manager_.init_child_poa (argc, argv, "child_poa") == -1){
        CORBA::String_var str  = 
          this-&gt;orb_manager_.activate_under_child_poa (servant_name,
                                                       this-&gt;servant_.in ());
    }
  </code></pre>
  
  <p>This is some description for TAO_ORB_Manager: </p>
  
  <pre><code>class TAO_UTILS_Export TAO_ORB_Manager
  {
    /**
     * Creates a child poa under the root poa with PERSISTENT and
     * USER_ID policies.  Call this if you want a @a child_poa with the
     * above policies, otherwise call init.
     *
     * @retval -1 Failure
     * @retval 0 Success
     */
    int init_child_poa (int &amp;argc,
                        ACE_TCHAR *argv[],
                        const char *poa_name,
                        const char *orb_name = 0);
  
  
    /**
     * Precondition: init_child_poa has been called.  Activate &lt;servant&gt;
     * using the POA &lt;activate_object_with_id&gt; created from the string
     * &lt;object_name&gt;. Users should call this to activate objects under
     * the child_poa.
     *
     * @param object_name  String name which will be used to create
     *                     an Object ID for the servant.
     * @param servant  The servant to activate under the child POA.
     *
     * @return 0 on failure, a string representation of the object ID if
     *           successful.  Caller of this method is responsible for
     *           memory deallocation of the string.
     */
    char *activate_under_child_poa (const char *object_name,
                                    PortableServer::Servant servant);
    ...................
  }
  </code></pre>
  
  <p>After build, I can get what i want with -ORBListenEndpoints iiop://localhost:2809 option. Thanks @Johnny Willemsen help</p>