Thursday Dec 22, 2011

Broken Link Fixed - ADF and Servlets

I've just noticed that one of the articles that people actually refer to (Using ADF and Servlets together) still had a link back to the old Samplecode site and so the example was no longer available. I've now corrected that for you. Enjoy. 

Wednesday Dec 21, 2011

ADF Performance Presentation from UKOUG

I've given this presentation a few times now at various events around the world, most recently at the UK Oracle Users Group. It's an ever evolving topic area so I'm sure the paper will change over time, but here's the version for now:

This is very much based on our experience of tuning real ADF Enterprise Applications, for both internal and external customers.  Hopefully there are a few useful nuggets of information in there for you.

Thursday Dec 08, 2011

Automating Remote Deployment to Oracle WebLogic from Hudson

As part of my effort to streamline the continuous build processes around my sample and prototype portfolio, I use Hudson to trigger new builds of each sample as it is updated. Thus far I had been getting as far as testing, building (using OJDeploy), precompiling and archiving, but I'm not gotten around to deploying as part of those jobs. 

The main reason for this was due to the fact that the Hudson deployer plugin does not support WebLogic as a target (this is due in turn to a limitation of the underlying Cargo CodeHaus project) . Anyway I digress.

So rather than using the deploy step in a Hudson FreeStyle project, we need to add a normal build step at the end of the chain to handle the WebLogic deployment. Now as it happens, this is pretty easy to do, and given that you'll generally be building ADF projects with OJDeploy in any case, you have everything to hand, and no real additional setup is required. If you're not building and deploying an ADF project then the additional step you will need here is to ensure that there is a WebLogic server installation available on the Hudson machine that is executing the job.

The actual command line to trigger the deploy is pretty simple, however, at it's most basic level it takes a plain-text username and password for the WebLogic administrator.  This is probably not the kind of information that you want to leave sprinkled throughout your job configurations and console logs, so preventing that is the first step.

