
Migrating E-Business Suite CEMLIs
In day-to-day EBS development, CEMLIs are what bridge the gap between standard functionality and real-world requirements. Whether it is a custom concurrent program, a modified workflow, a new lookup, or an integration with external systems, these objects need to be carefully managed and migrated across environments.

In Oracle E-Business Suite (EBS), custom extensions (CEMLIs) such as custom lookups, messages, concurrent programs, forms, menus, workflows or reports can be migrated from a development instance to production with FNDLOAD and WFLOAD utilities. FNDLOAD is a generic loader that “can move Oracle E-Business Suite data between database and text file representations”.
CEMLI : Configurations, Extensions, Modifications, Localizations, and Integrations and represents all custom and semi-custom components developed within Oracle E-Business Suite to meet specific business needs.
This post serves as a practical reference for moving CEMLI components from Development to Production using tools like FNDLOAD and WFLOAD, with real command examples you can reuse whenever needed.
WFLOAD is the analogous workflow loader. Both are run on the application tier as the APPS user. For example, FNDLOAD is located under $FND_TOP/bin on the app server (so you can simply run FNDLOAD if $FND_TOP is set). The basic syntax is:
FNDLOAD apps/<password> 0 Y [UPLOAD|DOWNLOAD] <configfile.lct> <outputfile.ldt> <ENTITY> [parameters]
where <configfile.lct> is the loader control file (provided by Oracle) and <outputfile.ldt> is the data file. (A synopsis of the syntax is provided in the Oracle Setup Guide.) In download mode, FNDLOAD exports definitions from the database into the LDT file; in upload mode, it reads an LDT file and creates or updates objects in the database. The examples below show typical FNDLOAD commands for various object types. In each case, replace the example names (such as XXHR_CUSTOM_MESSAGE) with your actual custom object names, and use UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE on upload to overwrite any existing customization.
FNDLOAD Examples
Lookup Types
- To migrate a custom lookup type (e.g. in Application Short Name
XXHR), use theaflvmlu.lctloader. For example, to download and then upload a custom lookup, you could run:
# Download custom lookup XXHR_CUSTOM_LOOKUP from the DB
FNDLOAD APPS/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/aflvmlu.lct lookup.ldt FND_LOOKUP_TYPE APPLICATION_SHORT_NAME="XXHR" LOOKUP_TYPE="XXHR_CUSTOM_LOOKUP"
# Upload that lookup into another instance
FNDLOAD APPS/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/aflvmlu.lct lookup.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE
Messages
- To move custom seeded or custom messages, use
afmdmsg.lct. For example:
# Download a custom message XXHR_CUSTOM_MESSAGE
FNDLOAD APPS/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afmdmsg.lct XX_CUSTOM_MESSAGE.ldt FND_NEW_MESSAGES APPLICATION_SHORT_NAME="XX" MESSAGE_NAME="XXHR_CUSTOM_MESSAGE"
# Upload the message LDT to production
FNDLOAD APPS/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/afmdmsg.lct XX_CUSTOM_MESSAGE.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE
In the example above, replace XX_CUSTOM_MESSAGE with the actual message name. Note that if your instance is multi-language, you should download/upload all language variants of the message.
Value Sets
- To move custom value sets, use
afffload.lct. For example:
# Download
$FND_TOP/bin/FNDLOAD apps/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afffload.lct XX_CUST_VS.ldt VALUE_SET FLEX_VALUE_SET_NAME="XX_Cust_VS";
# Upload the message LDT to production
$FND_TOP/bin/FNDLOAD apps/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/afffload.lct XX_CUST_VS.ldt - WARNING=YES UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE;
Value Sets with values
- Again, use
. For example:afffload.lct
# Download
$FND_TOP/bin/FNDLOAD apps/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afffload.lct XX_CUST_VS.ldt VALUE_SET_VALUE FLEX_VALUE_SET_NAME="XX_Cust_VS";
# Upload
$FND_TOP/bin/FNDLOAD apps/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/afffload.lct XX_CUST_VS.ldt - WARNING=YES UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE;
Concurrent Programs
- For custom concurrent programs, use
afcpprog.lct. Example
# Download a custom concurrent program XXHR_CONC_PROGRAM
FNDLOAD APPS/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afcpprog.lct prog.ldt PROGRAM APPLICATION_SHORT_NAME="XXHR" CONCURRENT_PROGRAM_NAME="XXHR_CONC_PROGRAM"
# Upload the concurrent program definition
FNDLOAD APPS/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/afcpprog.lct prog.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE
Form Functions
- To migrate custom form functions (FND_FORM_FUNCTIONS), use
afsload.lct. For instance:
# Download a custom form function XXHR_CUSTOM_FUNC
FNDLOAD APPS/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afsload.lct func.ldt FUNCTION FUNC_APP_SHORT_NAME="XXHR" FUNCTION_NAME="XXHR_CUSTOM_FUNC"
# Upload the function
FNDLOAD APPS/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/afsload.lct func.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE
WebADI – Web Desktop Integrator
- To migrate custom integrator, use
bneintegrator.lct. For instance:
# Download
FNDLOAD apps/appspwd 0 Y DOWNLOAD $BNE_TOP/patch/115/import/bneintegrator.lct XX_INTEGRATOR.ldt BNE_INTEGRATORS INTEGRATOR_ASN="XX" INTEGRATOR_CODE="XX_INTEGRATOR";
# Upload
FNDLOAD apps/appspwd 0 Y UPLOAD $BNE_TOP/patch/115/import/bneintegrator.lct XX_INTEGRATOR.ldt CUSTOM_MODE=FORCE UPLOAD_MODE=REPLACE;
Menus
- Custom menus use the same
afsload.lctfile. Example:
# Download a menu XXHR_CUSTOM_MENU
FNDLOAD APPS/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afsload.lct menu.ldt MENU MENU_NAME="XXHR_CUSTOM_MENU"
# Upload the menu
FNDLOAD APPS/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/afsload.lct menu.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE
Note that downloading a menu will also download its contained form functions. The upload will recreate the menu (and by extension all its functions) in the target instance
To download only one function (to be later added to existing menu) use following download FNDLOAD functionality:
# Download only one function in a menu
FNDLOAD apps/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afsload.lct CUST_MENU_FUNC.ldt MENU PARENT_MENU_NAME="XX_SOME_CUST_MENU" FUNCTION_NAME="XX_CUST_FUNC"
Responsibilities
- To migrate a custom responsibility, use
afscursp.lct. Example:
# Download a responsibility with RESP_KEY='XXHR_RESP_KEY'
FNDLOAD APPS/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afscursp.lct resp.ldt FND_RESPONSIBILITY RESP_KEY="XXHR_RESP_KEY"
# Upload the responsibility
FNDLOAD APPS/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/afscursp.lct resp.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE
Make sure the responsibility key matches the custom one.
Request Set
- To migrate a custom request set, use
afcprset.lct. Example:
# Download
FNDLOAD apps/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afcprset.lct XX_REQ_SET.ldt REQ_SET REQUEST_SET_NAME='XX - Cust Req Set';
# Upload
FNDLOAD apps/apps_pwd O Y UPLOAD $FND_TOP/patch/115/import/afcprset.lct XX_REQ_SET.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE;
Request Group
- To migrate a custom request group, use
afcpreqg.lct. Example:
# Download
FNDLOAD apps/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afcpreqg.lct XX_REQ_GRP.ldt REQUEST_GROUP REQUEST_GROUP_NAME="XX - Cust Request Group" APPLICATION_SHORT_NAME="XX";
# Upload
FNDLOAD apps/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/afcpreqg.lct XX_REQ_GRP.ldt CUSTOM_MODE=FORCE UPLOAD_MODE=REPLACE;
Profile Options
- Custom profile values (if needed) can be migrated with
afscprof.lct. For example:
# Download a custom profile option (replace NAME and APP)
FNDLOAD APPS/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afscprof.lct profile.ldt PROFILE PROFILE_NAME="XX:Custom Profile" APPLICATION_SHORT_NAME="XX"
# Upload that profile file
FNDLOAD APPS/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/afscprof.lct profile.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE
Form Personalizations
- Custom FND form personalizations use
affrmcus.lct. For example:
# Download personalizations for form $fnd_form_name
FNDLOAD APPS/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/affrmcus.lct pers.ldt FND_FORM_CUSTOM_RULES FUNCTION_NAME="XX_CUST_FUNC"
# Upload them
FNDLOAD APPS/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/affrmcus.lct pers.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE
Descriptive Flexfields
- If migrating DFF configurations, use
afffload.lct. For example:
# Download a DFF named "MY DFF" in custom app XXHR
FNDLOAD APPS/apps_pwd 0 Y DOWNLOAD $FND_TOP/patch/115/import/afffload.lct dff.ldt DESC_FLEX APPLICATION_SHORT_NAME=XX DESCRIPTIVE_FLEXFIELD_NAME="XXDFF"
# Upload it
FNDLOAD APPS/apps_pwd 0 Y UPLOAD $FND_TOP/patch/115/import/afffload.lct dff.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE
Alerts
- For custom alerts (ALR_ALERTS), use
alr.lct. Example:
# Download a custom alert named "Custom Alert"
FNDLOAD APPS/apps_pwd 0 Y DOWNLOAD $ALR_TOP/patch/115/import/alr.lct alert.ldt ALR_ALERTS APPLICATION_SHORT_NAME="XXHR" ALERT_NAME="Custom Alert"
# Upload the alert
FNDLOAD APPS/apps_pwd 0 Y UPLOAD $ALR_TOP/patch/115/import/alr.lct alert.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE
XMLP
- Custom XML Publisher data definitions (the metadata, not the template file) use
xdotmpl.lctunder$XDO_TOP. For instance:
# Download all data definitions for AR (Accounts Receivable)
FNDLOAD APPS/apps_pwd 0 Y DOWNLOAD $XDO_TOP/patch/115/import/xdotmpl.lct data_defs.ldt XDO_DS_DEFINITIONS APPLICATION_SHORT_NAME=XX
# Upload in production
FNDLOAD APPS/apps_pwd 0 Y UPLOAD $XDO_TOP/patch/115/import/xdotmpl.lct data_defs.ldt UPLOAD_MODE=REPLACE CUSTOM_MODE=FORCE
You can also specify DATA_SOURCE_CODE= or TEMPLATE_CODE= to narrow the download to specific definitions/templates as needed.
# Download
FNDLOAD apps/apps_pwd 0 Y DOWNLOAD $XDO_TOP/patch/115/import/xdotmpl.lct XX_CUST_DD.ldt XDO_DS_DEFINITIONS APPLICATION_SHORT_NAME='XX' DATA_SOURCE_CODE='XX_CUST_DD_CODE' TMPL_APP_SHORT_NAME='XX' TEMPLATE_CODE='XX_CUST_DT_CODE';
# Upload
FNDLOAD apps/apps_pwd 0 Y UPLOAD ${XDO_TOP}/patch/115/import/xdotmpl.lct XX_CUST_DD.ldt;
Downloading and uploading DATA_TEMPLATE (Data Source .xml file)
# Download
java oracle.apps.xdo.oa.util.XDOLoader DOWNLOAD
-DB_USERNAME apps
-DB_PASSWORD appspwd
-JDBC_CONNECTION '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST='XX_HOST_NAME')(PORT=XX_PORT_NUMBER))(CONNECT_DATA=(SERVICE_NAME=XX_SERV_NAME)))'
-LOB_TYPE DATA_TEMPLATE
-LOB_CODE XX_TEMPLATE
-APPS_SHORT_NAME XX
-LANGUAGE en
-lct_FILE $XDO_TOP/patch/115/import/xdotmpl.lct
-LOG_FILE $LOG_FILE_NAME;
# Upload
java oracle.apps.xdo.oa.util.XDOLoader UPLOAD
-DB_USERNAME apps
-DB_PASSWORD appspwd
-JDBC_CONNECTION '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST='XX_HOST_NAME')(PORT=XX_PORT_NUMBER))(CONNECT_DATA=(SERVICE_NAME=XX_SERV_NAME)))'
-LOB_TYPE DATA_TEMPLATE
-APPS_SHORT_NAME XX
-LOB_CODE XX_TEMPLATE
-NLS_LANG en
-TERRITORY 00
-XDO_FILE_TYPE XML-DATA-TEMPLATE
-FILE_NAME DATA_TEMPLATE_XX_TEMPLATE.xml
-CUSTOM_MODE FORCE
-LOG_FILE $LOG_FILE_NAME;
Downloading and uploading RTF TEMPLATE (.rtf file)
# Download
java oracle.apps.xdo.oa.util.XDOLoader DOWNLOAD
-DB_USERNAME apps
-DB_PASSWORD appspwd
-JDBC_CONNECTION '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST='XX_HOST_NAME')(PORT=XX_PORT_NUMBER))(CONNECT_DATA=(SERVICE_NAME=XX_SERV_NAME)))'
-LOB_TYPE TEMPLATE
-LOB_CODE XX_TEMPLATE
-APPS_SHORT_NAME XX
-LANGUAGE en
-TERRITORY 00
-lct_FILE $XDO_TOP/patch/115/import/xdotmpl.lct
-LOG_FILE $LOG_FILE_NAME;
# Upload
java oracle.apps.xdo.oa.util.XDOLoader UPLOAD
-DB_USERNAME apps
-DB_PASSWORD appspwd
-JDBC_CONNECTION '(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST='XX_HOST_NAME')(PORT=XX_PORT_NUMBER))(CONNECT_DATA=(SERVICE_NAME=XX_SERV_NAME)))'
-LOB_TYPE TEMPLATE
-APPS_SHORT_NAME XX
-LOB_CODE XX_TEMPLATE
-LANGUAGE en
-TERRITORY 00
-XDO_FILE_TYPE RTF
-FILE_NAME TEMPLATE_SOURCE_XX_TEMPLATE.rtf
-CUSTOM_MODE FORCE -LOG_FILE $LOG_FILE_NAME;
Of course, if you used some other type of template (for example Excel xls, you would specify that in your script)
Considerations
- Each of the above examples assumes the LCT files live under
patch/115/import(they do in 12.2.10) and that you run FNDLOAD from the application tier as the APPS schema. Always test the download commands first to ensure the.ldtfiles contain the expected definitions (open them in some text editor), and then transfer those files to the target instance for uploading.
Workflow Migration with WFLOAD
For custom Oracle Workflow definitions (processes, notifications, etc.), use the Workflow Definitions Loader (WFLOAD). Unlike FNDLOAD, WFLOAD handles workflows in bulk. WFLOAD is invoked similarly, for example:
# Download all workflow definitions
WFLOAD APPS/apps_pwd 0 Y DOWNLOAD cust_workflow.wft XX_CUST_WFT
# Upload or force into target instance
WFLOAD APPS/apps_pwd 0 Y UPLOAD cust_workflow.wft
The generic WFLOAD command syntax is:
- To download definitions:
WFLOAD apps/<pwd> 0 Y DOWNLOAD <file.wft> <ITEM_TYPE1> [<ITEM_TYPE2> ...] - To upload from a
.wftfile:WFLOAD apps/<pwd> 0 Y UPLOAD <file.wft> - To upgrade/force an upload (overwriting protected objects):
WFLOAD apps/<pwd> 0 Y UPGRADE <file.wft>orWFLOAD apps/<pwd> 0 Y FORCE <file.wft>.
For example, to download all workflow definitions into workflows_all.wft, you can use WFLOAD APPS/apps_pwd 0 Y DOWNLOAD workflows_all.wft '*' (the asterisk in single quotes means all item types). To upload that file in production, use WFLOAD APPS/apps_pwd 0 Y UPLOAD workflows_all.wft. These commands are documented in Oracle’s online help.
Note: WFLOAD operates on workflow repository definitions (WF_ITEM_TYPES, WF_PROCESSES, WF_NOTIFICATIONS, etc.) and is separate from FNDLOAD. Typically you first download the workflows (to capture any custom workflow), then upload or upgrade in the target system to restore the processes there.
That’s it for this blog, if you liked it, feel free to join the newsletter for other cool content.
