JNDI usage in ADF Application Module for Data base connectivity
Open the AM in jdeveloper -> Configuration tab. Edit the existing AM Configuration.
JDBC URL -> In this type of connection, the end point information is directly hard coded on the source code [DB details like host:port:sid and DB credentials like username/password] and is generally picked up from connections.xml. This isn’t ideal – reason being, every change in DB connection requires application redeployment which isn’t a good idea. Or if I want to deploy same code [EAR] to multiple environments like Dev, QA 1, QA 2 each having its own DB, every time I need to change the DB details on my code and generate EAR and deploy. JDBC Data Source -> This works based on JNDI names. JNDI names are unique names that we use in our code and is configured in WLS. At runtime, java code looks for a mapping registration of that name on the deployed server and once it finds it, it uses the corresponding end points registered there. For eg, in weblogic, register a data source called AdfAppDB with JNDI name as “jdbc/AdfAppDBDS”. Make the application Module configuration use this JNDI name – hence no data base connection credentials/end point info is hardcoded in the source code. Every environment will have its own DB configured which will be looked up at runtime dynamically by ADF using JNDI mapping and respective DB end point would be resolved.
Now the way ADF uses the JDBC data source would be interesting. If I provide the exact JNDI name as the data source JNDI “jdbc/AdfAppDBDS” as given in above example, things will not work since ADF has its own JNDI parsing mechanism for data source lookups. I will try to explain the behavior in which ADF would parse the JNDI connection for AM DB configuration and resolve it to right value at runtime.
Defining the data source in weblogic:
To defining a data source in weblogic, navigate to Weblogic console -> Services -> Data source. Create a new data source with name “AdfAppDB” and JNDI name as “jdbc/demo/AdfAppDBDS”. Make sure you test the connection and target it to the right server.
Navigate to AM configuration -> edit the default configuration and make it use JDBC URL connection type with “AdfAppDB”.
Run the AM and you will see that all works fine.
I have a sample TestPage.jsf which I run and I can see that employee data comes all fine.
Either open the connections.xml or edit the connection for AdfAppDB, make it use an invalid DB and you will see that the page doesn’t load with DB connection errors. This confirms that when you have a JDBC URL connection type set on application module, the connection is picked up from connections.xml of deployed application.
Testing the page with JDBC Datasource:
Now on the AM, let’s use the data source that we created on the “Defining the data source in weblogic” step so that AM would do a JNDI lookup at runtime to weblogic to identify appropriate connection. To do this, first Navigate to AM configuration -> edit the default configuration and make it use JDBC data source connection type with “AdfAppDB” connection JNDI details selected as shown below.
Now when you run the AM, the data comes up all fine and is good. Run the TestPage.jsf – you will see that the page errors with below exception.
Caused by: javax.naming.LinkException: [Root exception is javax.naming.NameNotFoundException: Unable to resolve 'jdbc.AdfAppDBDS'. Resolved 'jdbc'; remaining name 'AdfAppDBDS']; Link Remaining Name: ‘jdbc/AdfAppDBDS’
at weblogic.jndi.internal.WLNamingManager.getObjectInstance(WLNamingManager.java:104)
at weblogic.jndi.internal.BasicNamingNode.resolveObject(BasicNamingNode.java:884)
at weblogic.jndi.internal.ApplicationNamingNode.resolveObject(ApplicationNamingNode.java:187)
at weblogic.jndi.internal.BasicNamingNode.resolveObject(BasicNamingNode.java:856)
at weblogic.jndi.internal.BasicNamingNode.lookup(BasicNamingNode.java:209)
Root cause: The JNDI name defined on weblogic is “jdbc/demo/AdfAppDBDS” where as what we have selected on the code is “java:comp/env/jdbc/AdfAppDBDS”. Of this, “java:comp/env/” part will be dynamically attached at runtime by WLS and hence that can be ignored. “demo” is missing in the JNDI name “jdbc/demo/AdfAppDBDS”. So let’s update the JNDI name alone manually on AM configuration to use “java:comp/env/jdbc/demo/AdfAppDBDS”. Now nothing is wrong here – let’s run the page and try.
Still the same error – but this time with a different JNDI name.
Caused by: javax.naming.NameNotFoundException: While trying to look up comp/env/jdbc/demo/AdfAppDBDS in /app/webapp/JndiDemoApplication-ViewController-context-root/26713680.; remaining name ‘comp/env/jdbc/demo/AdfAppDBDS’
at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1139)
at weblogic.jndi.internal.ApplicationNamingNode.lookup(ApplicationNamingNode.java:144)
at weblogic.jndi.internal.WLEventContextImpl.lookup(WLEventContextImpl.java:254)
at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:411)
To understand why this comes up again, let’s split the JNDI name used on the AM Configuration –
java:comp/env/jdbc/demo/AdfAppDBDS.java:comp/env – is added by WLS automatically at runtime
jdbc/ – ADF Expects ALL JNDI names used by it to start with jdbc/. Hence its a MUST that when you are using a Data source connection for your AM, that data source JNDI name must start with jdbc/.
demo/AdfAppDB – Even though ADF will do the JNDI mapping to the JNDI name on WLS, it still tries to find this name defined on connections.xml. Even if it is a invalid DB, that’s fine. But this connection name should be exactly present on connections.xml. This is the reason why it is failing second time above. We have connection name as AdfAppDB but not as demo/AdfAppDB.
DS – ADF Expects ALL JNDI names used by it to end with the string DS. Hence its a MUST that when you are using a Data source connection for your AM, that data source JNDI name must end with DS.
Now in our case, the WLS Data source has JNDI name “
jdbc/demo/AdfAppDBDS” which is fine. ADF expects the data source name to end with DS which is met here.We know that AM is fine. Based on above summary, what is missing is that connection name definition on connections.xml. Hence let’s define a new connection named “demo/AdfAppDB” and rerun the page and it works like charm now.