(Note: Even so I'm running in a pretty simple dev/test environment where the WebLogic is within the same network and I'm not using SSL, if you read the documentation references below you'll see how to beef this up for a more secure environment.)

Step 1. Conceal your Identity

The utility that we'll be using to do the deploy is weblogic.Deployer (more later, but see here for the 10.3.5 doc on this).  As I mentioned, that takes username and password parameters which we don't want, however, it also provides a way to externalize the credentials and that's what I'll use here.  This is a step that you need to carry out on the Hudson executor machine and it takes place outside of Hudson all together. We'll use the weblogic.WLST utility to generate an encrypted credential store to hold the username and password for the remote server I'm about to deploy to. You will need WebLogic or JDeveloper installed on the machine to get access to the  weblogic.Deploy and weblogic.WLST commands.  I'm signifying that location with ${WLS_HOME} here. For the sake of illustration I'm logged in as the user that runs the Hudson process and I'll store the new credential files in a sub-directory of that users home directory called wlskeys. I'm using the bash shell here:

source ${WLS_HOME}/wlserver_10.3/server/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> connect('weblogic','secret_admin_password',

Connecting to t3://duncan_wls:7001 with userid weblogic ...
Successfully connected to Admin Server 'AdminServer' that belongs to domain 'adf_domain'.
Warning: An insecure protocol was used to connect to the server. To ensure on-the-wire security, the SSL port or Admin port should be used instead.

wls:/adf_domain/serverConfig> storeUserConfig('~/wlskeys/',

Creating the key file can reduce the security of your system if it is not kept in a secured location after it is created.
Do you want to create the key file? y or n
The username and password that were used for this WebLogic Server connection are stored in /home/hudson/wlskeys/ and /home/hudson/wlskeys/duncan_wls_userConfig.key.

wls:/adf_domain/serverConfig> exit()
Exiting WebLogic Scripting Tool.

So there you have it. If you now peek in the specified directory you will be able to see the generated files.  It goes without saying that the files in question are ones to protect! You can go ahead and generate as many of these file pairs as you have servers for Hudson to deploy to.

Step 2. The Deploy command from Hudson 

The actual deploy step from Husdon is defined as a Execute Shell step in your job. To cut down on typing and allow for different directory structures across the Hudson slaves I'm using,  I've predefined some variables in the general Hudson config and overridden them appropriately on the slave node configuration (Node Properties -> Environment Variables):

  • ${WLS_HOME} WebLogic Home directory
  • ${WLS_KEYSTORE} The directory on which I save the properties and key files generated in Step 1 
  • ${TESTING_SERVER} The URL for the Admin Server (e.g. t3://duncan_wls:7001)

 Then the Hudson build step looks looks this:

source ${WLS_HOME}/wlserver_10.3/server/bin/
java weblogic.Deployer -adminurl ${TESTING_SERVER}
  -userconfigfile ${WLS_KEYSTORE}/
  -userkeyfile ${
  -deploy ${WORKSPACE}/deploy/myapp.ear -upload

The -upload parameter is the important one here, that will take the EAR file that Hudson has build and transfer it to the remote machine before trying the install.

Variations on the Theme

This approach is, of course, just one way of achieving this. Other options would include using the FTP-Publisher plugin to push the file to the remote server, and if this was set up to the right place and WebLogic was auto-deploying in development mode you could bypass the need for the WebLogic install on the Hudson executors. However, given that for an ADF application we really need to use OJDeploy to build the app we'll have this stuff to hand anyway. 

Other variations would include using WLST or the WebLogic ANT tasks rather than weblogic.Deploy. The end result and approach are identical in these cases.

I'm sure that the WebLogic plugin for Maven is probably an even better route to go for this entire process, however, I've not Maven-ised my main codebase yet so that will have to wait for another day.

Monday Nov 28, 2011

Zip files for TUHRA2 Re-published

Just a quick note to all readers of the venerable Oracle JDeveloper 11g Handbook: A Guide to Fusion Web Development. The chapter ZIP files and scripts have all now been re-located to in the tuhra2 project:

Thursday Nov 24, 2011

JSP Precompilation for ADF Applications

A question that comes up from time to time, particularly in relation to build automation, is how to best pre-compile the .jspx and .jsff files in an ADF application. Thus ensuring that the app is ready to run as soon as it's installed into WebLogic. In the normal run of things, the first poor soul to hit a page pays the price and has to wait a little whilst the JSP is compiled into a servlet. Everyone else subsequently gets a free lunch. So it's a reasonable thing to want to do...

Let Me List the Ways

So forth to Google (other search engines are available)... which lead me to a fairly old article on WLDJ - Removing Performance Bottlenecks Through JSP Precompilation. Technololgy wise, it's somewhat out of date, but the one good point that it made is that it's really not very useful to try and use the precompile option in the weblogic.xml file. That's a really good observation - particularly if you're trying to integrate a pre-compile step into a Hudson Continuous Integration process. That same article mentioned an alternative approach for programmatic pre-compilation using weblogic.jspc. This seemed like a much more useful approach for a CI environment. However, weblogic.jspc is now obsoleted by weblogic.appc so we'll use that instead.  Thanks to Steve for the pointer there.

And So To APPC

APPC has documentation - always a great place to start, and supports usage both from Ant via the wlappc task and from the command line using the weblogic.appc command. In my testing I took the latter approach.

Usage, as the documentation will show you, is superficially pretty simple.  The nice thing here, is that you can pass an existing EAR file (generated of course using OJDeploy) and that EAR will be updated in place with the freshly compiled servlet classes created from the JSPs. Appc takes care of all the unpacking, compiling and re-packing of the EAR for you. Neat. 

So we're done right...? Not quite.

The Devil is in the Detail

 OK so I'm being overly dramatic but it's not all plain sailing, so here's a short guide to using weblogic.appc to compile a simple ADF application without pain. 

Information You'll Need

The following is based on the assumption that you have a stand-alone WLS install with the Application Development  Runtime installed and a suitable ADF enabled domain created. This could of course all be run off of a JDeveloper install as well

1. Your Weblogic home directory. Everything you need is relative to this so make a note.  In my case it's c:\builds\wls_ps4.

2. Next deploy your EAR as normal and have a peek inside it using your favourite zip management tool. First of all look at the weblogic-application.xml inside the EAR /META-INF directory. Have a look for any library references. Something like this:


 Make a note of the library ref ( in this case) , you'll need that in a second.

3. Next open the nested WAR file within the EAR and then have a peek inside the weblogic.xml file in the /WEB-INF directory. Again  make a note of the library references.

4. Now start the WebLogic as per normal and run the WebLogic console app (e.g. http://localhost:7001/console). In the Domain Structure navigator, select Deployments.

5. For each of the libraries you noted down drill into the library definition and make a note of the .war, .ear or .jar that defines the library. For example, in my case maps to "C:\ builds\ WLS_PS4\ oracle_common\ modules\ oracle. adf. model_11. 1. 1\ adf. oracle. domain. ear". Note the extra spaces that are salted throughout this string as it is displayed in the console - just to make it annoying, you'll have to strip these out.

6. Finally you'll need the location of the adfsharebean.jar. We need to pass this on the classpath for APPC so that the ADFConfigLifeCycleCallBack listener can be found. In a more complex app of your own you may need additional classpath entries as well. 

Now we're ready to go, and it's a simple matter of applying the information we have gathered into the relevant command line arguments for the utility

A Simple CMD File to Run APPC 

Here's the stub .cmd file I'm using on Windows to run this.

@echo off
REM Stub weblogic.appc Runner

set WLS_HOME=C:\builds\WLS_PS4
set ADF_LIB_ROOT=%WLS_HOME%\oracle_common\modules
set COMMON_LIB_ROOT=%WLS_HOME%\wlserver_10.3\common\deployable-libraries
set ADF_WEBAPP=%ADF_LIB_ROOT%\oracle.adf.view_11.1.1\
set ADF_DOMAIN=%ADF_LIB_ROOT%\oracle.adf.model_11.1.1\
set JSTL=%COMMON_LIB_ROOT%\jstl-1.2.war
set JSF=%COMMON_LIB_ROOT%\jsf-1.2.war
set ADF_SHARE=%ADF_LIB_ROOT%\oracle.adf.share_11.1.1\adfsharembean.jar

REM Set up the WebLogic Environment so appc can be found
call %WLS_HOME%\wlserver_10.3\server\bin\setWLSEnv.cmd

REM Now compile away!
java weblogic.appc -verbose -library %ADF_WEBAPP%,%ADF_DOMAIN%,%JSTL%,%JSF% -classpath %ADF_SHARE% %1


Running the above on a target ADF .ear  file will zip through and create all of the relevant compiled classes inside your nested .war file in the \WEB-INF\classes\jsp_servlet\ directory (but don't take my word for it, run it and take a look!)

And So...

In the immortal words of  the Pet Shop Boys, Was It Worth It? Well, here's where you'll have to do your own testing. In  my case here, with a simple ADF application, pre-compilation shaved an non-scientific "3 Elephants" off of the initial page load time for the first access of each page. That's a pretty significant payback for such a simple step to add into your CI process, so why not give it a go.

Monday Nov 21, 2011

Things to watch for at UK Oracle Users Group in Birmingham

Grant Ronald has put together a handy summary of all of the Oracle Application Development Framework sessions for the UKOUG Tech Conference this year.:

If you're at the event then come along! 

Friday Sep 23, 2011

Adventures in Logging Index

It occurred to me that a lot of folks are referring to the Adventures in ADF Logging Series, but there was no master page as such which pulled them all together. Frankly I wanted a simple URL that I could then link from my various OOW, DOAG and UKOUG sessions this year.  So here are the individual entries in the series:

Article Contents
Part 1 Basic introduction to the ADF logger covering programmatic logging
Part 2 Covers the JDeveloper Code templates I created to make it a snap to insert logging code
Part 3 How to control and configure your logging output
Part 4 Browsing and filtering log output results
Part 5

The true power of the ADF logger including ADF request tracing for performance analysis

Part 6

Seeing all your log output on the console in 12c

Related Logging and Diagnostics Topics

  1. Selective Suppression of Log Messages 
  2. Click History in ADF 12c
  3. Click History Part 2 - Access from Java

Bonus External Material

Friday Sep 02, 2011

Heatmap Styling in Tables

A question that has come up a couple of times recently is that of applying cell level styling, for example background color / colour within a conventional ADF Table.  In the Pivot table this is trivial, you just apply the styleclass to the component inside the <dvt:dataCell>. For the conventional table, however, you'll run into a slight problem with this approach in that the chances are that your styled inputText or outputText will not completely fill the cell and you'll end up with whitespace around the component and a ragged right margin depending on the length of the data in each. 

The solution is, however, simple.  Within the <af:column> wrap the display component inside of a <af:panelGroupLayout>. Ensure that you set the PGL to a vertical layout to ensure that it is stretched to fill the table cell.  Then just apply your styleclass expression to the PGL rather than the input or output text within.

So you might end up with something like this:

<af:column  headerText="#{bindings.Accounts.hints.AccountStatus.label}">
  <!-- stlyes with the same name as the Status value exist in the CSS --> 
  <af:panelGroupLayout layout="vertical" styleClass="#{row.bindings,Status.inputValue}">
    <af:outputText value="#{row.bindings.Status.inputValue}"/>

Thursday Aug 11, 2011

Arcane zip commands for your ADF App and Hudson

I'm in the process of automating the builds of some of my sample applications that I create for proof of concepts and the like, and based on the fact that I'm heavily involved in the Hudson project now it made a lot of sense to use Hudson to help me. Now this entry is not about Hudson per-say, it is, however, related in that it's the type of syntax that you would use in a shell command executed from Hudson.

In this case I have a standard ADF project (Model, ViewController and the like)  which has been checked out from Subversion by Hudson and built with OJDeploy.  What I wanted to do in this case was also create a clean source archive from the checked out sources, without having to do a separate SVN export to get a clean copy.  So this involved working out the correct syntax of the unix zip command to exclude the artifacts (such as classes, WAR files and .svn directories) that I didn't want in the source zip file.

Anyway here's the command that creates the source zip in my top level deploy directory - hopefully it will save you a bunch of time if you ever need to do the same thing, it's one of those fiddly to get right things that always takes up way too much time.

The following is all one command, I've just split it up onto two lines for readability:

zip -r ./deploy/${JOB_NAME}_${BUILD_NUMBER} * 
    -x 'deploy/*' -x */deploy/* -x *classes/* -x *.data* -x *.svn*

This command is issued as a Hudson build step from the ${WORKSPACE} which is also the ADF Application workspace root directory

Thursday Jul 14, 2011

Book Recommendation - Oracle ADF Enterprise Application Development - Made Simple

Throughout the early part of this year I was involved in the technical review of a new ADF Book; Oracle ADF Enterprise Application Development - Made Simple (PACKT Press ISBN 978-1-849681-88-9), authored by Oracle ACE Director Sten Versterli. Sten and I subsequently went on to do a podcast on the same subject.  Well, as of a couple of weeks ago the book is now available for real and I've gotten my hands on a final copy to re-read, something which I've been doing over the last week or so.  

I have to say that this is a book which I really really like. I think the approach is spot on in terms of what the book covers and the tone.  It's not attempting to re-hash the well trodden material that has already been covered in the doc set or some of the other books out there.  Rather it takes a much more pragmatic and practical approach to the tasks involved in really building out a practical ADF application in a team development environment, going beyond the coding mechanics and APIs into the practicalities.  A lot of Sten's real world experience is really shining through here, and it's great advice to listen to. 

I'd say this one is a must for any team leader or architect about to start their first ADF project in earnest.


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!


« March 2015