Wednesday Apr 27, 2011

Integrating ADF and Servlets

Inspired by a recent (OK not so recent but I’ve been busy)  OTN Code Harvest article from Frank Nimphius and prompted by a specific customer question along the same lines I’ve put together a simple example project that demonstrates the technique in a very simple manner. Frank is discussing the common case of reusing ADF Business Components Application Module context, however, my sample is a little simpler and is just using a humble POJO for simplicity.

You can download the sample workspace from here: Sharing ADF context with a Servlet.

This sample is based on JDeveloper / ADF 11.1.1.4 (Fusion Middleware Patchset 3) but should upgrade to newer 11.1.1.n versions without a problem. There are no database dependencies.

To try it out, just unzip the sample, make and run index.jspx in the ViewController project.

This code demonstrates how a Servlet within an application can share the same data control context (frame) as the underlying UI pages and Task Flows within that application.
This approach is useful when you are creating integrated applications where servlets are leveraged to add functionality to the application such as AJAX calls or email generation

Notes

  1. The Servlet path is mapped to the same pageDef as the required ADF content in the DataBinding.cpx file
  2. The Servlet is registered with the ADF Binding filter in the web.xml file
  3. The "calling" page (or taskflow) will temporarily store the current Data Control Frame name on the session
  4. The servlet will retrieve the data control frame name and use that to access the binding that is required in the correct context

Tuesday Jun 08, 2010

Browsing Your ADF Application Module Pooling Params with WLST

In ADF 11g you can of course use Enterprise Manager (EM) to browse and configure the settings used by ADF Business Components  Application Modules, as shown here for one of my sample deployed applications.
em_adfpooling.png