Thanks,
Kavin.
How to start weblogic managed servers without manually entering the password
While starting a managed server in weblogic, we start with below command.
<domain_home>/bin/startManagedWebLogic.sh soa_server1 t3://localhost:7001
This command will prompt to manually enter the username and password for the AdminServer. There are two ways of preventing that and here I am going to talk about it.
Option 1: Setting the java options for username and password.
Set below java option on your terminal before starting the managed server.
export JAVA_OPTIONS=”-Dweblogic.management.username=weblogic -Dweblogic.management.password=weblogic1″
After setting this, when the WLS Managed server startup kicks off, it will pick up the username and password from above properties and wouldn’t ask for manual entry of Adminserver username or password.
Option 2: Setting up boot.properties
While starting weblogic server [including AdminServer], it will check for a file called boot.properties in <domain_home>/servers/AdminServer/security. This file can hold the property values for username and password and if the right values are present, WLS isn’t going to prompt for manual authentication. This file will be present by default for AdminServer and that’s why while starting AdminServer, it doesn’t prompt for username and password. To test, remove this file from servers/AdminServer/security and start your AdminServer – you will see that even AdminServer start up prompts you for entering username and password manually.
Enriching this concept for managed server, create a file boot.properties in the managed server folder.
Eg:
mkdir <domain_home>/servers/soa_server1/security
Create a new file called boot.properties and enter below property values.
username=weblogic password=weblogic
Now save this file and start the managed server as usual.
<domain_home>/bin/startManagedWebLogic.sh soa_server1 t3://localhost:7001
This time also, it wouldn’t prompt to enter the username and password manually.
NOTE that when the server is started for the first time, it will automatically encrypt BOTH username and password stored on this file.
Thanks,
Kavin.
Correlation Set in BPEL to Interrupt BPEL
Its been quite sometime since I blogged last – got very busy for past few months. Back now with something that I feel interesting.
Use case: A composite instance triggers a BPEL component. The BPEL component may invoke many asynchronous flows or it might be in wait state using “wait” activity or it might use a Human task and wait till human task completes. These scenarios might dehydrate BPEL. In this case, I take a scenario where I want to terminate the BPEL component instance when BPEL process is waiting for some legitimate reason.
Technical solution: The composite exposes a service with two operations. One MainOperation that would initiate the main flow of the BPEL. Two InterruptOperation that would trigger the OnMessage event handler of the same BPEL process and terminate the corresponding component instance initiated through MainOperation using Correlation sets.
Sample app used below: http://kavin-sample-apps.googlecode.com/files/InterruptBPEL.rar
Description of the project:
Create a SOA Application and Project with an empty SOA Composite.
The input schema that I have chosen for this composite is below. This schema has two messages.
1) EmployeeDetails -> Detail sent to initiate the main BPEL flow which has the core business logic. EmployeeId in this message is used in correlation set.
2) InterruptPayload -> This is used by InterruptOperation that is used to terminate the BPEL instance. This also carries EmployeeId so that the main flow can be correlated.
Create a new BPEL Process. Choose Template as “Base on a WSDL” and create a new WSDL file. Choose an one way operation and name it as “EmployeeProcessingFlow”. This is going to be the operation that is going to execute the core business logic in the BPEL process. This operation would be using “EmployeeDetails” element in above schema.
Instead of creating a new composite service for the Interrupt flow, let us add an additional operation to the existing WSDL in the same port. This operation is going to use a newly defined WSDL message “InterruptMessage” that would point to “InterruptPayload” in above given schema.
<wsdl:message name="requestMessage"> <wsdl:part name="EmployeeDetailMessage" element="inp1:EmployeeDetails"/> </wsdl:message> <wsdl:message name="InterruptMessage"> <wsdl:part name="InterruptMessage" element="inp1:InterruptPayload"/> </wsdl:message> <wsdl:portType name="EmployeeProcessingPort"> <wsdl:operation name="EmployeeProcessingFlow"> <wsdl:input message="tns:requestMessage"/> </wsdl:operation> <wsdl:operation name="InterruptFlow"> <wsdl:input message="tns:InterruptMessage"/> </wsdl:operation> </wsdl:portType>
Open the newly created BPEL process – “EmployeeProcessingProcess.bpel”. Add an OnMessage Event Handler to the global scope. This branch is going to wait for the incoming request from “InterruptFlow” operation of “EmployeeProcessingService”.
Now let’s correlate the receive and OnMessage entry point of EmployeeProcessingProcess into a single flow using correlation sets. To know more about correlation sets, refer to this section of Oracle SOA Suite Developers Guide. Basically correlation set is a way to attach a business specific key information to a BPEL instance so that the specific instance can be fetched at runtime and process can be executed further.
To start with, edit the receive activity of the BPEL process and add a new Correlation. Create a new Correlation set – “EmployeeFlowCorrelationSet” with a property to bind the business object specific unique key – BindEmployeeId. Add the EmployeeId element from the Input message of the receive activity as a “Property Alias” for Property. Make sure “Initiate” property of this correlation in this receive activity to “yes”.
Tip: In above screenshot, NOTE that there is no icon to “choose” Query declaratively. So point the cursor there and press Ctrl+Enter so that it would show the message automatically to select.
Add a wait activity after receive and set wait time to 5 minutes to simulate the use case. On OnMessage branch, do a terminate to cancel the BPEL flow. So when the first message comes from “EmployeeProcessingFlow”, the BPEL will be in wait state for 5minutes. In the interim, when message from “InterruptFlow” comes, then it would be correlated with old instance and the instance would be terminated. If certain clean up need to be done before termination, then it can be included in OnMessage branch before Terminate.
Edit the OnMessage branch and bind the same correlation. In this OnMessage branch, the EmployeeId from InterruptMessage has to be set as Property Alias for the existing correlation set.
That completes the coding
Testing the project:
Now deploy the composite to EM and access the end point using the default end point tester URL.
http://localhost:7001/soa-infra/services/default/InterruptBpelFlow/EmployeeProcessingService_ep
Select the operation “EmployeeProcessingFlow” that handles main flow. Enter an EmployeeId value like “349827495″ and a random Salary value and Invoke this to Initiate the composite main flow. This would initiate the BPEL process receive activity by setting EmployeeId as correlation id and put the BPEL in wait state for 5 minutes which can be seen from EM.
Now on the same URL [http://localhost:7001/soa-infra/services/default/InterruptBpelFlow/EmployeeProcessingService_ep], select the “InterruptFlow” operation with same EmployeeId as input so that it would correlate with above mentioned BPEL instance and terminate it.
Thanks for Reading and Keep Smiling
Kavin
Enable/Disable Business Events Delivery in EDN
In SOA 11g, Business events framework, below is the option that is used to control the delivery of business events to the target consumers.
Login to Enterprise Manager -> Expand SOA. Right click on soa_server1 -> Administration -> System Mbean browser. Expand Application Defined MBeans -> oracle.as.soainfra.config -> Server:****** -> EDNConfig -> edn.
You can see a property called Paused. When this property is set to true, then it temporarily suspends the delivery of business events.When this value is false, events are delivered as usual.
This comes very handy when you are debugging event subscription issues where you can see event properly in EDN Log, but the composite subscribing to that business event isn’t fired.
Thanks for Reading and Keep Smiling ![]()
Kavin.













































