Showing posts with label Apex. Show all posts
Showing posts with label Apex. Show all posts

Thursday, 6 May 2010

Configuring Apache JMeter for Apex

A couple weeks ago I blogged how to configure Apache JMeter for testing Oracle's ADF. This week to complete the set, I'll post my findings on stress testing Oracle's Application Express (Apex) with JMeter . Both posts are related to an earlier post on how to record sessions in JMeter that are essential reading to understand what I've specified here.

A Small Caveat

Please note this particular post is the result of my rather limited testing of JMeter with Apex. I'm not an Apex expert, and I haven't used it for over 2 years in any development project. The implication for this post is I might not have discovered absolutely everything that needs to be done to set up JMeter for stress testing Apex in every considerably use case.

If you discover a problem, and hopefully a fix, to assist other readers it would be great if you could post your comments to this blog to assist those next readers please.

Yet Another Small Caveat

For those who read my ADF post, you'll find much of the text in this post similar. I'm mindful I have readers leaping into this post from Google without having read anything earlier, so I'm guessing it's important I give them the same spool. Apologies for repeating myself.

Not a Caveat, But My Thanks

I need to express my thanks to both Penny Cookson and Patrick Wolf with their assistance in getting this post together. Both obviously have a huge amount of experience with Apex and their thoughts and guidance were appreciated.

Introduction

When considering using JMeter for Oracle Application Express applications there are additional JMeter configuration steps required beyond that detailed in the original post. Apex similar to most web applications uses Cookies, and you can use JMeter's HTTP Cookie Manager to correctly handle the cookie. However Apex also makes use of a number of parameters passed as HTTP POST parameters and URL parameters. On running an Apex application you'll often see URL parameters including the session ID, and embedded within the HTTP bodies variables such as p_instance, p_vt01, p_arg_names and more, used by Apex to coordinate state with the browser session. In order for JMeter to simulate multiple user sessions it needs to be correctly configured to handle these too, capturing and carrying the unique values for each session in the load test.

The following post lists the additional configurations required for JMeter beyond those described in the original post. As noted in the original post the easiest way to setup your JMeter Test Plan is to record an existing Apex session through JMeter's HTTP Proxy Server and I haven't bothered to reiterate those instructions here. In turn I've taken no effort to explain the JMeter features we're utilizing to do this; if you want to learn about the relevant JMeter features consult the JMeter User Manual.

These instructions were created against the Apex version 3.2.1.00.10 included with the latest 11gR2 Oracle database release on Windows. Presumably in the future, possibly Apex v4, it will change its HTTP mechanisms, resulting in you having to carefully check this post's instructions against the future Apex version.

JMeter Apex Required Configurations

The following lists the additional objects and their settings required within JMeter. You need only create one of each for each Thread Group but I'll agree there does seem to be a lot of them. The end result will look something like this:


a) HTTP Cookie Manager

Create via Test Plan -> Thread Group -> Right Click -> Add -> Config Element -> HTTP Cookie Manager

Name:HTTP Cookie Manager
Clear cookies each iteration:Selected

In my original JMeter post, you'll see in the comments from Manolis Nikiforakis, he suggests the Cookie policy should be set to "compatible". In my own testing that didn't seem to work, so I used rfc2965 instead. See what works for you.

b) User Defined Variables

Create via Test Plan -> Thread Group -> Right Click -> Add -> Config Element -> User Defined Variables


Name:User Defined Variables Variables
Variable Name:sessionId
Variable Name:p_flow_id
Variable Name:p_flow_step_id
Variable Name:p_instance
Variable Name:p_page_submission_id
Variable Name:p_request
Variable Name:p_md5_checksum
Variable Name:p_arg_values
Variable Name:p_arg_names01...XXX
Variable Name:p_arg_names01name...XXX
Variable Name:p_arg_names01value
Variable Name:success_msg

Above where you see p_arg_names01...XXX and p_arg_names01name...XXX, what I'm implying here is you need to define as many as these as there are submittable fields on your Apex web pages. In the picture you can see I've defined a set of 10. How many do you need to create, well, you need to carefully look at the session requests you've recorded in JDev and identify the maximum number of fields like p_v01, p_t02 etc. If you're not familiar with what I'm describing here, read on and hopefully it'll become more apparent.

