Migrating 10g JSF Web project with ADF Faces components in jspx pages to 11g Facelets pages using Rich components
Introduction
As of this writing (Feb 2010), there are no tools available to convert your 10g project into an 11g project using Rich components, let alone something that can convert my jspx pages into Facelets. JDeveloper 11g FAQ confirms that, you need to do manual migration if you want to use Rich components. As Oracle points out, you’ll need to do some code refactoring to make use of new functionalities available with JSF 1.2 and Rich components (and Facelets).
This post discusses a few points encountered during my by hand migration process I’ve done with a couple of 10g projects. If you are migrating to use Trinidad components instead of Rich components, then this paper would be more useful than my post.
At the end of this post, you can download a sample 11g Rich Component project with Facelets pages to get you going.
Why Facelets?
Some other benefits like templating may not sound great to an ADF user as Oracle already had templating support from JDeveloper 10g.
Facelets support in JDeveloper
Although the usage of Facelets was possible with 10g as discussed here, there was little IDE support like code completion available to you. Although the support improved in 11g, it wasn’t perfect as John Stegeman explains here. But it is a lot better now with Patch 1 release on November 2009 (Version 11.1.1.2.0 onwards). So please update your JDeveloper 11g if you plan to use Facelets at all.
Skinning
In 11g, you can extend an existing skin rather than creating everything from scratch. The fusion desktop skin that comes with Patch 1 release looked great to us, and decided to use it instead of custom skinning. We changed a few styling details by adding some CSS styles and by overriding existing styles. You may find these posts on skinning useful
- http://download.oracle.com/docs/cd/E12839_01/web.1111/b31973/af_skin.htm
- http://biemond.blogspot.com/2009/01/adf-skinning-in-jdeveloper-11g.html
- http://technology.amis.nl/blog/7127/adf-skinning-and-resources-2#more-7127
- http://technology.amis.nl/blog/4169/adf-11g-why-use-skinning-why-not-use-simple-external-css-stylesheets
If you want to change your skin at run time, please see this forum post.
Once the template is created you could start converting each jspx pages. Use the new gallery and select Facelets page (Please make sure “All Technologies” tab is selected)
Then you may start with this code and copy/paste the main content from jspx page, excluding anything that is already in template file.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich"
template="template.xhtml">
<ui:define name="pageTitle">Facelets Test Page</ui:define>
<ui:define name="content">
<!--
Copy/Paste main content from your jspx page here
-->
</ui:define>
</ui:composition>
You can override any named UI component you’ve defined on your template file.
While a lot of simple rich tags like outputText, forEach, panelBox etc. won’t need any modifications at all, tags like table or treeTable will require some attention. (Please see af:table issues section as well). It will be worthwhile to have a look at the online rich client demo at http://jdevadf.oracle.com/adf-richclient-demo/faces/components/index.jspx. Please see this link if you want to deploy the online demo on your own server. With the introduction of new components like Calendar, Carousel etc. it is very tempting to do a page redesign. Another enhancement we liked was the inline dialog boxes and pop-up windows. (You can see it in action on the sample project)
You can find the list of new features in 11g at http://www.oracle.com/technology/products/jdev/collateral/papers/11/newfeatures/index.html
If you have used JavaScript in your pages, you’ll find this post by Frank Nimphius very useful. One thing you’ll notice straight away is, there are no on event attributes (e.g. onclick) available in tags like af:commandButton. You’ll be required to use af:clientListener tag instead. Please see Frank’s blog for examples.
af:table issues
Oracle has done quite of lot of work with af:table component. It is more intelligent now, so it will only fetch the data as you scroll along, if you wish so, something similar to Yahoo Mail’s inbox. It is quite a useful feature if you have a big table, but at least in our case, the user experience wasn’t that great, especially when you scroll with your mouse scroll wheel. You’ll see quite a lot of “Fetching Data” messages. Again a change you’ll notice here is the lack of separate pagination controls. So even if you set rows=”15” on af:table, it is not going to put pagination controls when you have a table with more than 15 items. It isn’t entirely bug free too, as discussed here. I’ve provided a dirty fix on the forum, but as I mentioned there, it is something Oracle needs fixing.
Code reuse and Facelets custom tag libraries (Please see reference section for online material on this subject)
If you are displaying similar data in more than one page, you could make use of Facelets custom tag libraries to create a common component and reuse everywhere else. When working with ADF Faces, there are a few catches though. One of them is the usage of partialTriggers in tag libraries. See this example here,
On test.xhtml, we are including the custom tag library with this line
<j:sdetails value=”#{test.msg}” partialTriggers=”cmdButtonId” />
On the tag library file sdetails.xhtml, if we include the partialTriggers directly as shown below, it will result in a run time java.lang.IllegalArgumentException: Cannot convert x of type class java.lang.String to class [Ljava.lang.String; as ADF Faces expect the attribute value of partialTriggers as a String array.
<af:outputText value=”#{value}” partialTriggers=”#{partialTriggers}” />
To pass in an array, we could define a function in our test.tablig.xml file as,
<function>
<function-name>getStringArray</function-name>
<function-class>uk.co.jaimon.ft.Test</function-class>
java.lang.String[] getStringArray(java.lang.String)
</function>
And declare this static method in Test.java file as,
public static String[] getStringArray(String string) {
if(string == null || "".equals(string)) {
return new String[0];
}else {
return string.split(" ");
}
}
Now on the taglib file, we can use the following line to make it work,
<af:outputText value="#{value}" partialTriggers="#{j:getStringArray(partialTriggers)}" />
You can see the full implementation on the sample project.
Navigation specified in faces-config.xml doesn’t work for pop-ups when used with Rich Components!
That was a surprise, and took a while to figure out Oracle has moved all their extension work on navigation to task flow files.
Let’s say you had a navigation defined in faces-config.xml as,
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>dialog:nameSearch</from-outcome>
<to-view-id>/nameSearch.jspx</to-view-id>
</navigation-case>
</navigation-rule>
To make this work under 11g, first you need to add an ADF task flow page. From new gallery, select ADF Task Flow off Web Tier/JSF category and click OK.
On the following page, uncheck the box “Create as Bounded Task Flow” as shown here,
And modify the content with the following lines,
<?xml version="1.0" encoding="windows-1252" ?>
<adfc-config xmlns="http://xmlns.oracle.com/adf/controller" version="1.2">
<view id="nameSearch">
<page>/nameSearch.xhtml</page>
</view>
<control-flow-rule>
<from-activity-id>*</from-activity-id>
<control-flow-case>
<from-outcome>dialog:nameSearch</from-outcome>
<to-activity-id>nameSearch</to-activity-id>
</control-flow-case>
</control-flow-rule>
</adfc-config>
Again, the sample project includes a working implementation.
Code re-factoring on Java code
This could be a simple task or a bigger one depending on how many bindings you’ve used in your project, and how much re-factoring you want to do. What I did was to replace the word Core with Rich using Search/Replace in Files option. So basically, your CoreTable becomes RichTable, CoreInputText becomes RichInputText etc. And in imports, replace all oracle.adf.view.faces.component.core. with oracle.adf.view.rich.component.rich.
JDeveloper 11g/WebLogic is only certified to work with JDK 1.6. Make use of the new functionalities available with JDK 1.5 and 1.6 like Generics, new for loops, auto boxing etc, if you aren’t already using JDK5 features in your 10g projects. Please see the release notes for JDK 1.5 and JDK 1.6 for more details.
Although OC4J R3 (10.1.3) was a J2EE 1.4 Server, it also supported EJB 3.0 and JPA, which were part of JEE5. If you are using EJB beans, then you might be better off using the migration wizard in JDeveloper 11g. Once migrated, you can convert your jspx to Facelets pages and change backing beans accordingly. You’ll be required to modify web.xml for Facelets support and take out the JSP library as well. Some of these post might be useful in EJB migration
- http://www.approach.nl/2009/02/migrating-ejb-3-applications-from-oc4j-to-weblogic/ http://www.approach.nl/2009/01/migrating-web-services-from-jdeveloper-10g-to-11g/
- http://today.java.net/article/2007/01/18/migrating-ejb-2x-ejb-30
- http://www.javaworld.com/javaworld/jw-08-2006/jw-0814-ejb.html?page=1
Migrating data sources
This Oracle document explains about various data sources migration options. What I did was to create IDE connections and then just drag the connection to different applications via Database Navigator. This will result in creation of connections.xml in .adf/META-INF folder on your application folder. Once you add the connection, JDeveloper will create necessary JDBC module when you run or debug your application with the integrated WebLogic server.
Obtaining data sources from your Java code.
JNDI lookup code also needs some modification if you’ve used code similar to,
DataSource ds = (DataSource) ic.lookup("jdbc/preProdDS");
You’ll need to change it to the following line to make it work with WebLogic server,
DataSource ds = (DataSource) ic.lookup("java:comp/env/jdbc/preProdDS");
Just a side note, here the connection name you set up in JDeveloper will be just “preProd” and not “preProdDS”.
IE6 support
Well, the simple answer is, there is none. If you open your application on IE6, a JavaScript alert will pop-up displaying the list of browsers Oracle support.
In a way, it is a good thing, so we can finally get those IE6 users to upgrade. But that can also be the problem, getting them to upgrade before they can use your 11g application. If you desperately needs IE6 support, then you should stick with Trinidad components with 11g and not Rich components.
Rendering issues on IE8
Although IE8 is officially supported with the patch 1 release as mentioned here, there are still some rendering issues with certain components (as of February 2010). One of them is the treeTable component. If you’re on IE8, open test.jspx from my sample application and click on Tree Table Issue button.
As you can see, when you scroll, some texts are getting displayed outside the scrolling area. This doesn’t happen in any other browsers I’ve tested. Hopefully Oracle will fix it in their next release.
Sample Application
You can download an 11g sample application from here. Run index.jsp or test.xhtml to start the application. It show cases some of the functionalities we’ve discussed on this post, including usage of Facelets templates, tag library, inline pop-ups, ADF-C page flow etc.
Have a happy migration!
Jaimon Mathew
References:
- Facelets Introduction Article by creator Jacob Hookom (Published in 2005)
- Facelets fits JSF like a glove (Paper published in 2006 on IBM Developer Works)
- Facelets Components (Excerpts from JSF 1.2 Components book)
- Known Issues for JDeveloper and ADF 11g (11.1.1.0.2)
- Oracle paper on JDeveloper migration to 11g
- FAQ – Oracle JDeveloper and ADF 11g
- Certification and Support Matrix
- MyFaces Wiki on Converting from JSP to Facelets
- Using JavaScript with 11g
- ADF Faces Rich Client Online Demo
- JDeveloper 11g Tutorials
- ADF Guide on Skinning
No comments yet.
-
Recent
- Check digit calculator for barcodes and credit cards
- An Excel Addin to work with Unicode CSV files
- SimpleImageInfo – A Java class to get image size without loading the whole data
- Making Scrollable Tables with fixed headers – Updated
- Migrating 10g JSF Web project with ADF Faces components in jspx pages to 11g Facelets pages using Rich components
- Monitoring Log4J messages on a browser via server push
- Managing Vimeo video player via Javascript using Moogaloop API
- Making Scrollable Tables with fixed headers
- C# FTP Client Library
-
Links
-
Archives
- April 2013 (1)
- August 2011 (1)
- January 2011 (1)
- March 2010 (1)
- February 2010 (4)
- September 2009 (1)
-
Categories
-
RSS
Entries RSS
Comments RSS
Leave a Reply