Archive

Posts Tagged ‘Configuration’

JNDI usage in ADF Application Module for Data base connectivity

October 18, 2012 3 comments
The application module created in ADF Application connects to a given data base using two options. JDBC URL and JDBC Data source.

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.

Testing AM with JDBC URL:
In the application, create a DB Connection named “
AdfAppDB”.


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.