c) sessionId Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name:sessionId Regular Expression Extractor
Response Field to Check:Body
Reference Name:sessionId
Regular Expression:f?p=([0-9]{1,3}):([0-9]{1,3}):([0-9]{16}):
Template:$3$
Match No.:1
Default Value:n/a

d) p_flow_id Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name:p_flow_id Regular Expression Extractor
Response Field to Check:Body
Reference Name:p_flow_id
Regular Expression:<input type="hidden" name="p_flow_id" value="(.+?)" id="pFlowId" />
Template:$1$
Match No.:1
Default Value:n/a

e) p_flow_step_id Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name:p_flow_step_id Regular Expression Extractor
Response Field to Check:Body
Reference Name:p_flow_step_id
Regular Expression:<input type="hidden" name="p_flow_step_id" value="(.+?)" id="pFlowStepId" />
Template:$1$
Match No.:1
Default Value:n/a

f) p_instance Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name:p_instance Regular Expression Extractor
Response Field to Check:Body
Reference Name:p_instance
Regular Expression:<input type="hidden" name="p_instance" value="(.+?)" id="pInstance" />
Template:$1$
Match No.:1
Default Value:n/a

g) p_page_submission_id Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name:p_page_submission_id Regular Expression Extractor
Response Field to Check:Body
Reference Name:p_page_submission_id
Regular Expression:<input type="hidden" name="p_page_submission_id" value="(.+?)" id="pPageSubmissionId" />
Template:$1$
Match No.:1
Default Value:n/a

h) p_request Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name:p_request Regular Expression Extractor
Response Field to Check:Body
Reference Name:p_request
Regular Expression:<input type="hidden" name="p_request" value="(.+?)" id="pRequest" />
Template:$1$
Match No.:1
Default Value:n/a

It's possible this extractor isn't needed, see why in the following descriptions. However I've included it for completeness.

i) p_md5_checksum Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name: p_md5_checksum Regular Expression Extractor
Response Field to Check:Body
Reference Name: p_md5_checksum
Regular Expression:<input type="hidden" name="p_md5_checksum" value="(.+?)" />
Template:$1$
Match No.:1
Default Value:n/a

It's possible this isn't required. In my mini Apex application I never saw the checksum populated. Potentially it may be in yours so I've included it for completeness here.

j) p_arg_values Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name: p_arg_values Regular Expression Extractor
Response Field to Check:Body
Reference Name: p_arg_values
Regular Expression:<input type="hidden" name="p_arg_values" value="(.+?)" />
Template:$1$
Match No.:1
Default Value:n/a

h) p_arg_names01..XX Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name:p_arg_names01...XX Regular Expression Extractor
Response Field to Check:Body
Reference Name:p_arg_names01..XX
Regular Expression:<input type="hidden" name="p_arg_names" value="(.+?)" /><input type="(hidden|text)" name="(p_[tv]01)"
Template:$1$
Match No.:1
Default Value:n/a

As described in the User Variables section, you'll need as many as these as the maximum amount of fields you have in any of your Apex pages. In the above table the Name and Reference Name should not include ..XX, that's just a notation to mean you need to create many of them. Look to the picture to see exactly what you define for the first.

k) p_arg_names01name..XX Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name:p_arg_names01...XX Regular Expression Extractor
Response Field to Check:Body
Reference Name:p_arg_names01name..XX
Regular Expression:<input type="hidden" name="p_arg_names" value="(.+?)" /><input type="(hidden|text)" name="(p_[tv]01)"
Template:$3$
Match No.:1
Default Value:n/a

Again as per the last extractor, you'll need as many as these as the maximum amount of fields you have in any of your Apex pages. In the above table the Name and Reference Name should not include ..XX, that's just a notation to mean you need to create many of them. Look to the picture to see exactly what you define for the first.

l) p_arg_names01value Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name:p_arg_names01value Regular Expression Extractor
Response Field to Check:Body
Reference Name:p_arg_names01value
Regular Expression:<input type="hidden" name="p_arg_names" value="(.+?)" /><input type="(hidden|text)" name="(p_[tv]01)" value="(.+?)" id="P2_BOOKING_NO" />
Template:$4$
Match No.:1
Default Value:n/a

