The purpose of this document is to provide a troubleshooting guide to a commonly encountered business function error, "JDB9900600 - Failed to store value, maximum exceeded. Probable cause is forgetting to call jdeRemoveDataPtr()", which is due to data pointers usage in a business function. This document guides user on how to debug this type of data pointer related issues which causes an EnterpriseOne application to malfunction. It provides some case study examples and detail troubleshooting steps to help resolve this type of data pointer issues.
This error is platform independent and when you encounter this error in the jde.log (see example below) when running an application, first find out which is the offending business function.
29424/6 WRK:10007140_009560B8_P43081 Mon Jul 20 hh:mm:ss.032907 jdb_utl1.c2644
JDB9900600 - Failed to store value, maximum exceeded. Probable cause is forgetting to call jdeRemoveDataPtr()
To find out which is the offending business function and the general troubleshooting method, you can perform the steps below:
[DEBUG]
Output=FILE
DataPointerTracing=1
Note: do not turn on CMTrace=1 which traces Cache Manager.
When troubleshooting Data Pointers Leaked errors like JDB9900600, JDB4100005 and JDB4100006, you can set DataPointerTracing=TRUE or 1 and Output=FILE in the [DEBUG] section of the JDE.INI. You can also set logDPLeaksAtSignoff=TRUE in the [DEBUG] section of the JDE.INI and look for JDB4100006 error messages. This message (JDB4100005) will only appear with debug tools code or when debug logging is turned on.
DataPointerTracing is a setting in the jde.ini which logs when a business function store, access, remove a pointer to the DataPointer Array
Turning this setting on will not cause any performance improvement - it can however help application developers debug and make sure a business function is well coded so that it releases as many slots of DataPointer as it creates. This setting will put extra information in the logs for data pointer APIs executed by C BSFNs. This is helpful when trying to find a memory leak in relation to the following error message in the jde.log.
"JDB9900600 - Failed to store value, maximum exceeded." Probable cause is forgetting to call jdeRemoveDataPtr().
Examples:
DP - Stored data pointer (0BEB4C20), pointer handle (1)
DP - Removed data pointer (0BEB4C20), pointer handle (1)
Example:
or,
When clicking the Find button in the application P43081(Purchase Order Approvals) multiple times, it issues multiple errors like No Memory, Null Pointer and so on with JDB9900600 - Failed to store value, maximum exceeded. Probable cause is forgetting to call jdeRemoveDataPtr() message in JDE.log.
------------------------------- 1. Get Purchase Order Header Information -------------------------------
1. ENTER: GetPurchaseOrderHeader
DP - Stored data pointer (35C399F8), pointer handle (121)
1. EXIT: for GetPurchaseOrderHeader=0
1. ENTER: ReturnPOHeaderInformation
DP - Retrieved data pointer (35C399F8), pointer handle (121)
1. EXIT: for ReturnPOHeaderInformation=0
1. ENTER: FreePtrToDataStructure
DP - Removed data pointer (35C399F8), pointer handle (121)
1. EXIT: for FreePtrToDataStructure=0
------------------------------- 2. Get Purchase Order Detail Information -------------------------------
1. ENTER: RetrievePODetailRows
DP - Stored data pointer (35E19F20), pointer handle (121)
1. EXIT: for RetrievePODetailRows=0
1. ENTER: ClosePODetailRowsHandle
DP - Removed data pointer (35E19F20), pointer handle (121)
1. EXIT: for ClosePODetailRowsHandle=0
------------------------------- 3. Get Address Book Information -------------------------------
1. ENTER: GetAddressBookData
DP - Stored data pointer (3628D570), pointer handle (121)
1. EXIT: for GetAddressBookData=0
In case you need to know exact event, capture jasdebug.log and get it from it.
------------------------------- 1. Get Purchase Order Header Information -------------------------------
F4301 Get Purchase Order Header Row (GetPurchaseOrderHeader, B4300130)
GC Order Co -> BF szDocumentCompany
GC Order Number -> BF mnDocumentNumber
GC Or Ty -> BF szDocumentType
"1" -> BF cCallType
"1" -> BF cReturnF4301PtrFlag /* This parameter determines whether to return data pointer or not */
FC GENLNG-Pointer to F4301 (wf) <> BF idF4301RowPtr /* Returned Data Pointer is to be used by next business function B4300190 */
FC DTAI:Error Message (wf) <- BF szErrorMessageID
"1" -> BF cSuppressErrorMessage
Code Example:
lpdsF4301 = (LPF4301)jdeAlloc(COMMON_POOL,sizeof(F4301),MEM_ZEROINIT) ; /* allocate memory at COMMON_POOL */
if ( lpdsF4301 != (LPF4301)NULL) /* To avoid ACCESS VIOLATION */
{
memcpy ((void *)(lpdsF4301), (const void *)(&dsF4301Fetch), sizeof(F4301) ) ; /* Memory Copy */
lpDS->idF4301RowPtr = jdeStoreDataPtr(hUser,(void *)lpdsF4301); /* Call API jdeStoreDataPtr) and return it */
}
F4301 Get Addresses, Currency and Ordered By (ReturnPOHeaderInformation, B4300190)
FC GENLNG-Pointer to F4301 (wf) -> BF idPointerToF4301DS /* Data Pointer returned by B4300130 is used */
GC Hd CD <- BF szOrderHoldCode
GC Order Status(wf) <- BF cPurchaseOrderStatus
Code Example:
lpdsF4301 = (LPF4301) jdeRetrieveDataPtr(hUser,lpDS->idPointerToF4301DS); /* API jdeRetrieveDataPtr() is used to retrive data pointer stored at COMMON_POOL */
if ( lpdsF4301 != (LPF4301) NULL) /* To avoid Access Violation */
{
/* Break In Code */
jdeStrcpy( (JCHAR*)lpDS->szOrderHoldCode, (const JCHAR *)(lpdsF4301->phhold) ); /* memory copy to get a specific column value */
/* Break In Code */
}
Memory, Free Ptr To Data Structure (FreePtrToDataStructure, B4000460)
FC GENLNG-Pointer to F4301 (wf) <> BF idGenericLong
Code Example:
if (lpDS->idGenericLong != (ID) 0) /* Not NULL */
{
lpGenericPtr = (void *)jdeRemoveDataPtr(hUser,lpDS->idGenericLong); /* JDE API jdeRemoveDataPtr() is called to remove data pointer */
if (lpGenericPtr != (void *) NULL)
{
jdeFree((void *)lpGenericPtr); /* to release memory */
lpDS->idGenericLong = (ID) 0;
}
}
------------------------------- 2. Get Purchase Order Detail Information -------------------------------
F4311 Get Item, Status, Amounts (RetrievePODetailRows, B4300520)
GC Order Number -> BF mnOrderNumber
GC Or Ty -> BF szOrderType
GC Order Co -> BF szOrderKeyCompany
FC GENLN2-Pointer to F4311 Handle <- BF idhRequestF4311
VA evt_StatusCodeNext_NXTR <- BF szStatusCodeNext
Code Example:
lpDS->idhRequestF4311 = (ID)jdeStoreDataPtr(hUser, (void *)(hRequest)); /* Pointer is returned to lpDS */
/* This business function will read the Purchase Order Detail table F4311 by the specified keys and return data from the table. */
Close PODetailRows Handle (ClosePODetailRowsHandle, B4300520)
FC GENLN2-Pointer to F4311 Handle <> BF idhRequestF4311 /* To close out the pointer returned by RetrievePODetailRows */
Code Example:
if ( lpDS->idhRequestF4311 != (ID) 0 ) /* when handle is NOT NULL */
{
hRequestF4311 = (HREQUEST)jdeRemoveDataPtr(hUser, lpDS->idhRequestF4311); /* Call JDE API jdeRemoveDataPtr() */
lpDS->idhRequestF4311 = (ID) 0; /* Set handle NULL */
}
------------------------------- 3. Get Address Book Information -------------------------------
Get Address Book Data (GetAddressBookData, B0101201)
GC Supplier Address Number -> BF mnAddressNumber
GC Supplier Name <- BF szNameMailing
Code Example:
lpdsD0101201c = (LPDSD0101201C)jdeAlloc(COMMON_POOL,sizeof(DSD0101201C),MEM_ZEROINIT); /* Allocate Memory at COMMON_POOL - Global Memory Area */
if (lpdsD0101201c) /* if memory is allocated then */
{
I0101201_SaveF0101Values(lpdsD0100041,lpdsD0101201c); /* Move All A/B values to dsD0100041*/
lpdsD0101201c->idF0101Ptr= (ID) jdeStoreDataPtr (lpdsUserEnv->hUser, (void *) lpdsD0101201c); /* JDE API jdeStoreDataPtr () gets called and returned through it is not used at all */
lpDS->idF0101Ptr= lpdsD0101201c->idF0101Ptr; /* this is integer value so direct copy */
}
For easier reading, some values are not shown.
For this example, the purpose of calling business function GetAddressBookData is to get mailing name of supplier in Grid. Therefore, possible fix to this issue can be,
As this example provided here occurs on the standard application P43081 and its related business functions, a bug has been reported for this issue. Please see Bug 21527282 - P43081 LEAVES DATA POINTER AFTER CALLING GETADDRESSBOOKDATA (B0101201). Check Bug 21527282 for the latest ESU information once it becomes available.
In completing work order through PF31011 (thin manufacturing, Ad-hoc completion), application issues error
---------------------------------- 1. Read Item Branch (F4102) --------------------------------------------------
1. ENTER: CheckItemBranch
DP - Stored data pointer (07FA00F0), pointer handle (991)
1. EXIT: for CheckItemBranch=0
1. ENTER: GetItemBranchInfo
DP - Retrieved data pointer (07FA00F0), pointer handle (991)
1. EXIT: for GetItemBranchInfo=0
1. ENTER: FreePtrToDataStructure
DP - Removed data pointer (07FA00F0), pointer handle (991)
1. EXIT: for FreePtrToDataStructure=0
----------------------------------- 2. Read F41021 -------------------------------------------------
1. ENTER: VerifyAndGetItemLocation
DP - Stored data pointer (07F8F018), pointer handle (991) *** The data pointer stored by this function never gets deleted ***
1. EXIT: for VerifyAndGetItemLocation=0
1. ENTER: GetItemLocationDetail
DP - Retrieved data pointer (07F8F018), pointer handle (991)
1. EXIT: for GetItemLocationDetail=0
----------------------------------- 3. Format Location -------------------------------------------------
1. ENTER: FormatLocation
2. ENTER: VerifyAndGetBranchPlantConstants
DP - Stored data pointer (2DD4EBC0), pointer handle (992)
2. EXIT: for VerifyAndGetBranchPlantConstants=0
DP - Removed data pointer (2DD4EBC0), pointer handle (992)
2. ENTER: CheckLocationMaster
2. EXIT: for CheckLocationMaster=0
1. EXIT: for FormatLocation=0
In case you need to know exact event, capture jasdebug.log and get it from it.
---------------------------------- 1. Read Item Branch (F4102) --------------------------------------------------
F4102 Get Item Branch Row (CheckItemBranch, B4100210)
FC Branch -> BF szBranchPlant
FC Short Item Number -> BF mnShortItemNumber
"1" -> BF mnIndex
"2" -> BF mnKeys
"1" -> BF cCallType
"1" -> BF cReturnRecord /* parmeter determines whether to return data pointer (in the log it is handle) or not */
VA evt_idF4102RowPointerGenlng <- BF idItemBranchRecord
Code Example:
if ( lpDS->cReturnRecord == _J('1') ) /* when input parameter cReturnRecord is '1', then */
{
lpdsF4102Record = (LPF4102) jdeAlloc(COMMON_POOL, sizeof(F4102), MEM_ZEROINIT ) ; /* Allocate memory for F4102 data */
memcpy ( (void *)(lpdsF4102Record), (const void *)(&dsF4102Fetch), sizeof(F4102) ) ; /* Copy data into memory */
lpDS->idItemBranchRecord = (ID)jdeStoreDataPtr(hUser, (void *)lpdsF4102Record); /* Store data pointer */
}
F4102 Get Grade, Potency and Quantities (GetItemBranchInfo, B4100310)
VA evt_idF4102RowPointerGenlng -> BF idF4102RowPointer
VA evt_LayerCodeSource_SRCE <- BF cLotProcessType
VA frm_CountryOfOriginRequired <- BF cCountryOfOriginRequired
Code Example:
lpF4102 = (LPF4102) jdeRetrieveDataPtr(hUser,lpDS->idF4102RowPointer); /* To retrive data pointer stored by B4100210 */
if (lpF4102 != (LPF4102) NULL )
{
/* Break In Code */
lpDS->cLotProcessType = lpF4102->ibsrce ;
jdeStrcpy((JCHAR *)lpDS->szCountryOfOrigin, (const JCHAR *)lpF4102->iborig);
}
Memory, Free Ptr To Data Structure (FreePtrToDataStructure, B4000460) /* Generic function to remove data pointer */
VA evt_idF4102RowPointerGenlng -> BF idGenericLong
----------------------------------- 2. Read F41021 -------------------------------------------------
F41021 Get Item Location Row (VerifyAndGetItemLocation, XF41021)
FC Branch -> BF szBranchPlant
FC Short Item Number -> BF mnShortItemNumber
FC Completed to Location -> BF szLocation
FC Lot/SN -> BF szLotNumber
"4" -> BF mnIndex
"3" -> BF mnKeys
"1" -> BF cCallType
"1" -> BF cReturnRecord /* Input parameter whether to return data pointer or not */
VA frm_idF41021PtrRecord_GENLNG <- BF idItemLocationRecord
VA frm_cErrorCode <> BF cSuppressErrorMessages
VA frm_szErrorMessageID <> BF szErrorMessageID
Code Example:
if ( lpDS->cReturnRecord == _J('1') ) /* Only when input parameter cReturnRecord is '1', then */
{
lpdsF41021Record = (LPF41021) jdeAlloc ( COMMON_POOL, sizeof(F41021), MEM_ZEROINIT ) ; /* allocate memory */
memcpy ( (void *)(lpdsF41021Record), (const void *)(&dsF41021), sizeof(F41021) ) ; /* Copy data into memory allocated */
lpDS->idItemLocationRecord = (ID) jdeStoreDataPtr ( hUser, (void *) lpdsF41021Record); /* Store and return */
}
F41021 Get Item Location Quantities (GetItemLocationDetail, B4100280)
VA frm_idF41021PtrRecord_GENLNG -> BF idF41021Pointer
"1" -> BF cSuppressErrorMessages
VA frm_szComptoLocation_COLOCN <- BF szLocation /* This is the purpose of calling B4100280 */
Code Example:
memset((void *)(&lpdsF41021), (int)(_J('\0')), sizeof(LPF41021) ); /* Initialize memory */
if( lpDS->idF41021Pointer != (ID) 0 )
{
lpdsF41021 = (LPF41021) jdeRetrieveDataPtr(hUser,lpDS->idF41021Pointer);
/* Break In Code */
jdeStrcpy((JCHAR *)(lpDS->szLocation), (const JCHAR *)(lpdsF41021->lilocn)); /* copy memory for LOCN */
}
----------------------------------- 3. Format Location -------------------------------------------------
F4100 Format Location (FormatLocation, B4000310)
FC Branch -> BF szCostCenter
FC Completed to Location <> BF szDisplayFormatLocation
VA frm_szComptoLocation_COLOCN <> BF szFileFormatLocation
"3" -> BF cValidate
"1" -> BF cMode
Code example:
if ( lpDS->idBranchConstantRecord <= (ID) 0 ) /* when handle for idBranchConstantRecord is not specified as input value */
{
memset((void *)(&dsBranchConst), (int)(_J('\0')), sizeof(DSD4101390A)); /* initilalize data structure */
dsBranchConst.cReturnPointer = _J('1'); /* to return data pointer of F41001 */
dsBranchConst.idF41001Pointer = (ID) 0 ; /* Initialize data pointer handle */
dsBranchConst.cSuppressErrorMessage = _J('1') ; /* Not to have hard error */
idReturnCode = jdeCallObject (_J("VerifyAndGetBranchPlantConstants"), /* Get Branch Constants retreives the record that contains the Size of Asile Bin Etc. and if it is Right or left justified */
NULL ,
lpBhvrCom,lpVoid, &dsBranchConst,
(CALLMAP *) NULL, (int) 0, (JCHAR *) NULL,
(JCHAR *) NULL, (int) 0);
if ( dsBranchConst.idF41001Pointer > (ID) 0 && idReturnCode == ER_SUCCESS ) /* When data pointer handle is returned by calling business function */
{
lpdsF41001 = (LPF41001) jdeRemoveDataPtr ( hUser, (unsigned long) dsBranchConst.idF41001Pointer) ; /* jdeStoreDataPtr () is handled in called business function VerifyAndGetBranchPlantConstants */
}
}
else
{
lpdsF41001 = (LPF41001) jdeRetrieveDataPtr ( hUser, (unsigned long) lpDS->idBranchConstantRecord) ; /* because data pointer reside at COMMON_POOL in case VerifyAndGetBranchPlantConstants is called before B4000310 gets called */
}
For easier reading, some values are ripped off.
Calling Business function CheckItemBranch from Level 1 for JDE. Application Name [PF31011], Version [ZJDE0001] (BSFNLevel = 1)
IN->[ 1] szBranchPlant [ M30]
IN->[ 2] mnShortItemNumber [82571]
IN->[ 3] mnIndex [1]
IN->[ 4] mnKeys [2]
IN->[ 5] cCallType [1]
IN->[ 6] cReturnRecord [1]
IN->[ 7] cErrorCode [ ]
IN->[ 8] idItemBranchRecord [0]
SELECT * FROM CRPDTA.F4102 WHERE ( IBMCU = ' M30' AND IBITM = 82571.000000 )
DP - Stored data pointer (07FA00F0), pointer handle (991)
OUT->[ 1] szBranchPlant [ M30]
OUT->[ 2] mnShortItemNumber [82571]
OUT->[ 3] mnIndex [1]
OUT->[ 4] mnKeys [2]
OUT->[ 5] cCallType [1]
OUT->[ 6] cReturnRecord [1]
OUT->[ 7] cErrorCode [0]
OUT->[ 8] idItemBranchRecord [991]
Return value is 0 for CheckItemBranch. (BSFNLevel = 1)
Calling Business function GetItemBranchInfo from Level 1 for JDE. Application Name [PF31011], Version [ZJDE0001] (BSFNLevel = 1)
IN->[ 1] idF4102RowPointer [991]
...
DP - Retrieved data pointer (07FA00F0), pointer handle (991)
OUT->[ 1] idF4102RowPointer [991]
...
Return value is 0 for GetItemBranchInfo. (BSFNLevel = 1)
Calling Business function FreePtrToDataStructure from Level 1 for JDE. Application Name [PF31011], Version [ZJDE0001] (BSFNLevel = 1)
IN->[ 1] idGenericLong [991]
DP - Removed data pointer (07FA00F0), pointer handle (991)
OUT->[ 1] idGenericLong [0]
Return value is 0 for FreePtrToDataStructure. (BSFNLevel = 1)
Calling Business function VerifyAndGetItemLocation from Level 1 for JDE. Application Name [PF31011], Version [ZJDE0001] (BSFNLevel = 1)
IN->[ 1] szBranchPlant [ M30]
IN->[ 2] mnShortItemNumber [82571]
IN->[ 3] szLocation [ ]
IN->[ 4] szLotNumber [ ]
IN->[ 5] mnIndex [4]
IN->[ 6] mnKeys [3]
IN->[ 7] cCallType [1]
IN->[ 8] cReturnRecord [1]
IN->[ 9] idItemLocationRecord [0]
IN->[ 10] cSuppressErrorMessages [0]
...
SELECT * FROM CRPDTA.F41021 WHERE ( LIITM = 82571.000000 AND LIMCU = ' M30' AND LIPBIN = 'P' )
DP - Stored data pointer (07F8F018), pointer handle (991)
OUT->[ 1] szBranchPlant [ M30]
OUT->[ 2] mnShortItemNumber [82571]
OUT->[ 3] szLocation [11LLH06 ]
OUT->[ 4] szLotNumber [ ]
OUT->[ 5] mnIndex [4]
OUT->[ 6] mnKeys [3]
OUT->[ 7] cCallType [1]
OUT->[ 8] cReturnRecord [1]
OUT->[ 9] idItemLocationRecord [991]
OUT->[ 10] cSuppressErrorMessages [0]
...
Return value is 0 for VerifyAndGetItemLocation. (BSFNLevel = 1)
Calling Business function GetItemLocationDetail from Level 1 for JDE. Application Name [PF31011], Version [ZJDE0001] (BSFNLevel = 1)
IN->[ 1] idF41021Pointer [991]
...
DP - Retrieved data pointer (07F8F018), pointer handle (991)
OUT->[ 1] idF41021Pointer [991]
...
Return value is 0 for GetItemLocationDetail. (BSFNLevel = 1)
For this example, data pointer created by business function VerifyAndGetItemLocation is not removed. To resolve this issue, a possible fix is to call FreePtrToDataStructure to remove the data pointer.
As this example provided here occurs on the standard application PF31011 and its related business functions, a bug has been reported for this issue. Please see Bug 21535726 - MEMORY LEAK IN PF31011 (JDB9900600 - FAILED TO STORE VALUE, MAXIMUM EXCEEDED). Check Bug 21535726 for the latest ESU information once it becomes available.