Oracle JD Edwards helps businesses manage core processes through a suite of integrated applications such as Human Capital Management, Financial Management, Order Management, Supply Management, Customer Relationship Management, and more. Ensuring strong performance of these tools is essential, as slowdowns or errors can directly impact daily value delivery.
This is where OCI Application Performance Monitoring (APM) comes in. APM instruments Java applications like Oracle JD Edwards to capture frontend-to-backend traces and pinpoint performance bottlenecks. While the default Java application monitoring is already powerful, you can enrich the trace data by capturing JD Edwards’ app, form, and error codes as well as translating them to meaningful names – e.g., capture the app code “P007032” and translate it into the more descriptive app name “Batches out of Balance”. This reduces the time needed to triage the performance bottlenecks found in APM traces by using terms specific to JD Edwards for a more meaningful context. You will know which exact JD Edwards applications and forms are impacted by the performance issues reported in APM. It allows management reporting to be created using JD Edwards terminology. In this blog, we will go through how to accomplish this.
There are three main steps:
- Prepare an APM domain. This contains all trace data collected by agents (click here for more).
- Deploy the APM agents—both the Java agent to collect backend data from servers and the JavaScript agent injected into web pages to capture frontend data from browsers. In this blog, we will manually inject some custom JavaScript code into webgui.js to capture JD Edwards’ app, form, and error codes.
- In OCI, enable APM’s built-in enrichment rule for mapping JD Edwards codes to names or descriptions.
Deploy APM Java agents and enable JD Edwards monitoring attributes
When the APM domain is created, you will need to download, provision, and deploy the APM Java agent on the JD Edwards WebLogic domain by following the documented steps provided (click here for more).
The Java agent will run on your WebLogic servers next time you restart JD Edwards. For the browser agent configurations, you will find the default browser agent JavaScript code at $DOMAIN_HOME/oracle-apm-agent/config/<version>/BrowserAgentTemplate.txt. First, make a copy of the template:
cp BrowserAgentTemplate.txt BrowserAgentTemplate.txt.orig
Now update BrowserAgentTemplate.txt, so it only contains the code below:
<script type="application/javascript"> document.apmrum = (document.apmrum || {}); document.apmrum.username='@@USER_NAME@@'; document.apmrum.trackPlainUserId='@@TRACK_PLAIN_USER_ID@@'; @@PROPAGATION_TYPE@@ @@GENERIC_ATTRIBUTES@@ </script>
Also, make sure to enable the automatic browser agent injection. You can do this in AgentConfig.properties in the same folder. Change the following properties as shown below:
com.oracle.apm.agent.rum.enable.injection=true com.oracle.apm.agent.public.data.key=<PUBLIC KEY FROM APM DOMAIN>
To capture the JD Edwards codes, you will also need to manually inject additional JavaScript into webgui.js (it should be located at $DOMAIN_HOME/servers/html_server/stage/html_inst/app/webclient.war/share/js). Make sure to back up the original version of webgui.js before making any changes:
cp webgui.js webgui.js.orig
At the bottom of webgui.js, insert the JavaScript code below. Remember to insert your APM domains’ data upload endpoint and public key. Also, remember to set an appropriate service name and web application name:
//Manual APM Browser Agent Injection for extracting JDE code attributes (function() { var apmScriptElement = document.createElement('script'); apmScriptElement.type = 'text/javascript'; apmScriptElement.async = true; apmScriptElement.src = '<DATA UPLOAD ENDPOINT FROM APM DOMAIN>/static/jslib/apmrum.min.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(apmScriptElement, s); })(); document.apmrum = (document.apmrum || {}); document.apmrum.serviceName='jde_ui'; document.apmrum.webApplication='JDE Web App'; document.apmrum.ociDataUploadEndpoint='<DATA UPLOAD ENDPOINT FROM APM DOMAIN>'; document.apmrum.OracleAPMPublicDataKey='<PUBLIC KEY FROM APM DOMAIN>'; //Gets app and form codes function getPaneFormNames() { const f=document.forms['E1PaneForm']; const fname = f ? f.name : ''; const fparts = fname.split('_'); return fparts } //Gets error code function getJDEErrorCodeForApm() { const inyfeContent = document.getElementById('INYFEContent'); const inyfeRows = inyfeContent ? inyfeContent.querySelector('[id^="DETAILID_0_"]').querySelectorAll('table tr') : ''; let errorId = ''; for (let i = 0; i < inyfeRows.length && errorId == ''; i++) { const row = inyfeRows[i]; const firstTd = typeof(row) == 'object' && typeof(row.querySelector) == 'function' ? row.querySelector('td:nth-child(1)') : ''; const firstTdTxt = typeof(firstTd) == 'object' && firstTd.textContent ? firstTd.textContent.trim() : ''; if (firstTdTxt == 'Error ID') { const secondTd = typeof(row) == 'object' && typeof(row.querySelector) == 'function' ? row.querySelector('td:nth-child(2)') : ''; errorId = typeof(secondTd) == 'object' && secondTd.textContent ? secondTd.textContent.trim() : ''; }; }; return errorId } //Sets code attributes for spans document.apmrum.udfAttributes = [ { name: 'JdeAppCode', value: ()=> { let fp = getPaneFormNames(); return Array.isArray(fp) && fp.length == 2 ? fp[0] : '' } }, { name: 'JdeFormCode', value: ()=> { let fp = getPaneFormNames(); return Array.isArray(fp) && fp.length == 2 ? fp[1] : '' } }, { name: 'JdeErrorCode', value: ()=> { return getJDEErrorCodeForApm() } } ]; //End of APM Browser Agent Injection
NOTE: You may need to add a record in JD Edwards’ Content Security Policy to allow connections to your data upload endpoint. Create a record (click here for more) with the following input for the Soft Coding Value field (the example below uses the more common “oci.oraclecloud.com” suffix. If your APM domain is in a more specific region, you need to change his to align with your data upload endpoint URL):
<allow_content_security_policy> <properties> <property><name>script-src</name><value>https://*.oci.oraclecloud.com</value></property> <property><name>connect-src</name><value>https://*.oci.oraclecloud.com</value></property> </properties> </allow_content_security_policy>
From now on, whenever a user interacts with JD Edwards, the app, form, and error codes will be captured as part of the trace data in APM.
Map JD Edwards codes to names with APM enrichment rules
APM enrichment rules modify your incoming trace data e.g., by adding new attributes. These rules can be configured from scratch. Thankfully, APM provides one for JD Edwards out of the box. You need to specify a filter query to determine which spans the enrichment rule will apply to. “JdeAppCode is not omitted” is a fitting query for this use case. In OCI, go to Observability & Management > Application Performance Monitoring > Administration. Select your APM domain and follow the steps shown below to prepare the JD Edwards enrichment rule:

The enrichment rule in the newly created group will look for JD Edwards code attributes in spans specified by the filter. Then the code values will be translated into names assigned as values to new JD Edwards attributes using lookup tables included in the Oracle-provided rule.
You might need to activate the new JD Edwards attributes before they become available in APM’s Trace Explorer. Under the APM domain administration page, go to Span attributes and check for active and inactive spans with the query filter “attribute_name ilike ‘%jde%’”. If any JD Edwards attributes are listed as inactivate, activate them with Type set to Dimension like shown below:

The APM Trace Explorer now shows which apps, forms, and errors are involved in your traces:

You can also create a dashboard like the example below:

Instrument the Oracle JD Edwards suite with OCI Application Performance Monitoring (APM) to capture app, form, and error codes. Enrich application traces with this additional context to identify performance bottlenecks found in APM and their impact on critical business functions managed via JD Edwards.