In your application if you have sequence number fields that are prepopulated from a database sequence number and hidden from the user, you need to include an extractor for each. In this example we're grabbing a hidden P2_BOOKING_NO field.

l) success_msg Regular Expression Extractor

Create via Test Plan -> Thread Group -> Right Click -> Add -> Post Processors -> Regular Expression Extractor


Name: success_msg Regular Expression Extractor
Response Field to Check:Body
Reference Name:success_msg
Regular Expression:success_msg=(Action%20Processed.%2F[A-F0-9]{32,33}%2F)
Template:$1$
Match No.:1
Default Value:n/a

It's possible in this extractor the length of the hex regular expression of 32-33 chars could be to limited.

Recorded HTTP Request Changes

After recording an Apex session in JMeter, and setting up the variables above, you'll note in the recorded HTTP Requests numerous references to the same named variables as HTTP parameters. Yet the recorded HTTP Requests include the parameters' values for the recorded session, which simply won't work when we replay the session as the values will have changed.

It is therefore necessary to identify all locations where the parameters exist in the recorded session HTTP Requests and substitute references to your variables.

a) HTTP Request – Parameters – sessionId

For any HTTP Request that has the parameter "p", where the value looks something like:

102:1: 1438937389458569:::::

The third value must be replaced with

102:1: ${sessionId}:::::


If you see a "p" value that looks something like this:

102:1::::::

...don't modify it.

b) HTTP request – Parameters – for any of the following parameters we need to change their values to the following expressions:

p_flow_id -> ${p_flow_id}
p_flow_step_id -> ${p_flow_step_id}
p_instance -> ${p_instance}
p_page_submission_id -> ${p_page_submission_id}
p_arg_names -> ${p_arg_names}
p_v01...p_vXX -> ${p_arg_names01..XX}
p_t01...p_vXX --> ${p_arg_names01..XX}

...as demonstrated in the following picture:


Then in addition for each p_v01..XX and p_t01..XX fields you'll need to replace the actual parameter names, such that:

p_v01..XX -> ${p_arg_names01name..XX}
p_t01..XX -> ${p_arg_names01name..XX}

...ditto for every parameter name, as demonstrated in the following picture:


You'll note we haven't bothered to do anything with the p_request and p_md5_checksum fields. I'm still not overly convinced we need to, so I've included them in the User Variables and Regular Expression Extractors, but haven't done any more with them at this stage.

c) HTTP request – Parameter – success_msg

For the success_msg parameter, replace its value with ${success_msg}, and ensure Encoding is turned off:


Assertions

Once you've completed the above setup and want to run your load test via JMeter, it is important to see that the test is working correctly. One way to do this is to create a View Results Tree (Test Plan -> Thread Group -> Right Click -> Add -> Listener -> View Results Tree) that allows you to inspect the response of each HTTP Request. If you then see HTTP Request responses in red this indicates a HTTP error code response (!= 200). However it's also necessary to inspect each response even if they are green to see if there's a valid response returned carrying an error message. There is definitely a small knack to differentiating between the different type of failures in an Apex application, which you'll become familiar with on some experience.

In order to save you having to look for the same problems for each test-run, you can create a Response Assertion (Test Plan -> Thread Group -> Add -> Assertions -> Response Assertion) to look for specific errors in the responses. To set this up:

Which Samples to Test:Main Sample Only
Response Field to Test:Text Response
Pattern Matching Rules:Contains
Not:Selected
Patterns to Test #1:The error string you're looking for

Sample JMeter file

Readers can download a sample JMeter JMX file for Apex here with the configurations already setup.

Finishing Comment

As I mentioned much earlier in this post, this post really constitutes my research to date in stress testing Apex with JMeter, and doesn't necessarily cover everything you need to do. Ultimately my goal, like other posts on this blog is to share the spark of inspiration such that you can take the ideas and run with them to form a complete solution yourself. Without a doubt because of the length of this post I'll have a typo or have missed something, so again follow up comments would be appreciated to help the next reader please.

Good luck.

Thursday, 26 June 2008

What's the most active OTN forum?: Apex vs JDev vs Forms wars continued

