DateTimeConverter cannot convert from Microsoft.Dynamics.Ax.Xpp.AxShared.Date

Hi All,

I have created the batch job to transfer some sales information to Loc8 Interface…When i run the same code using AOT → job , it is working fine.But while running batch job i got the following error…

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —> System.NotSupportedException: DateTimeConverter cannot convert from Microsoft.Dynamics.Ax.Xpp.AxShared.Date.
at System.ComponentModel.TypeConverter.GetConvertFromException(Object value)
at System.ComponentModel.TypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at System.ComponentModel.DateTimeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at System.ComponentModel.NullableConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
at Dynamics.Ax.Application.NOB_Loc8InterfaceBatch.XXX_callloc8assetservice() in XXX_Loc8InterfaceBatch.XXX_CallLoc8AssetService.xpp:line 84

Can any suggest me how to solve this and why i am getting this error only in batch process?

Thanks in Advance…

Have you generated the IL?

You’re failing to reproduce the problem because you’re testing a wrong thing. Jobs execute on client, i.e. in X++, while batches execute in CIL on server. Change your test to use CIL too.
It would also help if you showed the code in question, finding bugs in unknown code it pretty difficult.

This is my code…

public static void KTI_CallLoc8AssetService()
{
    System.Exception                                        exception;
    ClrObject                                               clientType;
    MapEnumerator                                           enumerator;
    KTI_Loc8References.AssetsService.saveAssetRequest       request;
    KTI_Loc8References.AssetsService.AssetsPortClient       assetclient;
    KTI_Loc8References.AssetsService.customStringField      customStringField;
    KTI_Loc8References.AssetsService.customBooleanField     customBooleanField;
    KTI_Loc8References.AssetsService.customDateTimeField    customDateTimeField;
    KTI_Loc8References.AssetsService.customListField        customListField;
    KTI_Loc8References.AssetsService.customNumberField      customNumberField;
    KTI_Loc8References.AssetsService.customField[]          customField;
    KTI_Loc8References.Clients                              clients;
    System.DateTime                                         datetime;
    WMSOrderTrans                                           wmsOrderTransTmp;
    SalesParmLine                                           salesParmLineTmp;
    KTI_EcoResAttributesValues                              kti_EcoResAttributeValues;
    NOB_LocAssetInterface                                   locAssetInterface, locAssetInterfaceChk, locAssetInterfaceChk1;
    SysOperationProgress progress1;
    #AviFiles
    int                                                     counter = 0,i,j;
    int64                                                   n;
    str                                                     url;
    System.ServiceModel.Description.ServiceEndpoint         endPoint;
    System.ServiceModel.EndpointAddress                     endPointAddress;
    NOB_parmtable                                           parmtable;
    utcDateTime                                             time;
    SalesTable                                              salesTable;
    LogisticsLocation                                       logisticsLocation;
  //  InteropPermission                                       InteropPermission = new InteropPermission(InteropKind::ClrInterop).assert();



    j    = 1;
    time = DateTimeUtil::utcNow();
    parmtable = NOB_parmtable::find();
    //ttsBegin;
    while select locAssetInterface
        where locAssetInterface.InterfaceStatus == InterfaceStatus::Waiting || locAssetInterface.InterfaceStatus == InterfaceStatus::Retrying
        && locAssetInterface.LastInterfaceDateTime <= DateTimeUtil::addMinutes(time,-parmtable.KTI_AssetRetryWaitTime)
    {
        if (locAssetInterface)
        {
            try
            {
                select firstOnly wmsOrderTransTmp
                    where wmsOrderTransTmp.RecId == locAssetInterface.RefRecId
                    &&  wmsOrderTransTmp.TableId == locAssetInterface.RefTableId;

                salesTable = SalesTable::find(wmsOrderTransTmp.inventTransRefId);

                progress1 = SysOperationProgress::newGeneral(#aviUpdate,"Calling Loc8 webservice",1);
                progress1.setAnimation(#AviUpdate);
                progress1.setCount(counter);
                Progress1.incCount();
                progress1.update(true);
                clientType = CLRInterop::getType("KTI_Loc8References.AssetsService.AssetsPortClient");
                assetclient = AifUtil::CreateServiceClient(clientType);
                url= strFmt("%1assets.wsdl",NOB_parmtable::find().KTI_WSDLWebsite);
                endPointAddress = new System.ServiceModel.EndpointAddress(url);
                endPoint = assetclient.get_Endpoint();
                endPoint.set_Address(endPointAddress);
                select count(RecId) from kti_EcoResAttributeValues
                        where kti_EcoResAttributeValues.RefTableId == locAssetInterface.RefTableId
                            && kti_EcoResAttributeValues.RefRecId   == locAssetInterface.RefRecId;
                n = kti_EcoResAttributeValues.RecId;
                customField = new KTI_Loc8References.AssetsService.customField[n]();
                clients = new KTI_Loc8References.Clients();
                clients.addSOAPHeaderforAsset(assetclient,NOB_parmtable::find().KTI_Loc8Username,NOB_parmtable::find().KTI_Loc8Password);
                request = new KTI_Loc8References.AssetsService.saveAssetRequest();
                request.set_assetId(wmsOrderTransTmp.KTI_TNIBarcode);
                request.set_integrationId(wmsOrderTransTmp.KTI_TNIBarcode);
                request.set_name(wmsOrderTransTmp.itemName());



                logisticsLocation = LogisticsLocation::find(LogisticsPostalAddress::findRecId(WMSPickingRoute::find(wmsOrderTransTmp.routeId).DeliveryPostalAddress).Location);

                request.set_parentId(logisticsLocation.NOB_TechInspectLocationId ? logisticsLocation.NOB_TechInspectLocationId : logisticsLocation.LocationId);



                request.set_purchaseOrder(salesTable.PurchorderFormNum);
                request.set_purchaseDate(DateTimeUtil::date(WMSPickingRoute::find(wmsOrderTransTmp.routeId).ActivationDateTime));
                request.set_assetClassName(InventTable::kTI_getassetclassName(wmsOrderTransTmp.itemId));
                request.set_serialNumber(InventDim::find(wmsOrderTransTmp.inventDimId).inventSerialId);
                request.set_createdDate(DateTimeUtil::date(DateTimeUtil::utcNow()));
                request.set_createdDateSpecified(true);
                i=0;
                while select kti_EcoResAttributeValues
                        where kti_EcoResAttributeValues.RefTableId == wmsOrderTransTmp.TableId
                            && kti_EcoResAttributeValues.RefRecId   == wmsOrderTransTmp.RecId
                {
                    switch(kti_EcoResAttributeValues.DataType)
                    {
                        case AttributeDataType::Text:
                            if(!kti_EcoResAttributeValues.IsEnumeration)
                            {
                                customStringField   = new KTI_Loc8References.AssetsService.customStringField();
                                customStringField.set_fieldName(kti_EcoResAttributeValues.AttributeName);
                                if(kti_EcoResAttributeValues.Value != "")
                                {
                                    customStringField.set_fieldValue(kti_EcoResAttributeValues.Value);
                                }
                                else
                                {
                                    customStringField.set_fieldValue("Unknown");
                                }
                                customField.set_Item(i,customStringField);
                            }
                            else
                            {
                                customListField     = new KTI_Loc8References.AssetsService.customListField();
                                customListField.set_fieldName(kti_EcoResAttributeValues.AttributeName);
                                customListField.set_fieldValue(kti_EcoResAttributeValues.Value);
                                customField.set_Item(i,customListField);
                            }
                            break;
                        case AttributeDataType::DateTime:
                            customDateTimeField = new KTI_Loc8References.AssetsService.customDateTimeField();
                            customDateTimeField.set_fieldName(kti_EcoResAttributeValues.AttributeName);
                            datetime = System.DateTime::Parse(kti_EcoResAttributeValues.Value);
                            customDateTimeField.set_fieldValue(datetime);
                            customField.set_Item(i,customDateTimeField);
                            break;
                        case AttributeDataType::TrueFalse:
                            customBooleanField  = new KTI_Loc8References.AssetsService.customBooleanField();
                            customBooleanField.set_fieldName(kti_EcoResAttributeValues.AttributeName);
                            if(kti_EcoResAttributeValues.Value == "true")
                            {
                                customBooleanField.set_fieldValue(true);
                            }
                            else
                            {
                                customBooleanField.set_fieldValue(false);
                            }
                            customField.set_Item(i,customBooleanField);
                            break;
                        case AttributeDataType::Integer:
                        case AttributeDataType::Decimal:
                            customNumberField   = new KTI_Loc8References.AssetsService.customNumberField();
                            customNumberField.set_fieldName(kti_EcoResAttributeValues.AttributeName);
                            customNumberField.set_fieldValue(str2num(kti_EcoResAttributeValues.Value));
                            customField.set_Item(i,customNumberField);
                            break;
                        default: break;
                    }

                    i++;
                }
                request.set_customFields(customField);
                assetclient.saveAsset(request);
                assetclient.Close();
                assetclient.Dispose();
                ttsBegin;
                select forUpdate locAssetInterfaceChk
                    where locAssetInterfaceChk.RecId == locAssetInterface.RecId;
                locAssetInterfaceChk.InterfaceStatus = InterfaceStatus::Success;
                locAssetInterfaceChk.update();
                ttsCommit;

            }
            catch(Exception::CLRError)
            {
                if (j<=parmtable.KTI_AssetInterfaceRetry)
                {
                    j++;
                    retry;
                }
                else
                {
                    exception = CLRInterop::getLastException();
                    info(exception.ToString());
                    ttsBegin;
                    select forUpdate locAssetInterfaceChk1
                        where locAssetInterfaceChk1.RecId == locAssetInterface.RecId;
                    locAssetInterfaceChk1.FailureReason = exception.ToString();
                    if (locAssetInterfaceChk1.RetryCount >= parmtable.KTI_AssetInterfaceRetry)
                    {
                        locAssetInterfaceChk1.InterfaceStatus = InterfaceStatus::Failed;
                    }
                    else
                    {
                        locAssetInterfaceChk1.RetryCount =  locAssetInterface.RetryCount + 1 ;
                        locAssetInterfaceChk1.InterfaceStatus = InterfaceStatus::Retrying;
                    }
                    locAssetInterfaceChk1.LastInterfaceDateTime = DateTimeUtil::utcNow();
                    locAssetInterfaceChk1.update();
                    ttsCommit;
                   // break;
                }
            }
        }
        j= 1;
    }
   // ttsCommit;
    info('Batch Process has been completed');
}




Hi Kranthi,
Thanks for ur reply…
I ran both incremental and full CIL…
This is what you asked right…
or any other…?

Any suggestions…?

Are you sure the line number match? There doens’t seem any code like that at line 84? Did you build CIL? If so, please now use the debugger to debug the code. If you followed my original advise, you will be able to debug synchronous code instead of the batch.

Hi Martin,
84 -request.set_purchaseDate(DateTimeUtil::date(WMSPickingRoute::find(wmsOrderTransTmp.routeId).ActivationDateTime));

When you have problems with type conversions, you should always check what types are involved. Also, when you have a line doing several things, you should find out which one is failing.
Because you didn’t give us any details, I’ll have make a plenty of assumptions.
I assume that ActivationDateTime is utcDateTime and set_purchaseDate() expects System.DateTime. DateTimeUtil::date() is there probably because you want to remove the date part. The fact that there is no handling of time zones may be a bug, or maybe it’s acceptable in your case. It seems that it’s failing on the call of request.set_purchaseDate() and it would behave the same if you provided a fixed value (i.e. the rest of your code could be ignored, as it’s relevant to the problem).

There is a known issue which indeed is related to CIL; you don’t need a batch to see it. Your code expects that the X++ date value (returned by DateTimeUtil::date()) will be implicitly converted to the .NET structure System.DateTime, but it doesn’t happen in CIL. You should do the conversion explicitly, e.g. with utcDateTime2SystemDateTime().

Hi Martin,
Thanks for your valuable reply…I have used utcDateTime2SystemDateTime() but it wasn’t working…
After commenting the following two lines it is working fine …
request.set_purchaseDate(DateTimeUtil::date(WMSPickingRoute::find(wmsOrderTransTmp.routeId).ActivationDateTime));
request.set_createdDate(DateTimeUtil::date(DateTimeUtil::utcNow()));

Hi Martin,

I got the following error in Test environment for this same process…

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —>

System.ServiceModel.FaultException: org.hibernate.exception.GenericJDBCException: could not execute

statementServer

stack trace: at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime

operation, ProxyRpc& rpc) at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway,

ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout) at

System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,

ProxyOperationRuntime operation) at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,

IMessage retMsg) at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)

at KTI_Loc8References.AssetsService.AssetsPort.saveAsset(saveAssetRequest1 request) at

KTI_Loc8References.AssetsService.AssetsPortClient.KTI_Loc8References.AssetsService.AssetsPort.saveAsset

(saveAssetRequest1 request) at KTI_Loc8References.AssetsService.AssetsPortClient.saveAsset(saveAssetRequest

saveAssetRequest) — End of inner exception stack trace — at System.RuntimeMethodHandle.InvokeMethod(Object

target, Object[] arguments, Signature sig, Boolean constructor) at

System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) at

System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[]

parameters, CultureInfo culture) at Microsoft.Dynamics.AX.ManagedInterop.ClrBridgeImpl.InvokeClrInstanceMethod

(ClrBridgeImpl* , ObjectWrapper* objectWrapper, Char* pszMethodName, Int32 argsLength, ObjectWrapper** arguments,

Boolean* argsAreByRef, Boolean* isException)

Can you please tell me how to solve this issue…?

I already replied to the duplicate thread on another forum. This error is returned by the Java service you’re calling; it’s not originating from AX.