JDeveloper/ADF 11g Technical Preview Tips and Tricks

Send me a mail
 Dive into Oracle ADF   Click to see the XML version of this web page.   (Updated: 3/30/2009; 2:36:28 PM.)
Tips and tricks from Steve Muench on Oracle ADF Framework and JDeveloper IDE

JDeveloper/ADF 11g Technical Preview Tips and Tricks

I will update this page with tips and tricks for using the JDeveloper/ADF 11g Technical Preview 2 (build 4684) released on September 27th, 2007.

Checkout the long list of new features that we've been working on to bring you

  • Visit the OTN JDeveloper 11g Tech Preview page to find links to download the product and view a growing list of online screencast demonstrations

  • Read the Oracle ADF 11g Primer document to understand how many of the new ADF pieces fit together for Fusion web application development

  • Try the built-in JDeveloper/ADF 11g Fusion Web Application tutorial, available as built-in cue cards in the product. To access it:

    • Select Help | Start Page

    • Click on the Build Fusion Web Applications link in the Tutorials section to start the step-by-step cue card tutorial

  • See the Install Guide as well as the Release Notes and Release Notes Addendum for additional information on known issues


Tips

Improve Embedded OC4J Startup Time

To improve the startup time of embedded OC4J, to workaround a performance bug we found after shipping the Technology Preview 2 release, do the following:

  1. Ensure you've run the embedded OC4J server at least once after first installing JDeveloper 11g Technology Preview 2
    • You can do this by running any servlet, EJB session bean, or JSP page
  2. Find your JDeveloper system settings directory (system11.1.1.0.20.46.84 )
    • If you start JDeveloper 11g with the -singleuser command line switch, then it will be in the JDev installation home directory
    • Otherwise, it will be in the user profile directory on your operating system, under a JDeveloper subdirectory.
  3. In the system11.1.1.0.20.46.84 directory, change directory to the subdirectory named o.j2ee/embedded-oc4j/config
  4. Edit the java2.policy file
  5. Comment out the following entry by adding a /* on the line before it and */ on the line after it:

So that this entry in your java2.policy file will now look like this:

/*
grant codeBase "
file://generated/by/oracle.j2ee.connector.proxy.BCELProxyClassLoader" {
    permission java.security.AllPermission;
};
*/

The next time you start the embedded OC4J, it should be about 20 seconds faster.

Avoiding "Fetching Data..." in Rich Table for Initial Page Render

If you want your page that uses an <af:table> to initially render data instead of first rendering the outline of the table, then asynchronously fetching the data using a postback, then set the contentDelivery="immediate" attribute on the <af:table> component.

Referencing Entity Object Methods in Groovy Validation Expressions

In order to call methods on the current entity instance you'll need to reference the source property of the current object that gives you access to the entity instance being validated. For example, imagine that your entity object had the following four methods in it:

public boolean isNewRow() {
System.out.println("## isNewRow() accessed ##");
return true;
}

public boolean isNewRow(int n) {
System.out.println("## isNewRow(int n) accessed ##");
return true;
}
public boolean testWhetherRowIsNew() {
System.out.println("## testWhetherRowIsNew() accessed ##");
return true;
}
public boolean testWhetherRowIsNew(int n) {
System.out.println("## testWhetherRowIsNew(int n) accessed ##");
return true;
}

Then the following Groovy validation condition would trigger them all (one of them being triggered twice!)...

newRow && source.newRow && source.isNewRow(5) && source.testWhetherRowIsNew() && source.testWhetherRowIsNew(5) 

Notice the slightly different syntax for the reference to a method whose name matches the JavaBeans property getter method naming pattern. That is, if a method is a non-boolean type and the method name is getXyzAbc() with no arguments, then you access its value as if it were a property named xyzAbc. For a boolean-valued property, the same holds but the JavaBean naming pattern for the getter method changes to recognize isXyzAbc() instead of getXyzAbc().

Notice that both newRow and source.newRow work to access the boolean-valued, JavaBeans getter-style method that has no arguments. If the method on your entity object does not match the JavaBeans getter method naming pattern, or it takes one or more arguments, then you must call it like a method using its complete name as shown in the example.

Running the example above and forcing entity validation to occur, you would see the following diagnostic output to the log window:

## isNewRow() accessed ##
## isNewRow() accessed ##
## isNewRow(int n) accessed ##
## testWhetherRowIsNew() accessed ##
## testWhetherRowIsNew(int n) accessed ##

Tuning Entity Associations Using Custom View Objects