(Disclaimers up front for those who don't regularly read my blog: I'm a JDeveloper advocate)

Recently in attending the ODTUG conference, during the ADF vs Apex session run by Dimitri and Lucas, a comment was made that the Apex OTN forums are the most active OTN forums of all.

This comment surprised me, because I would have thought before Apex, or even JDeveloper (where my heart lies), the database and SQL/PL-SQL forums would be more popular.

The OTN Forums running within Jive provide an easy way to verify the statistics of each of the forums, so I thought I'd publish the top forums to verify the comment from above. I gathered the following statistics on the 26/6/2008 via the following top level OTN page. I've only included forums that have had over 1 million views:

(Note the Thread Response Ratio calculation is my own based on the formula (messages – threads) / threads, on the assumption that messages includes both original thread message and answers. This may be a bogus calculation based on my assumptions so don't read too much into it; I just thought it would be an interesting number)

Database – General
Views: 3,997,367
Threads/Messages: 78,690/384,365
Thread Response Ratio: 3.88

SQL and PL/SQL
Views: 4,163,007
Threads/Messages: 69,220/374,638
Thread Response Ratio: 4.41

Application Express
Views: 3,069,147
Threads/Messages: 33,886/158,752
Thread Response Ratio: 3.68

JDeveloper
Views: 2,322,767
Threads/Messages: 55,191/182,215
Thread Response Ratio: 2.3

Forms
Views: 2,286,956
Threads/Messages: 50,765/182,155
Thread Response Ratio: 2.58

Now there is the famous quote "lies, damned lies, and statistics" that we must keep in mind when analysing the above numbers; we shouldn't read too much into the figures. For instance we don't know when the forums started nor the statistics were started. However I think it can be clearly said that that Database and SQL/PL-SQL forums win hands down for views, threads and messages over all other forums for the current statistics.

In revisiting the ODTUG comment about Apex having the most active community derived from the OTN forum statistics, the comment was made in context of the Apex vs JDev ODTUG session. As such let's address the comment context with the OTN statistics at hand.

Looking at the numbers for the 2 relating forums for Apex and JDev, there is no clear winner. Apex has higher views than JDev, but has less threads and messages. Neither is top or bottom if you take all 3 statistics on board. So I disagree with the original comment that Apex is the leader. I think the point to make is that they are *both* very active forums, in the top 5 forums for OTN. This shows not only is the database an active area within Oracle's arena, but so are *both* Apex and JDeveloper. That's great news for the Oracle community at large.

And I think the second point to make, drawing the conclusion only from the OTN forums statistics and not looking elsewhere on the internet and user groups, the point to make is Apex is not the only tool with great community support, JDev has great support too, and so does Forms. The fact that the Apex advocates say Apex has great community support doesn't mean by inference JDev and Forms have poor community support. The OTN statistics show all are very active areas with many readers (views), many posters asking questions (threads) and many people posting answers (messages).

Caveat: Obviously community support goes beyond just the OTN forums, and I can rave on about what's happening in the JDev community as much as other technical arenas can, but for this blog post I'm focusing on the OTN forums for the bounds of the discussion.

As a third point, moving off the Oracle technology wars, the amount of activity on the OTN forums should show to non-proprietary software advocates (ie. open-source fans), that the proprietary software market has just an active community as the internet based open-source corners. Anybody that argues the big problem with software from big vendors is the locked-in black-box approach is underestimating the IT community at large in collaborating to solve common issues. Such large amount of readers and posters is a huge movement that shouldn't be discounted. And the fact that Oracle hosts these forums and Oracle employees actively participate shows a company that pays attention to its customer base.

As a final side note, these are the stats for SQL Developer:

SQL Developer
View: 685,297
Threads/Messages: 5,144/24,156
Thread Response Ratio: 3.69

Though the Threads/Messages aren't that high, the view count certainly is getting up there. Not bad for a relatively new tool.

Friday, 2 May 2008

Why neither Apex or JDeveloper are actually "free"

I've always had trouble with the word "free". Because the people who bandy it around are typically in marketing and sales (or consulting ;). And they wouldn't be in a job if they actually sold stuff for "free".

Recently PsyBlog had a well articulated blog entry describing this sales-speak: FREE! But at What Price?

This is why the marketing for Apex and JDeveloper as "free" doesn't sit well with me, and neither the zeal behind the Apex and JDev camps with the argument "but it's free!". To me free means 100% free. No conditions attached. Forever. Covers all cases for you and me and everyone else. There shouldn't be a "yeah-but" situation with free.

As such Apex strictly isn't free because the majority of users are running it on a purchased licensed Oracle database edition. Of course it's "free" if you use it on Oracle XE, but I've yet to find a single customer with a substantial Oracle install willing to downgrade to the Oracle-lite version. I'm not saying there aren't Oracle XE sites out there, but (from my subjective experience) in the scheme of things most Oracle customers aren't using Oracle XE for production purposes. The Oracle salesman already got'em.

In turn JDeveloper isn't strictly "free" either. Arguably the IDE is, but JDeveloper is coupled with ADF (not free), WebCenter (not free) and SOA (not free). If we specifically look at ADF it is "free" as long as you own an OAS license or pay a per user seat license.

A question arises though, why did Oracle bother to make these tools "free", or more specifically the marketing exercise of "free"?:

Arguably for JDeveloper it was the other competing Java IDEs, namely Eclipse and NetBeans are free, so Oracle needed to compete on the same playing field to entice those sarcastic and critical Java crowd. For Apex the reason is not so clear to me as I don't work in the Apex circles and maybe a reader can put their opinion forward. If Apex only runs on Oracle, why bother with the "free" marketing unless it's just a feel-good? Why not just say SQL and PL/SQL are also free with the database? Why did they pick Apex? To compete with JDev? I dunno.

So the next question arises, how could Oracle go about making these tools really "free" (be it a realistic dream or not)?:

For JDeveloper it's obvious. If you couple a component such as ADF with the IDE, then remove any of the OAS license caveats. Otherwise if you're going to include another part in the base download, either make it free or strip it out as a clear downloadable plug-in.

For Apex, if I use an Oracle non-XE edition (eg. SE, EE etc), and I use no features but those available to Oracle XE, and Apex, then make it free across the board, database included, regardless of edition.

Realistic: no?

Idle Friday musings?: yes.

Give you a good chuckle?: I hope so.

Oh, and I'm still waiting on Oracle to apply the same "free" marketing to Oracle Forms, be it "free" as long as you install to OAS ;)

BTW, take time to check out other articles on PsyBlog. My recent favourite: How Children Learn the Earth Isn't Flat.

Thursday, 6 March 2008

The JDev vs Apex vs Forms wars continue - now in print!

About a year ago I started a mini Internet war on which was the best Oracle development tool: JDeveloper or Apex or Forms; in the following blog post: A career path for Oracle developers - consider JDeveloper!

This was followed by a number comments and posts by Apex bloggers including Patrick Wolf, John Scott and Dimitri Gielis.

Whether you agree or not with the outcome of these discussions the topic certainly hit a nerve and is still a popular point of contention and discussion in Oracle circles.

In the famous words of Kim Jong-Il "can't we all just get along?", a number of Oracle specialists worked together to publish "The Oracle development tool review" article looking at the pros and cons of Apex, Forms and JDeveloper, to help readers decide the relative merits of each tool, in particular what they are suited to.

This article has been published in the UKOUG OracleScene Q1-2008 issue and is also scheduled for print in the Q2 IOUG Select magazine. Hopefully you're lucky enough to be a member of one of these organisations and can pick up a copy of the relevant magazine.

Very special thanks on my part must go to Grant Ronald for driving through the format of the article and providing sage advice, Wilfred van der Deijl for his input on Oracle Forms, John Stegeman for his assistance with the JDeveloper section, and Penny Cookson for the Apex section. All these people delivered a timely response to the article that allowed us to publish.

In addition thanks must go to John Scott, Dimitri Gielis, Bill Ferguson and Patrick Wolf for their contributions behind the scenes, and the UKOUG and IOUG editors and staff for their assistance on publishing this article. There's also thanks to a number of other Oracle staff who helped review the article but will remain nameless, and I'm sure I forgot somebody, so thanks to you to :)