This screen you can access from the EM homepage by pulling down the Application Deployment menu, and then ADF > Configure ADF Business Components. Then select the profile that you are actually using (Hint: look in the DataBindings.cpx file to work this out - probably the "Local" version unless you've explicitly changed it. )
So, from this screen you can change the pooling parameters and the world is good. But what if you don't have EM installed? In that case you can use the WebLogic scripting capabilities to view (and Update) the MBean Properties.
Explanation
The pooling parameters and many others are handled through Message Driven Beans that are created for the deployed application in the server. In the case of the ADF BC pooling parameters, this MBean will combine the configuration deployed as part of the application, along with any overrides defined as -D environment commands on the JVM startup for the application server instance.

Using WLST to Browse the Bean Values
For our purposes here I'm doing this interactively, although you can also write a script or write Java to achieve the same thing.

Step 0: Before You Start
You will need the following
  1. Access to the console on the machine that is running the server or another machine on the same network that has the same version of WebLogic
  2. The WebLogic Admin username and password (I'll use weblogic/password as my example here - yours will be different)
  3. If you are connecting to a remote server the network path to the listen address and port of the running server (for example t3://adf.example.com:7001)
  4. The name of the deployed application (in this example FMWdh_application1)
  5. The package path to the bc4j.xcfg file (in this example oracle.demo.fmwdh.model.service.common.bc4j.xcfg) This is based on the default path for your model project so it shoudl be fairly easy to work out.
  6. The BC configuration your AM is actually running with (look in the DataBindings.cpx for that. In this example DealHelpServiceDeployed is the profile being used..)
Step 1: Start the WLST console
To start at the beginning, you need to run the WLST command but that needs a little setup:
  1. Change to the wlserver_10.3/server/bin directory e.g. under your Fusion Middleware Home
    [oracle@mymachine] cd /home/oracle/FMW_R1/wlserver_10.3/server/bin
  2. Set your environment using the setWLSEnv script. e.g. on Oracle Enterprise Linux:
    [oracle@mymachine bin] source setWLSEnv.sh
  3. Start the WLST interactive console
    [oracle@mymachine bin] java weblogic.WLST
Initializing WebLogic Scripting Tool (WLST) ...
Welcome to WebLogic Server Administration Scripting Shell
Type help() for help on available commands

wls:/offline>


Step 2:Enter the WLST commands
  1. Connect to the server
    wls:> connect('weblogic','password')
    Or if it is a remote server
    wls:> connect('weblogic','password','t3://adf.example.com:7001')
  2. Change to the Custom root, this is where the AMPooling MBeans are registered
    wls:> custom()
  3. Change to the b4j MBean directory
    wls:> cd ('oracle.bc4j.mbean.config')
  4. Work out the correct directory for the AM configuration you need. This is the difficult bit, not because it's hard to do, but because the names are long. The structure here is such that every child MBean is displayed at the same level as the parent, so for each deployed application there will be many directories shown. In fact, do an ls() command here and you'll see what I mean. Each application will have one MBean for the app as a whole, and then for each deployed configuration in the .xcfg file you'll see: One for the config entry itself, and then one each for Security, DB Connection and AM Pooling. So if you deploy an app with just one configuration you'll see 5 directories, if it has two configurations in the .xcfg you'll see 9 and so on.
    The directory you are looking for will contain those bits of information you gathered in Step 0, specifically the Application Name, the configuration you are using and the xcfg name:
    First of all narrow your list to just those directories returned from the ls() command that begin oracle.bc4j.mbean.config:name=AMPool. These identify the AM pooling MBeans for all the deployed applications.
    Now look for the correct application name e.g. Application=FMWdh_application1
    The config setting in that sub-list should already be correct and match what you expect e.g. oracle.bc4j.mbean.config=oracle.demo.fmwdh.model.service.common.bc4j.xcfg
    Finally look for the correct value for the AppModuleConfigType e.g. oracle.bc4j.mbean.config.AppModuleConfigType=DealHelpServiceDeployed
  5. Now you have identified the correct directory name, change to that (keep the name on one line of course - I've had to split it across lines here for clarity:
    wls:> cd ('oracle.bc4j.mbean.config:name=AMPool,
        type=oracle.bc4j.mbean.config.AppModuleConfigType.AMPoolType,
        oracle.bc4j.mbean.config=oracle.demo.fmwdh.model.service.common.bc4j.xcfg,
        Application=FMWdh_application1,
        oracle.bc4j.mbean.config.AppModuleConfigType=DealHelpServiceDeployed')
  6. Now you can actually view the parameter values with a simple ls() command
    wls:> ls()
    And here's the output in which you can view the realtime values of the various pool settings:

-rw- AmpoolConnectionstrategyclass oracle.jbo.common.ampool.DefaultConnectionStrategy
-rw- AmpoolDoampooling true
-rw- AmpoolDynamicjdbccredentials false
-rw- AmpoolInitpoolsize 2
-rw- AmpoolIsuseexclusive true
-rw- AmpoolMaxavailablesize 40
-rw- AmpoolMaxinactiveage 600000
-rw- AmpoolMaxpoolsize 4096
-rw- AmpoolMinavailablesize 2
-rw- AmpoolMonitorsleepinterval 600000
-rw- AmpoolResetnontransactionalstate true
-rw- AmpoolSessioncookiefactoryclass oracle.jbo.common.ampool.DefaultSessionCookieFactory
-rw- AmpoolTimetolive 3600000
-rw- AmpoolWritecookietoclient false
-r-- ConfigMBean true
-rw- ConnectionPoolManager oracle.jbo.server.ConnectionPoolManagerImpl
-rw- Doconnectionpooling false
-rw- Dofailover false
-rw- Initpoolsize 0
-rw- Maxpoolcookieage -1
-rw- Maxpoolsize 4096
-rw- Poolmaxavailablesize 25
-rw- Poolmaxinactiveage 600000
-rw- Poolminavailablesize 5
-rw- Poolmonitorsleepinterval 600000
-rw- Poolrequesttimeout 30000
-rw- Pooltimetolive -1
-r-- ReadOnly false
-rw- Recyclethreshold 10
-r-- RestartNeeded false
-r-- SystemMBean false
-r-- eventProvider true
-r-- eventTypes java.lang.String[jmx.attribute.change]
-r-- objectName oracle.bc4j.mbean.config:name=AMPool,type=oracle.bc4j.mbean.config.AppModuleConfigType.AMPoolType,oracle.bc4j.mbean.config=oracle.demo.fmwdh.model.service.common.bc4j.xcfg,Application=FMWdh_application1,oracle.bc4j.mbean.config.AppModuleConfigType=DealHelpServiceDeployed
-rw- poolClassName oracle.jbo.common.ampool.ApplicationPoolImpl
Thanks to Brian Fry on the JDeveloper PM Team who did most of the work to put this sequence of steps together with me badgering him over his shoulder.
Additional thanks to James Bayer who pointed out that we can connect remotely to the server, allowing the same script to be run from a single point against many servers.

Saturday May 08, 2010

Script For Detecting Availability of XMLHttp in Internet Explorer

Having the XMLHttpRequest API available is key to any ADF Faces Rich Client application. Unfortunately, it is possible for users to switch off this option in Internet Explorer as a Security setting. Without XMLHttpRequest available, your ADF Faces application will simply not work correctly, but rather than giving the user a bad user experience wouldn't it be nicer to tell them that they need to make some changes in order to use the application? 
Thanks to Blake Sullivan in the ADF Faces team we now have a little script that can do just this.
The script is available from the sample code page here, just look for the browserCheck.js sample - This is what you'll need to add to your project.
The best way to use this script is to make changes to whatever template you are using for the entry points to your application. If you're not currently using template then you'll have to make the same change in each of your JSPX pages.
  1. Save the browserCheck.js file into a /js/ directory under your HTML root within your UI project (e.g. ViewController)
  2. In the template or page, select the <af:document> object in the Structure window.
  3. From the right mouse (context) menu choose Facet and select the metaContainer facet.
  4. Switch to the source code view and locate the metaContainer facet. Then insert the following lines (I've included the facet tag for clarity but you'll already have that):
      <f:facet name="metaContainer">
        <af:resource type="javascript"
                     source="/js/browserCheck.js"/>
        <af:resource type="javascript">
           xmlhttpNativeCheck(
                     "help/howToConfigureYourBrowser.html");
        </af:resource>
      </f:facet>

Note that the argument to the xmlhttpNativeCheck function is a page that you want to show to the user if they need to change their browser configuration. So build this page in the appropriate place as well. You can also just call the function without any arguments e.g. xmlhttpNativeCheck(); in which case it will pop up default instructions for the user to follow, but not redirect to any other page.
About

Hawaii, Yes! Duncan has been around Oracle technology way too long but occasionally has interesting things to say. He works in the Development Tools Division at Oracle, but you guessed that right? In his spare time he contributes to the Hudson CI Server Project at Eclipse
Follow DuncanMills on Twitter

Note that comments on this blog are moderated so (1) There may be a delay before it gets published (2) I reserve the right to ignore silly questions and comment spam is not tolerated - it gets deleted so don't even bother, we all have better things to do with our lives.
However, don't be put off, I want to hear what you have to say!

Search

Archives
« April 2014
MonTueWedThuFriSatSun
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today