ADF app param “oracle.adfinternal.view.rich.region.dynamicClientId.DISABLED”
I was asked recently to make a proof of concept for automated functional testing. The tool we decided to test is Selenium. Selenium is a really easy, powerful and fast testing framework that allows to run GUI tests in different environment (browser, os, language). I will not go into details into this post, but if you are not familiar with the tool, it provides a Firefox add-on with which you can record every UI interaction you have and save it in a test case file. After that, you might want to reopen your test case and execute it. This can be very useful for regression testing as part of your automated build process (we use maven and hudson in our case).
When you use the Firefox IDE to record your test, it adds a list of command in your FF context menu to accelerate your test case development time. However, to retrieve the UI elements on the page, Selenium is using the ids on your elements. In ADF, it is strongly suggested set the “id” attribute on every JSF component. If you plan to use selenium, this becomes essential, because you don’t want the ids to change from run to run.
I encountered a problem in the case where my test case included a region component. The region component were generating an additional id after the one I specified, for example:
<af:region id="regionX" model="#{bindings.myTaskFlow.regionModel}"/>
would sometime render as
<div id="regionX:0"></div>
sometimes as
<div id="regionX:1"></div>
After some investigation, it was discovered that the region component is adding a dynamic container clientId for every page fragment in use at the same time in the region. I guess the ADF team had a reason to add this behavior, but for the moment, I’m glad they added a parameter to disable it and avoid that thoses ids change from run to run, enabling us to build selenium test cases. Just add it to your web.xml:
<context-param> <param-name>oracle.adfinternal.view.rich.region.dynamicClientId.DISABLED</param-name> <param-value>true</param-value> </context-param>
I’m just unaware for the moment of any side effects it might have, but hadn’t find any yet.
Using Java enums as SelectItems
Since Java 5.0, enumerations are very common in J2EE application as a replacement for constants and enumerations. They are very powerful because you can use them as normal classes and they express in a very clean manner your business model constant types. For example, you can have the following very simple enum to describe payment options for your e-commerce website:
public enum PaymentType
{
MONEY_ORDER,
VISA,
MASTERCARD,
PAYPAL;
}
As a matter of fact, it would be very useful to use them in your JSF page code. Guess what, it is supported by the default converter of SelectItems in JSF 1.2 (I don’t know if previous version of JSF supported them). This mean you can strongly type your value in the bean that holds your JSF component selected value. For example:
public class PaymentController
{
public void setPaymentType(PaymentType type) { this.type=type; }
public void getPaymentType() { return this.type; }
}
And therefore can use something like this in your page:
<af:selectOneChoice label="Payment type : " value="#{pageFlowScope.paymentController.paymentType}">
<f:selectItems value="#{pageFlowScope.paymentController.paymentTypes}"/>
</af:selectOneChoice>
Then, just create a function that generate your SelectItem list from an enum type:
public class PaymentController
{
...
public List<SelectItem> getPaymentTypes()
{
List<SelectItem> items = new ArrayList<SelectItem>();
for (PaymentType type: PaymentType.values())
{
items.add(new SelectItem(type, type.toString()));
}
return items;
}
...
}
You can now add types to your enum and your UI will automatically support them. Another thing you can do is that instead of calling type.toString() as a SelectItem label, you can use a ressource bundle to specify for each of your enum values a key and a label and format them using the user’s current locale.
Feature request : pageFlowScope declarative variables
In ADF task flows, you have a way to specify IN and OUT parameters in a declarative way. You also have the possibility to declares various managed beans in a specific scope.
But sometime, you need to create an attribute on the pageFlowScope inside a Java class.
public void initTaskFlow()
{
RequestContext.getCurrentInstance().getPageFlowScope().put("foo", new Foo());
}
But unlike parameters and managed beans, those variables will not be visible to JDeveloper at design time, but it will work at runtime. It would be nice if there were a simple way to only declare a variable that will be used in the pageFlow scope such that JDeveloper doesn’t underline in yellow every references to that variable in the JSF fragment. It would also be possible to use auto-completion inside the JSF page editor.
I don’t think it would be that difficult to implement and it would also enhance the performance of the editor, IMHO.
ODTUG Kaleidoscope 2010
The 2010 ODTUG Kaleidoscope conference will be held this year in Washington D.C. from june 27th through july 1st. This is an Oracle event organized by the Oracle Development Tools User Groups where technical sessions and presentations are offered for everyone who are currently developing applications (or are planning to) with Oracle technologies. Some of the technical sessions are already announced here. The following looks pretty interesting to me:
- It’s Happening! On Event-Driven SOA (by Lucas Jellema). I never had the chance to see Mr. Jellema’s live presentation, but I would definitely go for this one because everytime I read something coming from him, I found myself learning new things in a simple way.
- Accessing the Oracle Database from Google (Apps, App Engine, Spreadsheets) (by Anjo Kolk). I found the purpose of the technical session very innovative because it is demonstrating how Google and Oracle can integrate together. I did had the time to try Google app engine yet and this might also be interesting from the perspective of seeing what you can achieve with it.
- How to Write Efficient SQL (by Jonathan Lewis). Sometimes developer are working on project that has dedicated DBAs for writing efficient SQL. Most of the time however, developers have to write SQL. I know I have a lot to learn in this area, so the technical session is definitely something I wouldn’t miss.
That’s it for now, I don’t know yet if I’ll have the opportunity to attend the conference, but if not, I will be definitely be watching for their slides online!
The Oracle ADF methodology group
I have been working with J2EE since I got out of school in may 2008 and ever since that time I have been working with the Oracle Application Development Framework (ADF) which includes some neat features like TaskFlows and regions, but some less interesting parts like Business Components (Database-centric persistance framework).
At the beginning of my journey with Oracle java entreprise stack, I had the habit to often consult and ask questions on the JDeveloper forums. It is of great help and you are often answered lighting fast by competent people (I include my colleague Simon Lessard with which I met there at the time). Be careful to stick to the ADF subject, if you have problems with Weblogic for exemple, there is a separate forum for that.
Now I come to my point! After two years working with the technology, I found myself more autonomous and I am not reading the forums anymore. However, I read daily reports from the ADF methodology group. This is a Google group lead by Chris Muir (oracle ace director) for experienced ADF developer to share their opinion on architectural and/or advanced topics like large project structure, reusability, coding standards, etc. Until now, they have produce a good set of documents that goes beyond what you would find in the developer guides. For those who are familiar with the technology, those readings are very interesting and you can contribute your knowledge and experience with the group if you’d like.
ADF obscure databinding iterator property : ChangeEventPolicy
As you might have use JDeveloper’s drag and drop functionnality once, you may have this property on some of your defined iterator bindings. This is a well documented property that caused us some big headache recently and this is the reason from the documenation:
When you create a form, setting up PPR to work for all the components in the form can be time consuming and error prone. To alleviate this, you can set the changeEventPolicy attribute to ppr on value bindings. Doing so means that anytime the associated component’s value changes as a result of backend business logic, the component will be automatically rerendered. You can also set an iterator binding’s changeEventPolicy to ppr. When you do this, any action or value binding associated with the iterator will act as though its changeEventPolicy is set to PPR. This allows entire forms to use PPR without your having to configure each component separately.
When you drop a form and elect to include navigation controls, JDeveloper automatically sets the changeEventPolicy attribute on the associated iterator to ppr. JDeveloper also sets each of the navigation buttons’ partialSubmit attribute to true. This is how command components notify the framework that PPR should occur. When you set the navigation command components’ partialSubmit attribute to true and you set the iterator’s changeEventPolicy to ppr, each time a navigation button is clicked, all the components in the form that use the iterator binding are rerendered.
It is quite something to know indeed when you have complex pages that have evolved through times (roughly 2 years old pages) that contains several fragments and regions (taskflows). You just don’t want to use that kind of “magic” in a real world application!
How to disable a commandButton with the client-side API
I have been trying to achieve the disabling of a button with Javascript lately without success mainly because the disabled property is a secured property. This mean that this property cannot be set explicitely with javascript, but it’s rather the adf framework itself that handles it. As it turned out, I couldn’t find any way to disable the button with the framework… The following piece of code is launched by a clientListener on another button, e.g.:
<af:commandButton text="Disable!" id="sourceButton"> <af:clientListener type="action" method="foo"/> </af:commandButton> <af:commandButton text="Disabled button" id="targetButton"/>
Trial #1:
function foo(event)
{
event.cancel();
var component = AdfPage.PAGE.findComponent('targetButton');
AdfUIComponent.SetDisconnectedProperty(AdfRichCommandButton, "disabled");
component.setProperty("disabled", true, false, AdfUIComponent.PROPAGATE_LOCALLY);
}
Trial #2:
function foo(event)
{
event.cancel();
var component = AdfPage.PAGE.findComponent('targetButton');
var peer = component.getPeer();
peer.SetBusy(true);
}
Trial #3:
function foo(event)
{
event.cancel();
var component = AdfPage.PAGE.findComponent('targetButton');
var peer = component.getPeer();
peer.setBusy(component,true);
}
After those 3 unsuccessful trials, I decided to do it manually and apply the CSS directly with AdfDomUtils.addOrRemoveCSSClassName( ... );. As you may have noticed, this is not very efficient because the button will still be active, to avoid that side-effect, I have also put a clientListener on that button that check for a custom property set on my component to indicate whether or not it’s a legitimate click, if not, I just cancel the event…
<af:document>
<f:facet name="metaContainer">
<af:group>
<![CDATA[<script>
function foo(event)
{
var sourceButton = event.getSource();
var targetButton = AdfPage.PAGE.findComponent('targetButton');
var domElement = AdfRichUIPeer.getDomElementForComponent(targetButton);
if (sourceButton.customDisabled && sourceButton.customDisabled === true)
{
AdfDomUtils.addOrRemoveCSSClassName(false, domElement, AdfRichUIPeer.DISABLED_STYLECLASS);
targetButton.customDisabled = false;
}
else
{
AdfDomUtils.addOrRemoveCSSClassName(true, domElement, AdfRichUIPeer.DISABLED_STYLECLASS);
targetButton.customDisabled = true;
}
event.cancel();
};
function bar(event)
{
var source = event.getSource();
if (source.customDisabled === true)
{
event.cancel();
}
};
</script>]]>
</af:group>
</f:facet>
<af:form>
<af:commandButton text="Disable!" id="sourceButton">
<af:clientListener type="action" method="foo"/>
</af:commandButton>
<af:commandButton text="Disabled button" id="targetButton">
<af:clientListener type="action" method="bar"/>
</af:commandButton>
</af:form>
</af:document>
Not elegant, but achieving what I need!
An attemps to remotely debug an applet with JDeveloper & Weblogic
First, I wanted to enable debugging inside weblogic. So I opened the file : %JDEV_USER_DIR%\11.1.1\system11.1.1.0.31.52.05\DefaultDomain\bin\setDomainEnv.cmd and found the pieace of script which set the debug flag to false if in production:
if '%PRODUCTION_MODE%'=='true' ( set debugFlag=false set testConsoleFlag=false set iterativeDevFlag=false )
I added an else condition to enable debugging in development mode (which is the default mode for jdev’s enbedded Weblogic) :
else ( set debugFlag=true )
but the result of starting the server was :
ERROR: Cannot load this JVM TI agent twice, check your java command line for duplicate jdwp options.
This error is documented here as a known issue for jdev 11.1.1.0.2 (the exact version I’m using).
So for the moment I am kind of stuck… metalink request pending!
The other thing to do is to open the Java Option panel (Configuration panel in Windows XP) and add the following line as a JVM argument (under the Java tab):
-Djava.compiler=NONE -Xnoagent -Xdebug -Xrunjdwp:transport=dt_shmem,address=8453,server=y,suspend=n
volatile vs synchronized
One of my more experienced colleague recently did a code review for an asynchronous task scheduler service I developed and came with the suggestion to add some kind of locking mechanism to a status variable I was updating inside a task. As those tasks were asynchronously executed inside the same virtual machine, it is indeed something obvious I forgot (Lacking time is always a poor excuse I know…). So he suggested me to either add synchronized to my getter and setter for the status field, or to add the java volatile keyword on the private member variable. I had some serious doubt back then about the volatile approach because I could not remember seeing any piece of code that was using it (I’m still young!) and I remembered some warning about using that by some teachers back in school. So digging for the distinction between using volatile against synchronized brought me to that wonderful explanation by Brian Goetz.
It is somewhat complex at first, but it then came all clear at the end of the article. He explains the correct premises for using volatile:
You can use volatile variables instead of locks only under a restricted set of circumstances. Both of the following criteria must be met for volatile variables to provide the desired thread-safety:
- Writes to the variable do not depend on its current value.
- The variable does not participate in invariants with other variables.
Basically, these conditions state that the set of valid values that can be written to a volatile variable is independent of any other program state, including the variable’s current state.
I was then surprised then the 5 patterns for using volatile over synchronized, which included directly my use case for a shared status variable:
- Pattern #1: status flags
- Pattern #2: one-time safe publication
- Pattern #3: independent observations
- Pattern #4: the “volatile bean” pattern
- Pattern #5: The cheap read-write lock trick
The 5th pattern is interesting because it makes read very fast while providing a better protecting for writing operations. I was also amused by the 4th pattern, which I think may be useful for multi-user web applications dealing with realtime data.
Overall, this lesson made me realized that the Java Memory Model spec is something I should really be reading someday as well as some of the code of the java.util.concurrent package.