Amazingly the original blog post was March 2007 and the final articles published in March 2008. This shows great patience, persistence and faith from all of those above and I think a great recommendation on how the Oracle community is willing to work together even though they have different opinions. Well done.

Monday, 4 February 2008

Advert: March Oracle Application Express (APEX) course in Perth

SAGE Computing Services and Penny Cookson will be running an Oracle Application Express (APEX) workshop in Perth Australia March 5th-7th.

As you may already know Penny is recognized as one of the best Oracle educators winning Oracle Educator of the Year by Oracle Magazine in 2004. Penny is also well known in the Australian Oracle community, awarded AUSOUG lifetime membership in 2003, and has won numerous conference best paper prizes. And to get the disclaimer out of the way, Penny is my boss ;)

If you're interested in all things Apex and want to pick up some down to earth training, check out the events page on our website which has more details including the agenda, location and price. We hope to see you there.

Wednesday, 14 November 2007

My OOW Unconference Session Wednesday - Take a load off

For those readers interested and are attending OOW, I'll be presenting my session "Take a load off! Load and stress testing Oracle Apex and JDeveloper web applications" at the OOW Unconference on Wednesday 4pm. Check out my Oracle Wiki page for more information. I look forward to seeing you there.

Wednesday, 24 October 2007

OOW Unconference - oh, me, me, me!

