Menu

JIVariant marshaling ing 1.24

2008-06-11
2012-11-29
  • Michael Stevens

    Michael Stevens - 2008-06-11

    Greetings,

    I am working on upgrading our DCOM application from j-interop 1.22 to 1.24

    The server our client talks to requires lots of variants or arrays of variants so we were expecting a few problems.

        final JIArray vName = new JIArray(new JIVariant[] { new JIVariant(new JIString("1234.ABCD.GFGE.XXX 123")) });
        final Object[] params = new Object[] { vName };
        final Object[] res = dcon.callMethodA("GetValue", params );

    Dumping the NDR data I found that the lengths of the JIVariant containing strings are being calculated differently in 1.24. This new calculation method seems to be incorrect in that the server we are connecting to rejects the stub data.

    The line in question is in JIVariant.getArrayLengthForVarType() line 1936
        length += variant.getLengthInBytes(FLAG) * 8;

    the old version which is still contained in a comment is
            length += ((VariantBody)(variant.member.getReferent())).variantType * 8;

    I don't quite understand the logic behind variantType * 8 but it seems to work if I switch back to the old code.

    Is getLengthInBytes supposed to return a different length or is this a bug?

    All the best from me and also "sgstaedler" who ask me to look into this problem.

    Michael

     
    • Vikram Roopchand

      Hi Michael,
                 Could you please show me the log files at the FINEST level for these cases:-

      A) In the code which FAILS.

      1. Have the Array with 1 member.
      2. Have the Array with 2 members.
      3. Have the Array with 3 members.

      B) In the code which SUCCEEDS (after you replace the lines with the old ones).

      1. Exactly the same code as above (with the same members)

      Please provide separate logs and not all in one. Please use only Strings as inputs and of different length (for the 3 members). I want to check the packet lengths. We may need to repeat this with different data types for confirmation.

      Thanks,
      best regards,
      Vikram

       
    • Michael Stevens

      Michael Stevens - 2008-06-13

      Hi Vikram,

      I will try and get FINEST logs to you for the simple test cases. The logs I have at the moment at for complex data on a production server which I cannot post!

      Is there a way to get j-interop to marshal the method call parameters without connecting to a COMObject. That way I could build a minimal test case without a test server.

      All the best,
        Michael

       
      • Vikram Roopchand

        Hi Michael,
                   Do not post the logs here, please send them to me. As for your second question, unfortunately there is no such way.

        Thanks,
        best regards,
        Vikram

         
    • Michael Stevens

      Michael Stevens - 2008-07-08

      Hi Vikram,

      Sorry to take so long to get back to you. I've been working on a few other things. I finally got down to getting some logs and doing some testing. Latest tests are with 2.0-rc5 so you don't have to look at old code.

      Test scenario is as follows:

      DCOM Server in C++ with a very simple IDL for testing
      // component.idl
      import "unknwn.idl";

      [ uuid(10000003-0000-0000-0000-000000000001),
        helpstring("MiniDcom Type Library"),
        version(1.0) ]
      library Server
      {
          importlib("stdole32.tlb");
          interface IDouble;

          [ uuid(10000002-0000-0000-0000-000000000001) ]
          coclass MiniDcom
          {
              interface IDouble;
          }
      };

      [ object, uuid(10000001-0000-0000-0000-000000000001), dual ]
      interface IDouble : IDispatch
      {
          [id(0x00000008), helpstring("method GetIPValue")]
          [id(0x00000010), helpstring("method TestName")]
              HRESULT TestName(
                              [in] VARIANT* vName);
      }

      DCOM Client with j-interop-2.0rc5:
        public void testName() throws IllegalArgumentException, UnknownHostException, JIException
        {
              final JIClsid clsId = JIClsid.valueOf(appuuid);
              final JISession session = JISession.createSession(domain, username, password);
              final JIComServer comServer = new JIComServer(clsId, address, session);
              final IJIComObject gmsDconServer = comServer.createInstance();
              final IJIDispatch dcon = (IJIDispatch) JIObjectFactory.narrowObject(gmsDconServer.queryInterface(IJIDispatch.IID));
             
              final JIArray aName = new JIArray(new JIVariant[] {
                  new JIVariant(new JIString("1234.ABCD.GFGE.XXX 123"))
                  ,new JIVariant(new JIString("BBBB"))
                  ,new JIVariant(new JIString("CCCC"))
               });
              final JIVariant vName = new JIVariant(aName);

              final Object[] params = new Object[] { vName };

              final Object[] res = dcon.callMethodA("TestName", params);
              dcon.release();

              System.out.println("res:" + res.length);
        }

      I now tested with both Win2000 and WinXP. The result is very interesting. Everything is fine as long as the DCOM server is running on WinXP. When the DCOM server runs on Win2000 then calling the method results in:

      org.jinterop.dcom.common.JIException: The stub received bad data. Please check whether the API has been called in the right way, with correct parameter formation. [0x800706F7]

      I think there is some fundamental difference between the way Win2000 and WinXP marshal this kind of Variant array data. I guess Microsoft take account of this in there own automation client libraries.

      Oldly it seems that the serizalised data from J-interop is different when connecting to a Win200 server then from that when connecting to a WinXP server. I not sure about this however as I have not looked into the exact changes to the NDR. I have logs of the tests with both client and server on XP and 2000 which I will email you.

      The interesting thing is that the original code in JIVariant from j-interop 1.22 allows you to talk to a Win2000 server as long as there is only 1 element in the array.

      I hope this helps, all the best,
      Michael Stevens

       
      • Vikram Roopchand

        Hi Michael,
                   Could you send me the logs please for both platforms. I am not sure if the packets would be marshaled in different ways for different OSs. We do not maintain any such dependency in code. If the packets are the same then I can only think about the treatment of the COM application in Windows itself. I have seen many apps work on one but not on another platform and it is mostly related to the runtime on that platform. But we should investigate it fully. I would like to rule out a bug in the library or fix it if one exists.

        Thanks,
        best regards,
        Vikram

         

Log in to post a comment.