views:

2185

answers:

5

My app sends lots and lots of data to SAP. To di this, it builds up an SAP table object and sends it over. I get this error somewhat regularly, but not reliably:

System exception thrown while marshaling .NET type 20081219 to RFCTYPE_BCD
   at SAP.Connector.Rfc.RfcMarshal.NetFieldToRfcField(Object src, RFCTYPE type, Encoding encoding, Byte[] dest, Int32 offset, Int32 len, Int32 charSize, Int32 decimals)
   at SAP.Connector.Rfc.RfcStructureUtil.ToRfcStructure(Object obj, Byte[] dest, Type t, Encoding encoding, Boolean isUnicode, PropertyInfo[] propinfos, RfcStructInfo structInfo)
   at SAP.Connector.Rfc.RfcStructureUtil.GetITabFromList(SAPConnection conn, Object list, Type t, RfcStructInfo structInfo, Int32 itab)
   at SAP.Connector.Rfc.RfcClient.PrepareClientParameters(Type classType, MethodInfo m, Boolean isTQRfc, Object[] MethodParamsIn, RFC_PARAMETER[]& paramsIn, RFC_PARAMETER[]& paramsOut, RFC_TABLE[]& tables, ParameterMap[]& paramMaps)
   at SAP.Connector.Rfc.RfcClient.RfcInvoke(SAPClient proxy, String method, Object[] methodParamsIn)
   at SAP.Connector.SAPClient.SAPInvoke(String method, Object[] methodParamsIn)

What's weird is that this doesn't happen every time. Also, the .NET type it complains about, "20081219" is the data I'm passing (a date)--not a type. I think the type of that field is RFCTYPE.RFCTYPE_TIME.

Any suggestions on how to troubleshoot this intermittent error? Is there some kind of state I should be clearing between calls to the SAP RFCs?


Update:

As requested, here's the code that calls SAP:

Using sapConnection As New MySapProxy(ConnectionString)
  sapConnection.Connection.Open()
  sapConnection.TheSapRfcICall(SapOpCode, Nothing, Nothing, sapTable, ResultTable)
End Using

I'm thinking maybe multiple threads are using the same connection some how. Using SAP.Connector.GetNewConnection instead didn't change anything.


Update:

It seems this problem occurs even when I run a single thread! What's the deal??

Is there a way to disable the connection pool to see if that fixes it?


Update:

@Igal Serban's answer seems to be working for me. I'll check the logs tomorrow morning and (hopefully) award the bounty! Thanks so much.


Update:

As requested, my version of librfc32.dll is 6403.3.78.4732.

+1  A: 

Update 4: In second thought, I don't think that the librfc version is important. The exception seems to come from the managed code. The options that I can think of are:

  • Try to use debugger on the single threaded version.
  • The magical way. Even without finding the bug ( That is on sap or your code). Just changing the way you do business can make it go away. Its ugly, but sometimes practical. Anyway the recommended way for your scenario seems to be to use connection pool, and not to create new proxy object for each request. So something like this (untested) code can be used:


MySapProxy proxy = new MySapProxy(); // do this only once.

// and in you main loop:
using (proxy.Connection = Connection.GetConnection(connectionString))
{
    proxy.TheSapRfcICall(SapOpCode, Nothing, Nothing, sapTable, ResultTable)
}


This sample is using implicitly the connection pool. The use of can be controlled from the config file.

Update 3: Can you please check your librfc32.dll version and date? its should be in system32 directory or in your application directory or somewhere in your %path%.

Update 2: Sap notes are just like kb articles. I don't know if there is free access to the note in the sdn.sap.com so I have send it to your mail.

Update 1: SAP Note 1000057 states:

Under multithreaded heavy load, exceptions of type RfcMarshalException with reference to System.Xml.Xsl.XsltException as inner exception may occur.

While not exactly the exception you receive. Its worth a try.

Patch is available as attachment to this note.

Update 0:Only a guess. But I would suggest to look at threading issues. Is this all the stack? Can you post the part off the code where you call the sap code?

Igal Serban
Now that you mention it, that makes a lot of sense. I'll force the app down to one thread and see if the problem goes away.
Michael Haren
It does go away when running a single thread. Now I just have to figure out why...
Michael Haren
@Igal Serban: unforunately this has not solved the problem. I think you're on the right track, though--it seems to occur in spurts, perhaps during high load times.
Michael Haren
As requested, my version of librfc32.dll is 6403.3.78.4732.
Michael Haren
I agree that reducing the number of connection cycles by persisting a long-lived connection would probably help, it'd be nice, though, to know what the real problem is.
Michael Haren
+1  A: 

Edit:

I still think it's something to do with the mapping. I believe that RFCTYPE_BCD type is decimal (Business Connector Decimal), so it will have difficulty pushing a date value into it (and could possibly work sometimes?). I would suggest regenerating the proxies, or log the data being marshalled when you get the error. Something like this (sorry - we use our own proxy layer, so I'm not that familiar with Business Connector):

Could you translate the following into VB (and whatever the format of the sapTable structure is):

Using sapConnection As New MySapProxy(ConnectionString)
  sapConnection.Connection.Open()
  try {
    sapConnection.TheSapRfcICall(SapOpCode, Nothing, Nothing, sapTable, ResultTable)
  } catch (Exception e) {
    StringBuilder sb = new StringBuilder();
    foreach (Field f in sapTable.Fields) {
      sb.AppendLine(f.Name + "=" f.Value);
    }
    sb.AppendLine(e.StackTrace);
    File.AppendAllText("C:\\Exception_" + DateTime.Now.ToString("u") + ".txt", sb.ToString());
  }
End Using

I know it's a pain, but just do a quick and dirty to get some data to spit out when the error occurs.

========

From just the description you've posted, the best I can come up with is perhaps you are trying to marshal a date value (20081219) into a time field?

Can you wrap that call in a try/catch and log the values of the table being sent to SAP and post those here? I'm hoping there's a clue in the data.

I know from doing web service postings to SAP that SAP is quite particular about the format of its date time & values.

Travis
Unfortunately I ruled out format issues because this doesn't occur consistently.
Michael Haren
That debug is a good idea in general, though, I'll try it.
Michael Haren
A: 
leppie
No, each thread has its own connection. In fact, I changed it so that each thread would create and open/close the connection each time it's needed. This didn't help.
Michael Haren
A: 

May it be the date format issue? You say it doesn't happens every time.
So when you pass 20081202 it takes '12' as a day part and 02 as a month part. It's OK.
But when you pass 20081219 it tries to parse 19 as a month and throws exception?
Check it with your SAP administrator.

Max Gontar
Unfortunately I ruled out format issues because this doesn't occur consistently. That is, it works and fails with the same data.
Michael Haren
A: 

Michael: Did you ever find the cause of this issue?

I'm having the same problem, where I get an exception saying it's trying to convert the text "PLN" to a decimal. In my case, the "PLN" is the value of a string field (RFC_CHAR), and the proxy classes cleary states this field a string. The weird thing (as in your case) is that posting the same exact same data works most of the time, but occasionally it throws an exception.

I'm running my app in a single thread, though I am creating a new proxy for each call. I'm using connection pooling.

Jon: I never really got an answer. I added some logic to reuse connections instead of recycling them very frequently (not quite connection pooling, but close) which seems to help. I still see it occasionally, though.
Michael Haren