I've taken the chance to throw one of my presentations into the Oracle Open World Unconference ring and hopefully it'll be selected. You can check my session proposal on the Oracle Wiki:

Take a load off! Load testing your Oracle Apex or JDeveloper web applications

I note Andrejus Baranovskis has entered a JDeveloper paper too:

Oracle JDeveloper/ADF Real Life Story

....great to see a JDeveloper case study; more of these please Andrejus! I'm sure we're both very keen to meet our peers interested in JDeveloper too (assuming either of our sessions are selected of course ;) so please show your support if you can.

I think the Unconference is a great idea, giving lesser known mortals a chance to present something they're interested in at this mega-event. I must admit it's also an important learning opportunity on how to present in front of an American audience for myself; let's just say I need to learn to turn down some of my Australian colloquialisms ;)

I hope more attendees will take up this great opportunity, real users presenting real topics, it doesn't get much better than that.

Thursday, 18 October 2007

The zen of the Oracle development landscape

Grant Ronald has recently blogged about Modernising your Forms Applications - SOA or bust, which (once again?) revisits the perception (or myth?) that Java is the one and only future of Oracle's development. I'd like to revisit why I think this perception has come about.

I think one of the reasons (and I emphasis the word one here, there are certainly more) Oracle developers look to Java and therefore JDeveloper by default as the Oracle development future is a matter of circumstances that eventuated in the past.

Around 1998 through 2004 Java was the buzz in the development industry and it was pretty important change time for the industry. Languages were revolutionized, the web was coming to the fore, and Java is famous for being the first cab off the ranks so to speak in the Web programming world (thanks to its servlet technology - which it is now partly infamous for).

I believe many Forms programmers came to the conclusion that Forms wasn't the future because of its clunky 2 tier architecture (later hammered into 3 tier) and plain-Jane interfaces. As such they were interested in what else was happening out there way back when. It just happened that Oracle invested in JDeveloper at the time and through Oracle's marketing, coupled with the buzz around Java, it gained popularity and became the perceived future of Oracle development. Forms programmers picked up on this fact and stored it away in their little box of tricks.

Then the world moved on.

Today those same typical Forms programmers are facing the following problems:

1) The majority of Forms systems are now legacy and it has taken them a long time to come around to adopting new technologies for various reasons regardless of their originally interest in other technologies, due to organisational lack of mobility in technology adoption, lack of in-house skills, lack of interest by management to move on and so on - take your pick. So their initial interest in other technologies has been stalled by the slow moving IT corporate world. It's hard to move to a new technology when you have to fix current problems in existing legacy systems.

2) There has been an incredible amount of change in the industry between 2000 and 2007 (as usual in the IT industry). Traditional Forms and PL/SQL Oracle programmers are outside the whole web world, revolution in web scripting languages, scratch their head at the term Ajax (it's something Google does isn't it?), have very little exposure to industry wide frameworks (as separate to inhouse frameworks), and so on. Keeping up with all this change is a full time job, much easier to keep the blinkers on, do what your job demands you to do, and just keep with what you learned way back when.

