|
Wednesday, September 30, 2009 |
This is a reminder that I've stopped blogging on this site and moved my blog to http://blogs.oracle.com/smuenchadf
I've just posted there a list of where you can find me during Oracle OpenWorld 2009 coming up in October...
Please update your bookmarks and/or blog readers to the new blog URL. Thanks.
10:06:18 AM
|
|
|
Friday, September 11, 2009 |
After recently receiving word from my current blog hosting company that their site will be closing at the end of the year, I need to begin moving over into my new home on Oracle Blogs. I will continue my blogging about JDeveloper and ADF over there at http://blogs.oracle.com/smuenchadf/ I'm still figuring out how to move all the existing content, but I started by moving the most popular page on my blog which is the page of Not Yet Documented Examples (http://blogs.oracle.com/smuenchadf/examples/). Please add this new blog to your blog readers, or bookmark the new site URL. Thanks for visiting.
10:14:34 AM
|
|
|
Thursday, September 03, 2009 |
My Easier Interactive Data Entry article in Oracle Magazine explains the new Auto-PPR feature in JDeveloper 11g. This feature makes it possible for you to avoid manually setting the "partialTriggers" property on UI components in most cases. With the new Auto-PPR feature enabled, the ADF framework automatically "repaints" any UI components whose data bound attribute values have changed, regardless of how they have been changed (by the user, by a calculated attribute's dependent attribute's value changing, by programmatic business logic, etc.)
I recently noticed, however, that the JDeveloper 11g R1 (11.1.1.1.0) design time incorrectly shows the "ppr" as the default setting for the ChangeEventPolicy of an iterator binding. The default of this property is still "none", even though you see "(default) ppr" in the property inspector.
In short, if you want to use the Auto-PPR feature in 11g R1, then just as you did in previous JDeveloper 11g releases, manually set the ChangeEventPolicy of the iterator binding to the value "ppr" yourself.
11:52:23 PM
|
|
I've added example# 149 to show the correct syntax to use to reference custom view row and view object methods from the Groovy expression of a calculated view object attribute.
10:58:14 PM
|
|
I've added example# 148 to illustrate a technique to declaratively initialize the bind variables of a view object at task flow startup time.
10:56:56 PM
|
|
|
Wednesday, September 02, 2009 |
I've added example# 147 which illustrates a technique for an application module consisting of all static and/or programmatic VOs to run with no database connection. It illustrates a number of lesser-used framework extension override classes to get the job done.
2:12:25 AM
|
|
|
Thursday, August 20, 2009 |
We added the createRootApplicationModule() API (in the oracle.jbo.client.Configuration class) to simplify acquiring an application module from the pool for brief programmatic manipulation before it is released back to the AM pool in unmanaged/stateless mode by a required call to the corresponding releaseRootApplicationModule() API. This simple method is a two-edged sword, however. It makes its intended use case very easy to accomplish, but frequently I'm observing that its ease of use tempts developers into using it incorrectly.
The context where I see this method most commonly misused is in JSF backing beans. Developers think, "I need to invoke a method on the client interface of my application module", and often the first thing that pops into mind for how to access an application module instance is the Configuration.createRootApplicationModule() API. However, this method should never be called from a backing bean. The reason it should not be used is that it leads to creating additional application module instances which are distinct from the AM instance that is automatically checked out and checked in for you by the ADF data binding layer for use by your UI pages and task flow method call activities. At a minimum, this can lead to an incorrectly functioning application (when the custom code you run actually happens on a different AM instance that the one your UI page is using) or at worst can least to performance and memory problems if your backing bean code calls Configuration.createRootApplicationModule() without ever calling releaseRootApplicationModule().
So, to reiterate, never call Configuration.createRootApplicationModule() in a backing bean.
Instead, to invoke a client interface method on an application module, view object, or view row, you should use a ADFM action binding to invoke it declaratively instead. This way requires no code, often obviating the need for any backing bean in the first place. If you do need to write some custom backing bean code (for example to perform programmatic manipulation of UI components before or after invoking the client interface method), then your backing bean code should exclusively invoke the client interface method on the application module using the action binding. One key reason to use the action binding even from your own custom code is to ensure that any exceptions are handled in the same, consistent way as if ADF had invoked the method declaratively.
You should ensure that your backing bean is invoked in a context where a pageDef has been defined (for example, the pageDef for a page or pageFragment, or the pageDef associated with a task flow method call activity), and then your backing bean code can invoke the method action using code like this:
public ... yourBackingBeanMethod(...) { /* Custom code before invoking the method action goes here... */
/* Get the current binding container */ BindingContainer bc = BindingContext.getCurrent().getCurrentBindingsEntry(); /* Lookup and invoke the action binding named "yourMethodName" */ bc.getOperationBinding("yourMethodName").execute();
/* Custom code after invoking the method action goes here... */
}
The "yourMethodName" above is the name of the action binding (also called an "operation binding" in JSR 227 parlance), which the JDeveloper 11g design time typically creates with the same name as the method being invoked. The BindingContext.getCurrent().getCurrentBindingsEntry() accesses the current binding container without having to parse the EL expression "#{bindings}", and then the getOperationBinding() method looks up the action binding by name, and the execute() method invokes the binding. The above works great for a void method being invoked (with no return value), but if you are calling a method that returns a result and want to work with the result, just change the code to look like this: this:
public ... yourBackingBeanMethod(...) { /* Custom code before invoking the method action goes here... */
/* Get the current binding container */ BindingContainer bc = BindingContext.getCurrent().getCurrentBindingsEntry(); /* Lookup and invoke the action binding named "yourMethodName" */ Object retVal = bc.getOperationBinding("yourMethodName").execute();
/* Do something with 'retVal' here */
/* Custom code after invoking the method action goes here... */
}
Section 9.10.3 How to Access an Application Module Client Interface in a Fusion Web Application in the 11g R1 developer's guide explains a technique for accessing the AM client interface directly by accessing the data control from the method action and calling the getDataProvider() on it to cast the AM instance to its client interface. However, I'm working to get that documentation section changed to reflect the advice above since invoking the client interface directly does not handle exceptions in the same consistent way (using the ADFM Exception Handler described in section 27.9 Customizing Error Handling of the dev guide).
In the case of an ADF Task Flow method call activity, the easiest way to invoke a custom method exposed on one of your component's client interface is to simply drag that method from the Data Control Palette and drop it onto the method call activity. No backing bean needed. If you do need to augment the method call with some custom code, you can first do this drag/drop operation, then adjust the method call activity to call a backing bean that used the technique described above to perform custom code before and/or after invoking the method action.
A note for developers using JDeveloper/ADF 10.1.3: The BindingContext.getCurrent().getCurrentBindingsEntry() call is new in 11g. In the 10.1.3 release you can follow the above advice but will need to access the binding container by evaluating the "#{bindings}" expression, perhaps using some helper code like the EL.get() method from my favorite EL helper class.
7:14:36 PM
|
|
|
Monday, August 17, 2009 |
The September/October 2009 issue of Oracle Magazine is now available online, and along with it the next installment in my Developer: Frameworks series:
NOTE: The example exercises described in the article assume that you are using the new 11.1.1.1.0 release of JDeveloper 11g, since the UI for creating a breakpoint was slightly changed in this release. The same basic techniques work in earlier releases, but if you want to follow the step-by-step instructions, it will be best to use the very latest release.
4:42:59 PM
|
|
|
Friday, August 14, 2009 |
I added example#146 that illustrates how to programmatically manipulate an af:table component's QBE filter search fields.
5:51:10 PM
|
|
Kuba blogs a link to an OTN article describing a new, declarative feature in JDeveloper / ADF 11g release 11.1.1.1 to automatically warn users before they navigate away from a page with pending data changes. This was a commonly requested feature that we finally had a chance to make a simple, declarative option.
5:02:23 PM
|
|
|
Monday, July 27, 2009 |
When you migrate your ADF 11.1.1 application to 11.1.1.1, if you happen to have attributes with names like Category, Reference, PropertyValue, Sequence, or several others, then you may notice that your application malfunctions where it references these attribute names in Groovy scripts/expressions. One situation where the problem occurred for me was in a bug tracking application with cascading LOVs. I had three fields with LOVs configured -- Product, Category, Subcategory -- and the view accessor used by the Subcategory LOV contained bind variable Groovy expressions of:.
- BindVarProduct => Product
- BindVarCategory => Category
When I ran the application in ADF 11.1.1.1.0, the Subcategory LOV never returned any rows. In the debugger, I was able to set a breakpoint in the bindParametersForCollection() method of ViewObjectImpl to study the values of the bind variables for the view accessor's query, and I noticed that the BindVarCategory bind variable was being assigned a value of type java.lang.Class (the object representing groovy.lang.Category class) instead of a String with a value like "SOME_CATEGORY", so of course the query returned no rows.
Groovy issue# 3451 complains about a change in behavior between Groovy version 1.5.4 used by ADF 11.1.1.0.x and the Groovy 1.6.0 release used by ADF 11.1.1.1. Groovy 1.6 changed the order of resolution for a symbol like Category to first resolve to the name of a class visible in the current classloader before giving a scripting client like ADF BC a chance to resolve the name to the value of a row attribute.
The workaround is to change the Groovy script to reference adf.object.Category instead of just Category (or whatever the offending attribute name is). The complete list of attribute names that can cause problems includes the name of every class in the java.lang and the groovy.lang packages (which are auto-imported by the Groovy runtime). You can consult the text of bug# 8732845 in Metalink (or the JavaDoc for these two packages) for a complete list of class names that can cause problems in Groovy scripts if used as attribute names and referenced in an unqualified way.
4:54:13 PM
|
|
In releases prior to 11.1.1.1.0, if you used custom ADFBC domain classes to encapsulate common datatype validation into a reusable value class, you needed to create a custom JSF converter to handle data entry in your JSPX pages. Failure to do so would result in errors like:
Cannot convert 11.1.2.3.4 of type class java.lang.String to class fusion.bugtracker.model.datatypes.common.OracleVersionNumber
Now in 11.1.1.1.0, ADF Faces registers a built-in converter you can use for this purpose. Just reference the converter with id "oracle.genericDomain" like this:
<af:inputText value="#{bindings.ProductVersion.inputValue}" label="#{bindings.ProductVersion.label}" contentStyle="width:200px" required="#{bindings.ProductVersion.mandatory}" columns="#{bindings.ProductVersion.displayWidth}" id="it2"> <f:converter converterId="oracle.genericDomain"/> <f:validator binding="#{bindings.ProductVersion.validator}"/> </af:inputText>
2:05:20 PM
|
|
|
Sunday, July 26, 2009 |
|
Monday, July 13, 2009 |
I've added example #145 to illustrate how, using some new capabilities implemented in the new 11.1.1.1.0 release, you can easily (and declaratively) expose selectBooleanCheckbox controls in an editable table without having to introduce your own boolean transient attribute (as used to be required).
Note: The example requires the new 11.1.1.1.0 release to work correctly.
5:40:12 PM
|
|
|
Saturday, July 11, 2009 |
While I was out for some much-needed vacation, our JDeveloper / ADF 11.1.1.1.0 release went production. Some relevant links:
Enjoy
1:00:09 AM
|
|
|
Thursday, June 25, 2009 |
Jan Vervecken wrote me to let me know of a new effort to create screencast movies of interesting ADF "how to" articles over at http://wiki.oracle.com/page/Watch+It+ADF
The first two screencasts produced follow along with a couple of recent Oracle Magazine Developer Frameworks articles I wrote.
Thanks for the tip, Jan.
10:59:44 AM
|
|
|
Saturday, June 06, 2009 |
|
Tuesday, April 14, 2009 |
Grant blogs about a new whitepaper he's written on Groovy support in Oracle JDeveloper / ADF. I reviewed a draft of it and think it will be useful to everyone using Oracle ADF 11g.
11:44:25 PM
|
|
|
Friday, April 10, 2009 |
Due to lack of bandwidth, I don't get much of a chance to experiment with the finer points of our ADF Rich Client framework, but I always wondered how you'd implement the kind of auto-suggest (reduce-the-choices-as-the-user-types) type of functionality. As usual, Frank takes the time not only to figure out the implementation but to write it up nicely. Check it out if you've been wondering how to achieve this type of functionality in ADF 11g.
http://www.oracle.com/technology/products/jdev/tips/fnimphius/suggest/autosuggest.html
It's just one of many great article's on Frank's Code Corner on OTN...
12:42:09 AM
|
|
|
Monday, April 06, 2009 |
|
Friday, March 20, 2009 |
I've added example #144 to illustrate how to customize the application-level error handler to support informational messages (in addition to the default support we provide for warnings and errors).
3:06:06 PM
|
|
|
Sunday, March 01, 2009 |
The March/April 2009 Oracle Magazine issue is now available, and along with it the latest installment of my Developer Frameworks series:
A Ride at the OK (or Cancel) Corral Configure nested transactions using Oracle ADF task flows.
Enjoy.
10:56:54 AM
|
|
|
Sunday, February 01, 2009 |
In response to a question asked on the dBforums website, I created a little screencast to show the simple steps to go from a SQL query that you've got working in SQL Developer to a JSF page that display its results and allows the user to enter values for its bind variables.
11:27:05 AM
|
|
|
Friday, January 30, 2009 |
I wanted to call your attention to a fairly new section on OTN about ADF Patterns and Best Practices. Just yesterday I found David Giammona's January 2009 document there on:
to be very helpful to something I was working on.
3:02:07 PM
|
|
I often find it handy to use JDeveloper 11g's SQL worksheet toolbar menu to quickly pop open a window where I can play with SQL statements. As shown in the screen shot below, the toolbar button pops down to show you all your IDE-level database connections, as well as application resources database connections for open workspaces. After you pick which connection you want to work with, a SQL Developer worksheet window opens for you to experiment with.
One frustrating thing, if you happen to use the SQL worksheet for quick SQL testing like I do, is that when you're done with your experiments and close the window JDeveloper prompts you to save the file. In my usage pattern, I almost never want to save the contents, so this always meant more clicks that I wished I didn't have to make.
I wanted to share a tip I learned recently about an IDE-level tools preference below that comes to the rescue if you happen to use the SQL worksheet this way. After choosing {Tools | Preferences...} select the Database > Worksheet Parameters section and uncheck the Prompt for Save file on Close checkbox. Voila! No more nagging when you close the worksheet.
3:00:15 PM
|
|
© Copyright 2009 Steve Muench.
|
|