When you traverse entity associations in your code, if the entities are not already in the cache, then ADF Business Components will perform a query to bring the entity (or entities) into the cache. By default, the query performed to bring an entity into the cache is the "find-by-primary-key" query that selects values for all persistent entity attributes from the underlying table. If you find you perform a lot of programmatic entity association traversal, you could find that retrieving all the attributes might be heavy-handed for your use cases. Entity associations in ADF 11g support the ability to associate a custom, entity-based view object with either the source entity or target entity in the association (or both). The primary entity usage of the entity-based view object you supply must match the entity type of the association end for which you use it. Of most interest to developers is the fact that this custom view object's query can include fewer columns and it can include an ORDER BY statement. This allows you to control how much data is retrieved when an entity is brought into the cache due to association traversal, as well as the order in which any collections of related entities will appear.

Use SingleUser Mode If Your Windows is Installed on Drive Other Than C:

OTN Users have reported problems running JSPX pages inside JDeveloper 11g on the embedded OC4J server if they run on a machine where the Windows operating system is installed on a drive other than the default "C:\" drive. The workaround is to start JDeveloper 11g with the -singleuser command line flag so that JDeveloper creates is system directory as a subdirectory of the installation directory rather than in the %USERPROFILE%Application DataJDeveloper directory

Groovy Scripting Tips for ADF Business Components

ADF BC now provides integrated support for Groovy, a dynamic scripting language for the Java platform standardized in JSR 241. Groovy in ADF Business Components is dynamically compiled and evaluated at runtime. The JDeveloper/ADF 11.1.1.0.0 Technology Preview release is using the Groovy 1.0 release. The primary benefits of the ADF Business Components Groovy integration are:

  • Customization - because it is dynamically compiled, Groovy script can be stored inline in our XML and is eligible for customization
  • Simplification - Groovy supports object access via dot-separated notation

    so we can support syntax like:

    Salary * 0.10

    instead of

    ((Number)getAttribute("Sal").multiply(new Number(0.10))

    in Java in a calculated field expression,  or syntax like:

    PromotionDate > HireDate

    instead of

    ((Date)getAttribute("PromotionDate")).compareTo((Date)getAttribute("HireDate")) > 0

    in a validation rule.

You can use Groovy script expressions in the following different places in ADF Business Components:

  • Validation - you can use a Groovy script (that returns true or false) for declarative validation.
  • Validation Error Messages - you can use Groovy expressions to substitute the named tokens (e.g. "The value {val} is not legal."}) in the error message
  • Bind Variables - you may define the value for a bind variable using a groovy script expression
    • Default Values
    • View Criteria
  • View Accessor Bind Variable Values - you may supply bind variable values in a view accessor using Groovy script
  • Attributes - you may base a transient attribute on a Groovy script
  • Attribute Default Values - you may define a default value expression on an attribute using groovy script

Keywords and Available names

The current object is passed in into the script as the 'this' object so to reference any attributes inside the current object, simply use the attribute name. For example, in an attribute-level or entity-level Groovy Script Expression validator, to refer to an attribute named "Ename", the script may say simply reference Ename.

There is one top level reserved name adf to get to objects that the framework makes available to the groovy script. Currently these objects include:

  • adf.context - to reference the ADFContext object
  • adf.object - to reference the object on which the expression is being applied.
  • adf.error - in validation rules, to access the error handler that allows the validation expression to generate exceptions or warnings

You can also reference the current date (time truncated) or current date and time using the expressions:

  • adf.currentDate
  • adf.currentDateTime

All the other accessible member names come from the context in which the script is applied:

  • Bind Variable - the context is the variable object itself. You can reference the structureDef property to access other information as well as the viewObject property to access the view object in which the bind variables participate.
  • Transient Attribute -  the context is the current entity or view row. You can reference all attributes by name in the entity or view row in which it appears, as well as any public method on that entity or view row. To access methods on the current object, you must use the adf.object keyword to reference the current object like this adf.object.yourMethodName(...) The adf.object keyword is equivalent to the this keyword in java.  Without it, in transient expressions, the method will be assumed to exist on the dynamically-compiled Groovy script object itself.
  • Expression Validation Rule : the context is the validator object (JboValidatorContext) merged with the entity on which the validator is applied. You can reference keywords like:
    • newValue - in an attribute-level validator, to access the attribute value being set
    • oldValue - in an attribute-level validator, to access the current value of the attribute being set
    • source - to access the entity on which the validator is applied in order to invoke methods on it (accessing simply accessing attribute values in the entity does not require using the source keyword)

Usage Notes