3) The perception that development of Forms from Oracle has stalled.

4) A potential alternative Oracle Application Express (Apex - formally HTML DB) has only appeared to have become (again a perception thing, not necessarily reality) a viable mature development alternative more relatively recently.

....that because of these issues and perceptions (and I can't emphasis the word perception for this discussion enough - don't start arguing that's what I believe please), because typical Forms programmers haven't kept up with all the changes, because Forms is an old technology, because the marketing has at times focused on Fusion and JDeveloper and not Apex....

....that because of all these perceptions.... and how history eventuated.... and given a reluctance to give up on the potentially false or outdated perception learned way back when, that Java is still the only way to go....

.... that we see Forms programmers coming back again and again to thinking JDeveloper/Java is the future of Oracle development, and then becoming terribly disillusioned when they struggle with Java, JDev and ADF, can't see why the huge frameworks don't fit into their simple problem sets, struggle with the huge learning curve of adopting not one but several new technologies, and see an easier alternative in Apex, or scripting languages, or .Net or take whatever your pick in what you're more familiar with (it's always easier to say technology X is better than Y when you know X, but you don't know Y - that's human psychology for you).

Now given this whole discussion, does this mean I think Java and JDeveloper don't have a viable future for Oracle development? Not at all. For myself I've overcome the JDeveloper learning curve moving from Forms and I'm very excited about the future of the product. The rich AJAX components in JDev 11g ADF Faces Rich Client has me jumping up and down in excitement .... I can't believe I don't have to do hardly any JavaScript programming (don't get me started Apex programmers) at all to get these great AJAX enabled components in my web application .... Web 2.0 here we come.

For you and your organisation, like Grant says in his blog, to paraphrase, there are a number of ways to skin a cat, and what technology you pick should be dependent on your circumstances, or more precisely your organisation's circumstances. Don't invest in one of these technologies before understanding your organisation's circumstances or you will get burnt. For example investing in a huge Java project with just PL/SQL programmers without any Java training or experience will certainly burn you unless you're very lucky. And you should have known that fact before you start. That's the risk of falsely thinking Java is the holly grail of development. The same holds true for investing in an Apex project, a scripting language project and so on, there is no holly grail in development, particularly if you have none of the needed skills or the tool is badly suited to your environment. And for the record (you can quote me) there will never be a holly grail (unless you consider turning all the computers in the world off) – so get over it (the exception being of course Lisp ;).

So take Grant's point on board. Java and JDeveloper match certain problem sets and backgrounds. As does Apex as does Forms..... let your mind free itself from what you learned before and re-assess the Oracle development landscape today, to what suits your needs.

....and thus the title of this post.

Now, I seem to have broken my soapbox. Until I find another one, I'll keep the blog free of rants for a while. I think it's a time for a humorous post. Maybe I'll pick on DBAs or something fun.

Usual disclaimers to stop the unnecessary flames:

1) Please note I'm not trying to put all Forms programmers in one outdated boat. There is always a bell curve of people and skills; people who are as much as in the box as out, so put yourself in whatever box makes you happy for this discussion. When I say "typical" Forms programmers I'm drawing from my experience as a consultant and I'm referring to a generalisation of the Forms programmers I'm meeting on a day by day basis, not a specific person or group. There are certainly Forms programmers who I meet who know everything outside the Forms sphere too.

2) It's a false perception that Forms development from Oracle has stalled, as thanks to Grant's blog we can see there is still changes occurring in the Forms arena, just more subtle than before.

3) For the readers of one of my original posts A career path for Oracle developers - consider JDeveloper!, you will certainly be able to see a certain maturing in my thoughts about this, thanks to many discussions with Apex specialists, JDeveloper experts and other contemporaries.

Thursday, 4 October 2007

Apex Cascading LOVs revisited

Like the JDev community, the Apex community has plenty of blogs and example sites on achieving certain functionality which cuts down the learning curve or reinventing the wheel. I recently had the immediate requirement for a cascading LOV in Apex 2.0, and went with Carl Backstrom's example on his sample site.

For my own notes, and possibly of benefit to others, I'd like to extend Carl's example by describing the actual steps needed to implement the solution.

A cascading LOV is where a web page containing 2 poplists called Select Items in Apex, or sometimes loosely referred to as List-Of-Values (LOVs), where the 2nd poplist's values are dependent on the 1st poplist's current selection. When the user selects a value in the primary LOV, the secondary LOV should show a subset of values relevant to the primary value rather than all values.

To implement Carl's example follow these steps:

1) At the application level create an Application Item named: TEMPORARY_ITEM. Application Items are created through the Shared Components page for your application. On creating the Application Item accept the other defaults.

2) Also within the Shared Components, create an Application Process. Carl's example assumes the name of the process is "otn_Select_XML", but you can call it anything you want such as RESOURCE_LIST. On creating the Application Process, ensure the Process Point is "On-Demand", and enter the Process Text as supplied on Carl's website -- essentially an anonymous PL/SQL block with a cursor that constructs a list of items.

3) Within the Application Process change the cursor's SQL query to what ever you want your secondary poplist to show, for example as follows:

select description, code from resources where type_code = :TEMPORARY_ITEM

Note how the query needs to have a predicate (where clause) that is restricted by TEMPORARY_ITEM.

Ensure that within the cursor for loop, you change the column names for the rec pl/sql datatype to match that of your select list aliases in the cursor.

4) Again within the Shared Components, create a List of Values entry that is either a static list of values, or a query driven dynamic list, which you will use for your primary LOV. For example:

List of values name: RES_TYPE_LOV
List of values query: select name d, code r from resource_types order by 1

5) In the web page that will contain the cascading LOVs, within the page's attributes (accessible in Apex 2.0 by clicking on the Edit Attributes button near the top of the screen), in the HTML Header option, embed the JavaScript code from Carl's webpage.

Note that Carl's JavaScript example makes a number of calls to method $x which isn't supported in Apex 2.0. Thanks to the comment in this blog entry by Patrick Wolf, you may replace the call to $x with html_GetElement. If you're using a later Apex version you should be fine.

An alternative easy hack to get this working is to include the function $x in the JavaScript code you just included before the other routines:

<script language="JavaScript1.1" type="text/javascript">

/* begin $x functions */
function $x(pNd){
  try{
    var node;
    switch(typeof (pNd)){
      case 'string':node = document.getElementById(pNd);break;
      case 'object':node = pNd;break;
    default:node = false;break;
    }

  if(node.nodeType == 1){return node;}else{return false;}
  }catch(e){return false;}
}

....other functions....
</script>


The $x function here comes from htmldb_html_elements.js, presumably a JavaScript library available in later versions of Apex?

6) Note within the JavaScript code you just copied in, within the function get_AJAX_SELECT_XML, there is a call to a function htmldb_Get on approximately the 3rd line of the function. Within that function call, there is the following parameter:

'APPLICATION_PROCESS=otn_Select_XML'

otn_Select_XML refers to the Shared Component Application Process you created some steps back. Change otn_Select_XML to whatever you called the Application Process.

7) Still within the web page that you're interested in showing the cascading LOV, create your primary LOV field, a Select Item, named RESOURCE_CODE for example. Base it on the LOV you created in the previous step (ie. RES_TYPE_LOV). Accept the other defaults.

8) Now create your secondary LOV field as a Select Item, named RESOURCE_TYPE for example. Alternatively the actual item you want to be the Select Item may already be on the page as a Text Item for example, so just change it from a Text Item to a Select Item. Base the Static Item on a static list with one dummy item.

9) Once the poplist is created, invoke the editor for the primary poplist, and within the HTML Form Element Attributes option, specify a JavaScript onChange event as specified at Carl's site:

onchange="get_AJAX_SELECT_XML(this,'P37_SELECT_DROP_XML')"

You'll note the onchange code mentions P37_SELECT_DROP_XML. This in fact should be whatever you specified for your secondary Select Item's name.

....

That's all the steps you should need to do. If I've missed out any obvious steps let me know and I'll update the example for the benefit of others.

Thanks to Carl Backstrom for the original example. Note that Patrick Wolf has a more generic solution suitable to later Apex versions than 2.0 that could be better solution for your site.