This scripting logic works like JSF Expression Language (EL)  in the sense that you can use a dot-separated path to reference properties of an object and its nested objects. However one big difference is that if a Java object implements the java.util.Map interface, then only the map lookup is performed (instead of the bean style property lookup). For Maps that extend ADF's JboAbstractMap class however, you get the same EL-style behavior: map lookup first followed by bean lookup. Additional usage notes include:

  • All Java methods, language constructs and groovy language constructs are available in the script.
  • You can use built-in aggregate functions on ADF RowSet objects by referencing the functions sum(), count(), avg(), min(), and max(). They accept a string-value argument that is interpreted as a Groovy expression that gets evaluated in the context of each row in the rowset as the aggregate is being computed:

    rowSetAttr.sum("GroovyExpr") -- e.g. employeesInDept.sum("Sal") or employeesInDept.sum("Sal!=0?Sal:0 + Comm!=0?Comm:0")
    rowSetAttr.count("GroovyExpr")
    rowSetAttr.avg("GroovyExpr")
    rowSetAttr.min("GroovyExpr")
    rowSetAttr.max("GroovyExpr")

    on a RowSet object where expr can be any groovy expression that returns a numeric value (or number domain).
  • Use the return keyword just like in Java to return a value, unless it's a one liner expression in which case the return is assumed to be the result of the expression itself (like "Sal + Comm" or "Sal > 0").
  • Use the ternary operator to implement functionality like SQL's NVL() function. For example: Sal + (Comm != null ? Comm : 0)
  • Do not use { } to surround the entire script. Groovy treats { as a beginning of a Closure object - See groovy documentation for more on Closures.
  • Any object that implements oracle.jbo.Row, oracle.jbo.RowSet or oracle.jbo.ExprValueSupplier is automatically wrapped by the ADF runtime into a Groovy "Expando" object to extend the properties available for those objects beyond the bean properties (to enable easy reference to ADF row properties even if no Java class is generated, and as a way to avoid introspection for most used names).

Examples

This is a simple example of a view-object bind variable default expression that references the value of a key named FunctionalRole from the ADFBC Session's user data hashtable:

viewObject.DBTransaction.session.userData.FunctionalRole

This is a simple example of an entity-level Groovy script expression validator. The strings ExcGreaterThanApplicationLimit, WarnGreaterThan5000, and ExcTooLow are message bundle keys to error/warning messages.

if (Sal >= 5000) {
  long highSal = Long.valueOf(source.DBTransaction.rootApplicationModule.properties.salHigh)
  if (Sal >= highSal) {
    adf.error.raise("ExcGreaterThanApplicationLimit")
  } else {
    adf.error.warn("WarnGreaterThan5000")
  }
}
else if (Sal <= 1000) {
  adf.error.raise("ExcTooLow")
}
return true

Avoid Typing SQL Altogether with New SQL Independence View Object Mode

ADF 11g introduces a new SQL mode for view objects to complement the existing "Normal Mode" and "Expert Mode". The new mode is called "SQL Independence Mode" in the 11g Tech Preview release (although the name might change by production). When a view object is in SQL Independence Mode, you cannot type hand-written SQL for the WHERE clause or ORDER BY clause. Instead, you define the where clause using a declarative view criteria and define the order by clause by picking view object attribute names. At runtime, these are translated into SQL by the current SQLBuilder implementation you are running with (Oracle, SQLServer, DB2, etc.).

Running or Debugging an Application Module Using the ADFBC Browser

To run or debug an application module using the ADFBC Browser, just select the application module in the Application Navigator and choose either Run or Debug from the right-mouse context menu. These options replace the former Test... choice that you used in JDeveloper 10.1.3.

Removing an Application from the IDE

To remove an application from the IDE, select the "Remove Application from IDE..." menu choice on the drop-down menu to the right of the Application Navigator's current application selector dropdown list.

Deployment Profiles Have Moved Into the Project Properties Dialog

You can create and edit deployment profiles for a project by selecting the "Deployment" category in the project properties. A new "Deploy >" menu appears on the right-mouse context menu of the project to give you access to deploy any of its deployment profiles.

Data Control Palette Has Moved Into the Application Navigator

The data control palette is now a collapsible "accordion" zone in the Application Navigator. In addition to collapsing/expanding accordion zones, if you drag the accordion zone header you can control the vertical sizing of the zone and have multiple zones open at once. To minimize an accordion zone, use the drop-down menu choice available off the "down-facing arrow" on the right side of the accordion header. To reshow a minimized accordion zone, click the "..." section at the bottom of the panel and select the name of the minimized accordion zone to restore.

Define Alternate Unique Keys for Entity Objects and View Objects

One of the many new features in ADF Business Components in 11g is the ability to define alternate unique keys for entity objects. For example, if you want to be able to locate a Dept entity instance based either on the unique Deptno (primary key) as well as the Dname (alternate key), you can define an alternate key for the Dname attribute. You can then use this named alternate key in the new findByAltKey() API on EntityDefImpl as well as reference it in a UniqueKey validator to automatically enforce that two departments cannot have the same Dname value. At the view object level, for entity-based view objects, you can define alternate keys by referencing the desired alternate key definitions of underlying entity objects. There is a new findByAltKey() API at the view object level as well.

Recommended resource bundle mode for ADF Business Components projects

JDeveloper 11g supports a new project-level preference for resource bundles on the Resource Bundle panel of the project properties dialog. For this preview release, after creating a new project in which you will create business components, we recommend changing the project-level resource bundle preference to the setting "One Bundle per File". This will cause ADF Business Components to create a single resource bundle for each component that requires translatable strings for UI hints (label, tooltip, format mask, etc.) or validation error messages. Use of the the "One Bundle Per Project" option generally works, however in this technology preview release there is a known issue that UI hints for attributes of the same name in two different components will clash in the single, global message bundle.

Component and attribute renaming disabled in this release

In this technology preview, it is not possible to rename ADF Business Components or to rename entity object or view object attributes. This will be enabled in a later build.

Understanding how ADF Business Components uses application resource connections

In previous releases of JDeveloper, you would create IDE-level database connection definitions in the Connection Navigator. Then, these connections were available for reference by any ADF Business Components application module configurations when defining JDBC URL-type connections. In JDeveloper 10g and previous versions, connection definition were not captured as a proper artifact of your application, so if a colleague were to open your project on another machine, they would need to manually create the appropriately-named IDE-level connection definition in there instance of JDeveloper before the application would run.

To simplify this use case, JDeveloper 11g captures connection definitions as an application-level resources that "live" together with your other application files. When you initialize a project for using ADF Business Components, the connection definition you pick is one of these "Application Resources" connections. If no application-resource connection yet exists, you can define a new application-resource connection by clicking (New...) from the "Initialize Business Components" dialog.

To see and edit the properties of application-level resource connections, expand the "Application Resources" accordion panel in the Application Navigator and expand the "Connections" folder. To see/change the properties of an existing application-level connection, select it in this section of the Application Navigator and choose Properties... from the context menu.

Note that you can still define IDE-level connections as before, and reuse them in new ADF Business Components projects that you create, however the procedure to create them has changed slightly. To define an IDE-level connection database definition, choose View | Resource Palette to see the Resource Palette and then click on the "folder-with-plus-sign" icon next to the search field at the top of the palette to select New Connection > Database from the dropdown menu. Once you've defined IDE-level connections in the Resource Palette, you can:

  • Browse their contents in the Database Navigator by selecting View | Database Navigator
  • Add a copy of the connection definition to the current application as an application resource connection by selecting it in the Resource Palette and choosing Add to Application from the context menu.

Start OC4J 11g Embedded Server in Standalone Mode Instead of Using ADF Runtime Installer on OC4J 11g Extended Tech Preview

As expected, you can run and debug ADF 11g applications on the embedded OC4J server. However, if you want to test deploying an ADF 11g application to an external OC4J instance, we recommend using the <JDEVHOME>/jdev/bin/start_oc4j script to startup the embedded server in standalone mode.  NOTE: If you attempt to download the separate OC4J 11g "extended" Technology Preview release (oc4j_11110_preview.zip) and use the JDeveloper 11g Tech Preview "ADF Runtime Installer" to attempt to install the ADF 11g runtime into that OC4J instance, the procedure appears to succeed, however the ADF framework is not completely installed and deployment  of ADF applications to this OC4J container do not function correctly. (Bug 6038667)

See Configuring Standalone OC4J 11g Technology Preview Release for ADF 11g Application Deployment on OTN for step-by-step instructions on configuring a standalone OC4J 11g Technology Preview to support deployment and running of an ADF 11g application if you really need to test in this configuration.

Starting OC4J 11g Embedded Server in Standalone Mode Causes Subsequent ADF BC JAAS Authentication to Fail

When you startup OC4J 11g Embedded Server in Standalone mode, it modifies the <JDEVHOME>/j2ee/home/config/system-jazn-data.xml file in such a way as to prevent subsequent ADF Business Components JAAS authorization attempts to fail when run inside the JDeveloper IDE. For example, if your application module uses JAAS authentication with the jbo.security.enforce property set to true  then after starting up the embedded OC4J server in standalone mode subsequent attempts to run the ADF Business Components Tester for that application module will fail to authenticate properly. A similar problem would affect JUnit tests using an ADF application module requiring authentication, as well as an ADF Swing client requiring authentication. The workaround is to re-extract a copy of the original ./j2ee/home/config/system-jazn-data.xml file from the JDeveloper 11g Tech Preview zip file, and copy it to the <JDEVHOME>/j2ee/home/config directory. For convenience, I've staged a copy of this original system-jazn-data.xml file here. (Bug 5752851)

 

 



© Copyright 2009 Steve Muench. Click here to send an email to the editor of this weblog.
Last update: 3/30/2009; 2:36:28 PM.