JSF (ADF) Case Studies Paper
Upcoming SlideShare
Loading in...5
×
 

JSF (ADF) Case Studies Paper

on

  • 4,998 views

JSF Paper I did for RMOUG training days conferenece 2008

JSF Paper I did for RMOUG training days conferenece 2008

Statistics

Views

Total Views
4,998
Views on SlideShare
4,994
Embed Views
4

Actions

Likes
1
Downloads
55
Comments
0

3 Embeds 4

http://www.slashdocs.com 2
http://www.lmodules.com 1
http://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    JSF (ADF) Case Studies Paper JSF (ADF) Case Studies Paper Document Transcript

    • ADF CASE STUDIES Michael A. Fons, Graebel Companies, Inc. ADF Case Studies 2 Introduction 2 Design and Detail design 2 Training (Developers to do ADF) 4 Technologies 7 ADF BC with JSF/ADF Faces 7 Web Services 7 calling a .NET web service from Forms 8 Installing software 8 Which version of JDev to use…? 9 Hints 9 It is good to set up and familiarize yourself with… 10 framework extensions 10 CM for object/code sharing 10 skin changes (CSS and bundles) 10 deployment: 11 Other things to look at… 11 Security 12 ADF Security 12 Miscellaneous Technical experiences 13 Login modules and dynamic connections 13 Sorting of columns disappearing 14 Commit/undo buttons not enabling when view rows have changed… 14 www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons Putting in that first module and getting feedback from the user community. 14 Resources 15 ADF Case Studies Introduction The following paper/presentation actually is two case studies combined into one, because at the time of writing this paper I did not know which ones would work out. Any project can get shelved, and I wanted to have something to write and talk about, so I decided to increase the odds of that happening. The first project involves developing one or two new modules for a project at Graebel Companies, Inc., which is an international moving company. Graebel uses something called a Day Page to keep track of what moves will be happening in a particular city or area, and what people will be needed to make these moves happen. This project I will talk about is to create something called “on-line day pages” so that Graebel could internationally and nationally schedule and manage these daily “jobs” required to get the pre- and post-move packing, unpacking, warehouse work, and a good many other skills completed. Without this project coming to fruition, all 100+ branches of Graebel across the country and world would have to make due managing this information at a local, disconnected level with various Access, Excel, paper, and whiteboard methods they currently have today. When this project is complete there will be one on-line method to achieve this common goal for all the branches. This will make communicating this information easier; since most moves are connected (a move is always from somewhere (one branch) to somewhere else (another branch, many times)). Also, with the creation of this system, Graebel employees could transfer from one branch to another, and still use the same system for monitoring local job resources and coordinating move labor and resources. With the invention of this system, data could also be analyzed to help do business smarter in the future. The second project is to give RMOUG a new website. RMOUG’s IS Director (Dr. Barbara Lewis) want to give their website a face-lift and also to have some designated member’s-only areas so that membership to RMOUG can “have its privileges” similar to other my-xyz (portal) websites you have seen. Barbara has a lot of good ideas. And I enjoy working with her. I will be referring to both projects throughout this paper and presentation. Design and Detail design Graebel’s data-changing web-pages, up until now, have primarily been using Oracle Forms. About 1.5 years ago, Graebel hired me as an additional PL/SQL and Forms resource, but also someone who could help them understand ins-and-outs of ADF, so they have a subject matter expert on hand. I am self-trained on ADF and Java; my self-training tactic has always been “inch-by-inch-anything’s-a-cinch.” So I read a little everyday and program in ADF whenever I can, for whatever reasons I can think of. I have been studying harder for three years now, but I would like to spare the reader that same delay if at all possible. Meanwhile the ADF keeps evolving to be easier to use, and so does JDeveloper. Peggy, my boss/supervisor at Graebel, has asked me questions throughout the software lifecycle about the capabilities of ADF. Here are some questions my bosses/co-workers asked me about: 1. can ADF do an entity based on a database view? (yes; this is documented in the ADF Developers Guide from Oracle) 2. what sort of navigation options does it have? (three levels of menus, navigation drop-down list, dialog windows, links/buttons to take you anywhere you want to go. Asked if it had “pop-up” menu? (a right-click context menu; I do not know if it does…have not heard of it yet…maybe in 11g?) 3. what sort of testing options are there? At my boss’s boss’s request, I did a demo/presentation two quarterly meetings ago and for my company because of this question (I also presented on this; see the www.rmoug.org to download the powerpoint, or email me if you are interested). I found there are a lot of testing options, many of which are centered on JUnit. As we know in this field, there are also a lot of different kinds of testing. Each tool seems to take a slightly different approach/specialization to what it is made to test. www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons 4. Can the global button bar at the top of the af:panelPage (the menuGlobal facet) contain buttons like “create record”, and “delete record”, … that typically would be found on a button underneath or very near the form or table to which they would apply, and would be bound to the iterator. These global buttons she wanted would determine what “data block” to apply to by looking at what field is in focus, and then determining which iterator that field belongs to, and then running that action (operation binding) which is associated with that iterator and exists in the binding layer. I am not sure how big of a priority this will be as she seems like she might be flexible on having this button bar for this project. Her reason for wanting it is that our existing user community is used to having a global button bar. I am not sure, though, if it is wise to distance the user from basic functionality of ADF if it means going to enormous lengths of programming to get there. That said, I was still excited to be working on this problem (11/6/2007 9:41 PM). As of 11/17/2007 11:38:35 PM, I had developed a solution for one such button, so it is possible to do this for several buttons. My boss seemed pleased to hear this. Please contact me if you are interested in having this code sample. 5. Another question that I was trying to answer (also as of 11/6/2007 9:41:53 PM) is: is it doable to do a database log in (like we have in forms) so we can reuse some of our existing grant structure? At first I was not even sure if it was possible and was trying to imagine alternative solutions should such a thing not be possible. Prior to this investigation, I had implemented the same username/password model that SRDemo app implemented in their application. I used the XML jazn-data.xml style of specifying users and roles which have no relationship at all to the Oracle database user that is logged into in order to support the ADF BC layer. In the SRDemo setup, they use one user, and then do something like set a context in the database with a package spec variable to determine what user is accessing the data, so they know what data privileges that user can have. As of 11/17/2007 11:40 PM, I got to the point where I could confidently say that you can log into a database user in ADF. I said this because Frank Nimphius (two years ago) wrote an article (which Frank reassured just recently still applied today). The url for this article was: http://www.oracle.com/technology/products/jdev/howtos/10g/jaassec/index.htm I first implemented a proof of concept based on this article. It went somewhat slowly, but I made progress. As of 11/22/2007 9:19:29 PM, because of the urgent need for this kind of authentication, one of the DBA’s (Tom Gaines) also had been tasked with figuring out this issue. From what I have read, I saw that the point of the kind of authentication we need to do is to log in validating against the Oracle username and password. Then, if the authentication is successful, the LoginModule will add Principals (essentially “roles”) to the authenticated Subject; the LoginModule determines what roles/privileges the user will have by querying the roles in the schema it has logged in as, in one kind of custom LoginModule I looked at for Graebel. Just as much I was studying and implementing the version that stores user and roles in tables for RMOUG. And (as of 12/24/2007 for RMOUG and late November for Graebel) we had implemented and deployed this application with this functionality. For Graebel, we have implemented a login scheme where a login just connects to the database and checks database roles against roles in the web.xml file to determine authentication success. (More on this later in the paper). For RMOUG, we have an admin screen which allows an administrator to reset passwords, create login, users, roles, and remove these things as well. Also the member roles have access to an ADF web page which allows member end-users to change their password. At this point I am going to create a logout button (as described in the ADF Developers Guide from Oracle), so that after a password change the user has the option of logging out right then. Also see references for how to implement some of these technologies. In retrospect I wish I had had more experience to guide my boss through some of the design phases. I would have pushed harder to implement web pages that adhere closer to default functionality with regard to keeping af:table components as ways to select a particular row which could then be updated, rather than as an actual means to update the data. I think eventually ADF will be more flexible in this regard. But as it happens with today’s ADF version, this is like swimming upstream for an ADF newcomer. The ride would have gone smoother if I had had the experience to strongly recommend sticking with this default functionality instead of trying to strong-arm my way to success for a first form. As it happens we may not look as good in some management’s eyes because they might think we took too long to make a somewhat awkward form which would have taken less time to develop and would have been even more stable. Still though we did get a af:table-based updatable web-page implemented; although management now has their eyes set on going with the alternative multi-page implementation for the next web-page we are planning. For the RMOUG project detail design work consisted of me drawing forms and menu sketches on pieces of scrap paper and then attempting to communicate these drawing in the form of email with Dr. Barbara Lewis. My plan of attack is to use a really basic layout for forms, and to stick as much as possible with “default” ADF technology. As the RMOUG user-base (Barbara, the RMOUG board, RMOUG volunteers, RMOUG staff, and eventually RMOUG members and random visitors to the RMOUG website) comes to know the application, I am sure the input for this website will increase. While this is maybe not an ideal way to create an application, I am willing to work with that format, since that is what is available. www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons Training (Developers to do ADF) I put myself on the hook to do presentations, and practiced the presentation with my boss’s permission to my co-workers. So for the last few quarters I have been doing presentations to try and get everybody acclimated to this new era with regard to Oracle Java development tools. This at least keeps everyone open to the idea of learning more, and opens to doors somewhat for self-study. Although it is hard to say how much extra study was brought about by my encouragement. So at the very least, this was a foot in the door, and a venue to give me a chance to practice, and a way to start a library of tutorial documents that people can review whenever they are actually ready – should they not be currently. During the Graebel project, management gave us a week or two solely devoted to play with and learn about different tools to help make different SME’s in the company. Additionally each of the designated SME’s have had assignments in their tool of choice to christen them by fire. Here are the tools we were encouraged to play with (each person got a different tool or two): 1. BPEL – process driven functions; requires different kind licensing to use this, so we wanted to make sure it was a good fit. We ended using it in an approval process – replete with escalations, time limits, emails back and forth and database interaction. I did not personally work with this tool. 2. APEX – everybody took a look at this tool; I did a minor practice form just to get a feel for it…nothing that is bound for production yet, though. 3. BI Publisher • Apparently Oracle has been doing some free weekly on-line training or webinar-ing for some or all of its licensees. Either that or my boss has some “pull” with somebody at Oracle. • Some of us were designated BI Publisher SME’s. I did create a report that competed with an APEX version of the same report. I see that there is a lot to learn if you want to become a BI Publisher geek. I assume the same is true of APEX. 4. JDev: ADFBC with JSF – I was the teacher. Oracle Developer Day came to Denver in a timely fashion this year. It allowed some of the JDeveloper/BPEL newbies to get some really good exposure, and to fill in gaps for people who received my training, but did not really “get it.” I did not go to developer day, but the people that went who had been to my training said it was perfect for their level of understanding and complemented my lessons really well. Speaking of my lessons, three of my training sessions were a series of basic lessons where we all called in to a party line of sorts. What follows is the outline which my lessons generally followed (some of the lessons topics were combined, mixed up or omitted): Lesson 1 -- set up a basic parent child app • creating many business components using the BC components from tables wizard • creating a single business component using the individual BC creation wizards • linking them together • putting them into the app module • linking viewcontroller project to model project • faces-config.xml • Navigation diagram • Visual editor • Data Controls: drag and drop • individual unbound components click, or drag and drop • New pages: do we want backing beans? • Parent “block”: Form • Child “block”: Table • Adjusting field/column attributes Lesson 2 – business component issues • List different kinds of business components: entities, associations o views, view-links (also read only and transient views) o application modules o what packages to put them in o • Entity topics used for? o sharing o extending o www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons Sequences o exposing entity java files o • View topics one or more tables, reference or updateable o read-only views o transient views o exposing view java files o Lesson 3 – Navigation • faces-config.xml – configuration manager and Navigation diagrams • Basic navigation • “dialog:” – foundation of LOV’s. (Note: LOV’s are a somewhat advanced topic in version 10.1.3.x; 11g promises to be easier. See http://www.oracle.com/technology/pub/articles/gauchman-lov.html if you can’t wait.) • redirect – when to use • global navigation • navigation components: menus (dynamic menus are another advanced topic, but we need to cover it eventually. I hope future versions make o this easier as well.) navigation drop-down list o links and other components o • persistent from page to page requestScope/processScope/sessionScope/applicationScope variables o beans o Transient View Objects o parameters o o Lesson 4 – add validation • Database trigger level • Entity level • data binding layer level (af:validator*) • validation in Java Lesson 5 – different components • ADF Faces Core components panelPage (componentPalette) o panelHeader (component Palette) o inputText/outputText (generally from Data Control tab) o panelForm (generally from Data Control tab) o table (generally from Data Control tab) o commandButton/commandLink o objectImage o menu*/commandItem o facets (really not ADF Faces core; JSF core) o panel tip o hidden components: o setActionListener, returnActionListener (functional) switch many others o Lesson 6 – corporate infrastructure, sharing, code reuse, standards, etc. • work in progress • Framework code – common code – VERY IMPORTANT to get used to this up front. • configuration management – checking out shared things • using same menu • configuring the web server for our expected load application module/connection pools o right number of JVM’s/OC4J’s/application server’s/load balancing hardware o • testing part of testing needs to include shutting off of application module pooling during testing to make sure functionality o still holds. (AM pooling has certain “affinities” for optimization that will make variables appear persistent when they really are not; developers need to learn proper coding practices to avoid this.) • standard config settings for application module locking needs to be optimistic o need to turn on authorization (log in) o o www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons During training session I made the following observations: 1. We used Oracle Collaboration Suite to have a conference that could see my desktop as I demonstrated most of the above outline. 2. Ideally you would have a dual monitor system, with the demonstrator’s window in one monitor, and JDeveloper open on the other monitor where you could emulate. We only had one monitor (each) though, so we had each window open up pretty big, but not quite maximized – so that it was easy to flip back and forth. And to detect movement in the demonstrator’s window. (Note that collaboration suite opens maximized when you join a conference, but you can make it adjustable size by clicking the pushpin icon in the upper-right-hand corner.) 3. As the teacher I was also asked to say what I was doing over the “PC Conferencing” (a conference call service we have) as I did it. Because the participants were flipping back and forth between the demonstrator’s window and their JDeveloper window. 4. I also suggested that everyone close other programs except JDeveloper, since between JDeveloper and the embedded OC4J they would need quite a bit of memory. Everyone had 1Gig of memory on their computer. (We were using JDev 10.1.3.3.) 5. As I demonstrated I kept encouraging participants to let me know if they were having trouble so I could help them along. Other’s had to wait though while we kept everyone up to speed. 6. In our first set of training sessions, we ended up covering Lessons 1, 2, part of 3 and part of 5. After that we ran out of time. Hopefully we will get to go back and talk about more. Doing an actual assignment is a great way to learn a development tool. After a student/employee/volunteer has gotten to some level of familiarity with a technical subject, it is very good to give them an assignment, so they can start making their lessons more real. Even if they make mistakes (probably: because they make mistakes…) they and the team will still be better off with the end result: the student will learn things semi-permanently and will come out of the experience with a sense that they really accomplished something important. For example I am currently learning a lot with my current assignment which involves a web page and a report; the web page I am doing in JDev, and the report I was assigned to do with both BI publisher and APEX. I did get the BI publisher version fairly complete, and in the process discovered some very odd things about BI publisher that I am not likely to forget. (For example, BI Publisher has several gotchas when it comes to making a parameter have a Date datatype, and you are trying to use the Windows Template Builder product that goes with BI Publisher. I even filed and SR with Oracle because of it, although I am not actively pursuing its resolution because I found work-arounds to my problems. My feeling about BI Publisher is that one could become very deeply entrenched in it (the way I am entrenched with JDev ADF currently); so mentally I am open to learning more, but I am focusing on JDev learning.) I am running into a lot of foundational discoveries. Here are a couple examples of foundational discoveries I have made on my first real professional ADF assignments: LOV’s -- there are at least two ways to do LOV’s in JDev: 1. The way it says to in the ADF developer’s guide 2. The way I read about that seemed a lot simpler in the JDev forums. Both methods call another form as a dialog window. The new dialog window that comes up shows a af:table with rows on it and a af:tableSelectOne component on the side of it. You select the row you want, press select, and that value gets written back to your calling form and probably into the calling row of the form that you called from. The difference in the two methods chiefly is that the simpler method creates an iterator binding for the iterator you will be writing data back to, only you create it in the pageDef file of the called LOV form. In this simpler method the act of writing to this binding is just like referencing the same collection/iterator on two different pages: you instantly get access to the current row on the new page which means you can update it and have it reflect on the old page as well. You can easily write to this iterator binding using a af:setActionListener component (as many as you need). So many aspects of this solution are “declarative”. The setActionListener copies from #{row.field} of the LOV to #{binding.iterator.inputValue} which corresponds to the data field you want to set in the calling form. In this simpler method there are two downfalls: one is that you cannot create a generic “shareable” LOV, but this is not such a problem because they are pretty quick and easy to create in most cases. But since you have created an iterator binding pointing to the collection referred to by the calling form you have hard-coded the link between the LOV and the calling form. The other downfall is that if the calling form is using an LOV to populate the records of view that has some other fields in it that are mandatory and will be blank while populating the LOV field, then you may get either some weird behavior if your LOV has any reason to refresh the page. Essentially at that point the framework raises an error and complains about the other mandatory elements not being filled in the new record you are creating. (If you have a www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons very simple LOV this is not a problem, but if the list is longer it probably will be…especially if your LOV page needs some “find/execute” functionality.) (The way to overcome this issue is to override the LOV page’s page controller. Frank Nimphius gives instructions how to do this in his BlogBuster site.) In contrast, the developers guide’s method does not have such hard-coding. The price you pay is going programmatic. You first need to write to some processScope variables (probably using af:setActionListener). Then you refer to these variables to create an Object that you can pass back to the calling component’s returnListener. Then you need to instruct the framework to close the dialog window and return to the calling page. Then the calling component (say an af:commandLink or an af:commandButton on the calling page) gets an event with the passed data-Object in it. You extract the data, assign it to the proper binding iterator element, then you refresh the calling page. All this is done as an example in the ADF developers guide from Oracle, except the page refresh. I fiddled around with what I interpreted they meant by using partial page refresh to get the values to show up after you have refreshed the binding layer, but I just never got anything to work without refreshing the page. How to authenticate against a database the way we did in forms. This article already mentions the URL from Frank Nimphius on this subject. Plus the references section of this paper gives some more up-to-date references from the same author and another author that are more up to date. Validating data entry in individual fields challenged me. Trying to use various kinds of validations on fields like you might do in Forms is an eye-opening experience in JDeveloper. The process that ADF uses to validate is complex if you are not used to HTML programming. If you want field-by-field validation, one option is to set the input fields to do “autoSubmit” (a property on ADF Faces input components). Essentially the page will talk to the server each time the user leaves the focus of one “autoSubmit” field and goes to another. At this time you can validate what the user has entered at the business component level, the model level, or at the view level. Each has its relative merits. At the view level an af:table, for example, will validate each field and row that is displayed in the af:table component with every submit. If during a check you discover that an invalid value has been input wrong, what do you do? You can actually call an LOV for example restricting what they have entered by an LOV if they entered a partial value, but then what if you are creating a record? At that point you must validate and perhaps populate all mandatory fields in the row, so you don’t get errors again as the validation progresses. My point is that validation is something you need to dive into as soon as possible so you can create some best practices for your developer community where you are at. Although I would recommend that it would probably be much easier to start with a af:form component rather than an af:table, because validation would not skip from row to row. Technologies ADF BC with JSF/ADF Faces I have been learning this technology on the side and have done several presentations for RMOUG events. Oracle is still ramping up its development staff for this tool and is working with these technologies and promoting them/using them internally in order to overcome the gravity associated with bringing a Java developer IDE up to par with its competitors and with Oracle Forms. It is possible to approach this technology stack from both the Java/JSP developer standpoint and from the standpoint of a Forms Developer. • This duality is underscored by the availability of two developer’s guides: a 4GL/Oracle Forms approach and a Java developer’s approach. • Java developers can utilize the flexibility of the J2EE suite of tools and capabilities, as well as JSF’s offerings – like creating custom GUI components. • Forms developers can utilize more and more of this technology stack’s functionality by using the relatively declarative development techniques available in JDeveloper today and those coming soon in 11g. Web Services At Graebel there are a variety of platforms which all need to talk back and forth in order to implement this application. Some of these communications are XML or other text files passed back and forth. But for the instances where Oracle/ADF is needing to talk to a .NET platform, we are calling a .NET web service from JDev (.NET platform is, in turn, calling web services stored in the Oracle database, for whatever data they need from us): www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons • JDeveloper has a wizard that creates a DataControl from a WSDL. Only the simplest services work (at least in 10.1.3.2) with this wizard. If (for example) the web service that you are calling requires you to wrap your parameters in an object of some sort, then you will need to use the proxy wizard instead to create java classes to call. Then you will need to add programmatic calls to these generated classes in your backing bean code. • Will this improve in 11g? I hope so. Or maybe I was just doing something wrong. Because later in the ADF Developer’s Guide for 4GL Developers, I noticed that they talk about their web service data controls as being the best thing since sliced bread. Another web service issue that came up was the idea of calling a web service that when we passed a user name string that we would get back a token, which we would use for authentication, for future web service calls in that session. This uses AD (Active Directory). I am not sure how much use we will be getting out of this at this time. It is taking a while for our DBA’s and sysadmin people to agree about how do deal with things like AD, OID, SSO, and the like as of 11/6/2007 9:51:09 PM. calling a .NET web service from Forms first part very similar…you use the web proxy generator wizard in Forms Builder. Then you do so forms pl/sql programming; in this programming you make similar calls to the generated pl/sql calls to the Java classes that the proxy generator creates. This generator creates a “main” method so you can test a call to the service in forms. The overall picture in doing quasi-object-oriented programming in pl/sql is as follows: • any Java object you need to reference is represented by defining a generic Java Object variable in the pl/sql declaration section of your forms trigger that you want to call the service. • With this Java Object variable you can instantiate it and call methods in it by calling procedures which the proxy generator created. With these procedures you must pass in the Java object variable also. • There are some examples of how to do this on Technet. Installing software RMOUG has a Linux development box, and a production box with Solaris on it. The development box is what I got to play on around 10/28/07. What follows is a journal I kept as I was discovering how to make this setup work in this environment: 1) I had a good development run the weekend of 10/28/07 (and many other weekends) working with the RMOUG project. a) On the weekend of 10/28/07, I did the following: i) Installed JDK 5.0 (1.5) on the box because that is what the OC4J needed to run, and what the adfinstaller program needed to run itself. ii) I installed a 10.1.3.3 OC4J. iii) I installed the adfinstaller program into the OC4J, so that apps that I deployed to OC4J would have the libraries it needed to run ADF programs. iv) I started up the OC4J, went into EM using http://<hostname or ip>:8888/em, and deployed the .ear file that had my demo program of part of what the RMOUG website might look and act like in my rendition of their website. v) I harassed the IS Director of the RMOUG Board of Directors via email (sorry, Barbara ☺). Since RMOUG is a volunteer organization, everybody who works with that organization (almost) is a volunteer and has to rearrange their already busy schedules to get things going. Barbara is working on setting up the database. I have offered my assistance to her. When that piece is in place I will import the rmoug schema and the tables/db objects that go with it. b) From that weekend’s work, I learned the following: i) I learned that even though the 10.1.3.3.0 OC4J Readme.txt file says you can have Java SDK 1.4.2 installed on your computer, you really need Java JDK 5.0 (1.5.0_13 is what I used) to allow the OC4J EM (Enterprise Manager) program to work. At this stage I really like using EM more that admin-client.jar (in fact, I have never used admin-client.jar or admin.jar; eventually I expect to when I automate the deployment process. This program is surely what OC4J uses to do its deployments, and a good number of other related functions.) ii) I learned that “uname –a” is a good way to find out what kind of flavor of UNIX a box is running if you don’t already know. Originally I thought this development box was running Solaris. So I tried to install the Java SDK for the Solaris OS. I knew something was wrong when I kept getting checksum errors, and the Java SDK install kept failing. 2) The last 20% is sometimes 80% harder than you want it to be. (I just made that saying up, but there’s some truth there, eh?) a) 10/28/07 – Barbara finished the database installation. We found there was some serious latency issues after she started the new database however. I learned at that point that this server had only 1Gig of RAM. I also learned after some quick emails that she had seen this coming, had purchased another Gig of RAM, and was poised to give the www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons order to add it. I encouraged her, big time, to do so. She did it, and within hours we had a server with 2 Gigs of RAM. She also decreased the size of the SGA. b) 10/29/07 – I logged on to the dev server and found that the database was not up. So I looked up how to start the database, and found to my surprise that you could do that through sqlplus now. I don’t remember things being that way when I was a dba in 7.3; guessing it was though. I then found out the system user password was not any good (apparently), so I changed the system password through an internal connection. Then I imported the export file, but it did not create user; so I had to drop the tables I created in the system user accidentally. Then I created the rmoug user. Then I re-imported the export file. Then I tried to run my applications, but I kept getting JDBC errors in the application log. So then I remembered that I needed to alter some files with specifications about how to connect to the database. So I found one file named connections.xml with that information in it, sort of. So I changed that. The error log still showed JDBC errors. So then it occurred to me that maybe the database needed a listener.ora and a listener started. c) 10/30/07 – created the listener.ora as a copy of my local XE listener.ora adapted to point to the database at hand. Now the error log was reporting that it did not know what XE database was. So I did not know what file to change next. So I looked up the UNIX “find –exec grep –q …” command. Worked great: pointed me to the bc4j.xcfg file in the application I deployed. Oops…forgot about that file. I altered that file from XE to RMDB1 as the SID. Now I am getting an error that some XML file is not syntactically correct. I think the error is spelling out the XML element name that is not matching…so probably will need to use the find command again. But the smart money says I screwed up either the bc4j.xcfg or the connections.xml. Then my wife wanted to use the computer…man! 11/17/2007 11:48 PM I later learned that I had screwed up the bc4j.xcfg when I went in to edit it. To correct for it, I just copied it over from my XP computer again and then edited it again. This time things went fine. Since then I have also done another deployment, and I only change the bc4j.xcfg file (not connections.xml) and that change was sufficient to make things work ok. Which version of JDev to use…? Hard to say what the timeline of these projects will be; for RMOUG we are coordinating the extra time and energies of a number of folks. For Graebel, there are several things which management has told us ahead of time may delay this project (“risk factors”); so from that perspective, we should use 11g – since it promises to offer a variety of additional functionality. Since these risk factors have a tendency to happen quite a bit, the 11g ADF technology should be available about the time we actually get around to getting to work on this project. When we were initially working on the detailed design (September 2007), the newest production version available of JDeveloper was 10.1.3.3. 11g is supposed to come out in earnest in November – last I heard. 11g technical preview 2 (the sequel) has come out as of mid-October. As of the writing of this paper I believe there are still technical previews coming out for 11g. I looked at the first preview, but have mostly been studying the 10g verion’s functionality. So, by default, we are using 10g JDev, ADF, OC4J as of right now. Also because my manager does not like the “bleeding edge” for highly visible projects. At the very least I should be playing with and learning about this new version (11g) at this time. (I have not really started yet). • seems like there are hooks for the rich components which allow for easier application of functions like drag-and- drop of elements to various other elements. • As I work with the JDev forum on technet, I have gotten hints and everything short of promises as to what 11g will offer; I have also read a white paper on the new things JDev 11g will have. This is available on the JDev home page. • I also heard good things about OC4J 11g. For example it will have an API which will allow operations against implementations of container-managed security (JAAS). This API should make it much easier to do things like make a call to an ADF web page from an Oracle Form without having to re-authenticate. Hints backup JDev apps periodically, perhaps daily; I mean: just copying the application directory to another one; especially for your first forms. In your foundational discovery mode of programming, you are likely to screw things up in ADF as your creative urges take you in directions you later have to recant and back out of; or worse yet, some quirk of JDev forces you to give up attempting to do something a certain way because you encounter a total show-stopper. While everyone is messing around learning about ADF someone is going to change an entity which is being shared in a way that will break everything and require everything to be redone. (It could even be you!) It is quick to do this, and the peace of mind after you do a www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons backup like this is very nice. I think if you already have CVS running in JDev to help you do CM on your applications, then you may not need this. But it is hard to imagine anything as satisfying as knowing you can just rename a directory or two and be released out of some massive mess-up you might have just made. It is good to set up and familiarize yourself with… framework extensions (see the ADF Developer’s Guide from Oracle (one of them); there is a chapter or at least several sections on creating a framework extension by which you should extend all your ADF BC classes that you use in the model of your ADF BC projects. CM for object/code sharing Comes integrated with CVS in Jdeveloper. There is a rundown on how to work as a team using this tool as a CM repository within the ADF 4gl Developer’s Guide. • CVS seems to be geared toward grouping related objects together. So it sounds like you have to be aware of what is grouped, and that CVS would take some getting used to so that you could not make things harder on yourself than they needed to be. • If you want to share entities, say, it sounds like you would check out a group that had the entity and the xml file that goes with it. Pretty much, in ADF BC there is usually an XML file for every business component. It is the Java files that are optional. Another tool is available for download which is also usable CM. skin changes (CSS and bundles) My boss was intensely interested in changing the colors of the ADF look and feel. She really hates the default ADF BLAF colors, so she asked me to look into some of options using skinning in ADF. In the time allowed I am trying several different approaches to hopefully get something that we can work with. Find out what colors are standard for our company based on what the Marketing department has for standard colors for advertisements, logos, banners, equipment, web pages, stationary, etc. Incorporate those (and other) colors into your new skin. If you are running short on time there are a few skins provided with ADF by default (oracle, minimal, simple), a skin with SRDemo download, and three more skins you can download as extra skins (one of which is called limerine… ☺). Those should give you some ideas. Frankly I created a variant on the SRDemo skin to help us get something useable quickly. It appears that creating buttons and tabs that (based on graphical images, not CSS) look decent is an art form…one that I have not yet entirely mastered. You have to choose colors that work. You have to make color variations gradual. You have to know what miniscule effects will create what illusions when you are not looking at the individual pixels. And you need to be precise about if your lines are straight or how they are not straight if they are curved. I would imagine that people who are good at painting would also be good at making buttons and tabs and other similar ornamentation. One funky problem I ran into when running my different skinning attempts is that I kept getting two things which caused aspects of prior skin experiments to come peeping out when I least wanted them. To borrow a phrase, I had the “amazing disappearing skin!” I would run my first page, which would show the skin changes I asked for, then when I would do something that would partially or totally refresh the page, the refreshed page would use old skin setting that I thought I had disconnected. So there were two issues apparently: • The css files are cached…at least when running your app against your embedded OC4J. Although since OAS has something called a web cache that I hear is really good to clear out everytime you make some significant application changes. This leads me to believe that similar css caching scenarios may come into play, even outside of the embedded OC4J scenario. • Working hand in hand to cause this seems to be clearing the files our of IE (or whatever browser(s) you are using). In IE there is a button that is labeled “Delete Files”. • When I deleted these files and got rid of the cached .css files, this disappearing skin problem went away thank God. www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons deployment: Find issues ASAP so you can start troubleshooting them. At Graebel, we deployed 10.1.3.2 JDev proof of concept app to OAS 10.1.3 with the version of the ADFInstaller applied that goes with JDev 10.1.3.2 installation. Deployment seemed to go OK after OC4J was restarted (after deployment); but there was a delay of about 20 or 30 minutes after the AS restarted before the app would run (this delay may have been caused by using Solaris 8 on OAS 10.1.3.x). Before that the browser was getting 500 errors. We also experimented with cycling the web cache, the application, the OC4J and the whole OAS as well. For RMOUG, I have deployed JDev 10.1.3.3.0 to OC4J 10.1.3.3.0. We did not experience the same delays. But the development box for RMOUG is far less burdened than the test box we used at Graebel for a similar trial. Although regarding deployment, since test environment was running Solaris 10, we had far fewer problems. At Graebel, we had some trouble deploying an ADF BC/JSF app developed on JDev 10.1.3.3.0 to an OAS 10.1.3.x instance on Solaris 8. The ones on Solaris 10 worked fine, however. Other things to look at… It is possible to customize GUI components by doing a View Source of the final web page, copying it all, and pasting it into a html file you can create to work in using JDeveloper. Since ADF Faces servlet (?) optimizes it performance by compacting its output source code as much as possible, using the JDev html editor allows you to format your code with a right-mouse click, and a selection from the context menu. (One reason you might want to do this is if you want to add custom JavaScript code to you web-page, you will need to know how the JSF components are actually implemented, particularly if you messing with the DOM.) Here is a quirk for you, if you are into quirks: as you may know, if you add bind variables to your ADF/BC View queries, then if the corresponding view instances are put into the application module(s) for the application, you will suddenly see a new “operation” appear in the list of potential operations available to the collection data control corresponding to this view. This new operation is called something like “executeWithParams”. If you drop this operation onto your page and ADF adapter will give you the option of creating a new section to the page called a Parameter Form. This parameter form automatically creates one input field for each bind variable defined for the original view object corresponding to the collection attached to the operation. Now…if one of these bind variables happens to have a data type of Date you have to create it using this Parameter Form method. Normally if you create the parameter form and then later add a bind variable to your view object query, there is no problem with dragging and dropping that parameter icon onto the existing parameter form and requesting a manifestation of that bind variable as an inputText with a label. Then as you use this Parameter form, the newly added field works just as well as the other old ones; not so with newly added date datatype parameters. You add them individually in JDev 10.1.3.3.0, the parameter will add and appear to be working until you try to restrict your query by this parameter. At that point you will realize that however you are using this bind variable in your query, the value of the bind variable stays null no matter what you do. The solution to this quirk is to drop and recreate the parameter form, whenever you have a new additional date parameter to add, then things work just fine. (Out of curiosity I created a date parameter using the Parameter Form drop option and another individually. I could not offhand see the difference in the component properties or binding definitions between the two manifestations. If anyone knows, I would be interested in finding out the reason for this quirk.) It is possible to create and use custom components using JSF. I have not done it yet, but I really want to! I have heard from people that have done this. From them I have learned that the ADF Faces components are not extensible. I also learned that ADF Faces components are simply JSF components that the Oracle Corporation has put together. (So if you can do better go for it, but you might not get gobs of help from the forums…but I could be wrong about that. Fortunately the Oracle experts on the JDeveloper forums are extremely helpful in nearly every other way.) 11/17/2007 11:52 PM – it you want to allow entry as well as LOV into an af:table, then you may be asking for a lot of work. I am attempting to validate on the view layer whether or not people have hand-entered correct description information for the lov…like in Oracle Forms. Note that you can auto-submit each time you make an entry into an af:inputText in an af:table. I think that is the only reasonable way to make your ADF application do validation against the database for a value in a field right when they enter it. (I also read in the JDev forum about someone calling a JavaScript function on “onblur” field event to do a submit, but they were having some difficulty.) Currently I am just assuming that validation will happen when they submit manually with a button. It is important to consider if your boss would really like this idea or not; not to mention your end users. In my case, my boss had communicated she would like the user to be able to hand-enter a partial value in a field and have the form either auto populate or present an LOV list. Going after these goals has been a tremendous learning experience for me. But it is not working yet. I am getting some errors. And on commit I get a failure that I am still www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons researching. Actually commit is not working even if I do not get the error. Apparently I have a bad bind variable reference in my backing bean code. I am really concerned that with all this trouble I am having that my boss will cut me off so that I don’t get anything published. Really though I expect that she will tell me to put things together so that a much simpler version of this form goes out for evaluation; then while evaluation is occurring I can continue to work on better functionality and ease of use. This is good also because there may be significant things that the user community does not care about anyway that were causing me problems technically to implement. So I can just can those issues for now. Security There are many security options. It is good to decide what configuration is right for your organization, and your group. • Graebel Companies, Inc. seems to be about to embark on using SSO and OID, so for us a solution that utilizes these technologies is appropriate. • It appears that a programmatic solution is needed in ADF applications in order to utilize SSO/OID, but I am not 100% certain of this; a declarative SSO/OID solution maybe possible declaratively. I have just read an article which talked about adding a Filter (specified in web.xml) in between where the authorization Filter occurs and the ADF Faces/ADF Binding filters occur. ADF Security I cannot tell from reading the ADF Developer’s Guide where JDeveloper draws the line between Container-enforced JAAS functionality and ADF Security functionality. It appears that JAAS security is relating the interaction of the web.xml security specifications with the security configurations of the OC4J (or whichever java container you are using). Part of that functionality may be ADF Security, but what is solely ADF Security is when you define adf-config.xml. (Note: this is not the same as faces-config.xml, which serves to configure a whole different realm of functionalty.) Defining this file gives you options, so that at the binding layer you can control access to pages, iterators, attributes in a number of different ways. It is also possible to control access to various forms and components using Java (i.e., programmatically), whereas ADF Security authorization is typically done through property sheets, and XML configurations (i.e., declaratively). If you click on your JDev application’s UI project and then under the Tools menu select the ADF Security Wizard, this wizard will walk you through getting the adf-config.xml created and ADF Security set up properly (just take the default settings if you don’t know what to do except for step 4 of 5, where you should use form based – for this you can generate default forms for login and error handling). When I ran through this automated process (as of 10/23/2007) my application gave an error, but I really did not troubleshoot this too much; so I might have just fat-fingered something. In the past I have used the ADF 4GL Developer’s Guide to lead me though to working programs on multiple occasions. So even if the Wizard is buggy (and I am not saying that it is), there is enough to put something together for an implementation. In the JDev forum on technet, I worked with Frank Nimphius to see how the anonymous user functionality works in JDev. This functionality would be used if you had an ADF application where you wanted some pages to be public and some to be private. The public pages are made available to the anonymous user’s role, and the private pages (for which you would need a login) would be available to other roles. The thing that struck me as odd here was that jbo.security.enforce property of the App Module configuration file needed to be left at “None”. This was news to me, since I thought you needed this set to Must/Auth/Test in order to get a login screen. Apparently, however, you can get a login screen with this set to None…at least in the case where the Anonymous user is involved. Frank explained to me further that without the property set to Must or Auth, the username would not be available programmatically to your custom business-component layer Java code. The problem was whenever I set it to Must, I got an error that it was trying to Authenticate “null”. So Frank said he would either prove it could be done by doing it himself, or that he would file a bug; since needing to have the username/principal name at the BC-layer code is a valid use case. (As far as I know Frank Nimphius never pursued this because he is very busy and my particular need died out since I got what I needed.) While we are talking about Frank Nimphius, he seems to be everywhere at once and has been responsible for laying a certain amount of the groundwork for the ADF for the last decade. For example, Frank has been very active in the subject of custom login modules for ADF. I am currently trying to use one he actually had built into versions of OC4J on and after versions 10.1.3.1. For RMOUG currently I am using these custom login modules and a couple white papers that Frank wrote on the subject to make database table-based users and roles to authenticate against. But now it appears that while I have gained the ability for users to change their own password in the RMOUG application, I have lost the ability to use the OC4J anonymous user capabilities. So now I am looking for another way to have this anonymous automatic login capability. And after knocking around in the JDev forum’s archives and doing various searches (like LoginContext), I found another article (also by Frank N.) which explains and gives an example of some work he did to continue to customize the login modules and their www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons interaction with JAAS and OC4J and the login screen, so that you have a secure environment. I am hoping with this additional programming I will be able to do an anonymous login, somehow. In this particular article, Frank mentions that version 11g of OAS will have support (an API of some sort) to allow programmatic changes to alter the way the OC4J Container-enforced login security (JAAS implementation) will behave. I am hoping that also means things like public logins are more attainable and obvious to newbies like me. Miscellaneous Technical experiences Login modules and dynamic connections Graebel infrastructure has been one of Oracle user database roles. So all their roles security is invested in existing database role setup. To take advantage of this, I have programmed my ADF applications to use a custom login module to authenticate using Frank Nimphius’s custom login module which does this very thing. Interestingly, however authenticating a particular user does not make the application module automatically log in against this user. So if this is what you need, you have some more work to do. I got this worked out for Graebel. But the code which, again, Frank Nimphius has provided to do this “dynamic JDBC” was not working for me initially. I was trying to adapt the example program which he put together in an article he wrote on the subject of Dynamic JDBC. I had several issues, however. • It appears for some reason that when I am grabbing the HttpSession from the extended SessionCookieFactory he has me create it is null. And yet I was reading reports from several other people who had tried this example and had had success. The difference was that they were all using FORM based authentication and I was using BASIC authentication. Since their authentication forms were all written in JSP, the was already an HttpSession established when the time came for the SessionCookieFactory to fire off. With BASIC authentication there is not JSP authentication form, so there was no HttpSession already established. So I switch to FORM authentication and things worked really well. • Even then I had forgotten to do a set_role when the application module fired up. So I had to override an afterLogon method in the application module java implementation. Since I had already wrote the set_role functionality to do the authentication, I just made the same method static and made that method available to the application module. So that problem was solved. • So then I had a bit of trouble in deploying. I could not tell from the Dynamic JDBC article, where it gets the database/sid/port that it was going to connect to. The focus seemed to be on changing users. (Granted, it is possible I did not read carefully enough…). It turns out that the database/sid/port is obtained from the default connection that you set for the application module. At Graebel, we have dev, test, prod, and training environments. So this we need to change which database we are pointing to when going from level to level. This information is kept in a file called bc4j.xcfg, by default (although there are a million places to keep these parameters it seems; this is more or less the default place these things are kept). We were already going in there anyway because we knew that in there, there is a parameter called internal_connection which is where application module that get bumped get their state saved off to the database (again, by default). So we initially kept getting jdbc errors when we were not changing this, then bouncing the OC4J. (Not sure if bouncing the application would have been sufficient). • I guess three problems is really not that many when you think about it. In the ADF developers guide for 4GL programmers from Oracle, there is a section detailing how you could customize your exception/error handling. And since the users at Graebel really did not like the unique key error they were getting (“ORA- #####: …ABC_DEF_UK violation…blah blah blah”), I felt I had to get this implemented. I put all the code in 95% as it is copied over from SRDemo app, and it pretty much worked on the first go-round. It was a bit tricky though, because the error I tried to display was a field I hid by setting its containing af:column to the value of false. Apparently the SRDemo implementation of the error handler does not display errors for hidden fields. So I will have to mess with that a bit, but overall, the errors look better now. I was able to intercept any error containing “_UK” and replace the error with something more sensible to users. Also the SRDemo code gets rid of the prefixed JBO-#####. It also gets rid of all the “supporting” error stack if there is one. It just shows the “main errors” which is a lot easier on the poor users. For my particular application though, it appears the addition of the extra code from SRDemo to allow me to customize error messages is also causing critical varibles to be null…like #{row.xxxx}. I currently have an Oracle SR open on this. Hopefully it will be resolved by training days. www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons Sorting of columns disappearing It appears that if you have opted for sorted columns on a table that if, after you have created the af:table on your page, you add (bound) columns and data-bound text or field components to the table that the new columns by default are not sorted. I did not see how to make them sorted either. It turns out there are two things you have to do to these new columns. One of them is to set the af:column component’s sortable property to true. The other things you need to do on the column component is to find the property that specifies the attribute name of the underlying row set iterator that the column corresponds to, and put that name in that property. That does it. From my reading there are additional complexities introduced if your newly added column is for a table associated with a transient entity. But I was not doing that. If you are there are forum threads about this very subject and white papers devoted to helping you through this dilemma. (yikes). One thing I noticed about having the Sortable property in the af:column component is that it is possible to put an EL expression in this sortable property, and cause sortability to only be turned on at certain times. For example, if you make the value something like #{bindings.Commit.enabled ? ‘theAttributeName’ : ‘’} you can have conditional sortability that is tied to the same binding piece that controls whether the commit button is enabled or disabled. Commit/undo buttons not enabling when view rows have changed… I went round and round with LOV’s in some cases. But with a combination of defining an overridden page controller on the LOV page to keep validations from happening during partial page submits and sticking to putting an iterator of the base view in the LOV pagedef, then setting its values by using setActionListener components, this issue seems to have gone away. In addition to this I noticed that I could get the commit buttons to light up under circumstances by getting the current iterator from the binding layer programmatically, then getting the view of that iterator, and then setting the current row of the view. Putting in that first module and getting feedback from the user community. The first module I put into test for the end user testers to evaluate exposed a number of issues. For one thing they did not like the way errors are reported. Fortunately there are a couple of ways to generically alter the way errors are handled. The way that the ADF Developer’s Guide for 4GL programmers illustrates is a global method which changes the way errors are reported in a number of ways: • Certain errors are identified byJBO error number, and are categorically handled. For example there are a set of application module errors that are encompassed by a particular JBO error number. Should this error arise, instead of getting an error stack dump that is useful for troubleshooting, they get a readable English message which can be customized. These errors are in a message bundle format, so internationalization is no problem. • Just the top error is shown. Errors come in stacks often: this error was caused by this other error, which was caused by this third error. This ADF Developer’s Guide code just lifts the top error off the stack and presents it. • The JBO-##### is stripped off so the end user just gets the description. • There are opportunities for further customization. For example we looked for any instance of the name of a particular unique key constraint in order to give a simple message (like “Duplicate row entered.”) instead of a complex message (like ORA-12345: dml error on table abc_123; duplicate row detected for constraint ABC_123_UK). We are currently having some difficulty with this sample code. For some reason it combines with something we are already doing, and causes the references to #{row.whatever} to fail. I have created an SR. Oracle support is still fiddling with it. I think it may have to do with one of the classes that you have to override. So I am considering a work-around, which just turns custom error handling on for a particular page, rather than all pages in an application. There was a wealth of differing points of view in our testing community. On gentleman observed that creating an interface based on an af:table was a mistake. He thought it would be better for leaving the tables for selection of a particular row, then do an operation on that row that would take you to another screen or some other area of the screen…like a pop-up, or something. Another tester did not like the LOV idea at all. For our LOV icon we had a “flashlight”. Her experience with clicking flashlights had been negative in Discoverer reports, because some queries there needed tuning. So her hackles raised immediately when she saw the flashlight. I tried to reassure her, but she had already made up her mind; it was deep-seated hatred of the whole LOV concept. So she took up the sword of banning flashlights from this program, in favor of drop-down lists. From what I have seen so far, the drop-down list does not work very easily (or possibly at all) in the af:table. So that is another vote for doing the drop-down lists in a separate page, instead of doing the LOV in an af:table. www.rmoug.org RMOUG Training Days 2008
    • ADF Case Studies Fons There was also an expectation that validation would occur as soon as you left a field. This is doable in ADF, but there are some side effects which I have not worked out the kinks for yet. Another issue was that the testers started to look at the journal table tab of the form, and they noticed that there were indications that some user other than their own was doing the dml. This propelled the need for dynamic JDBC as described earlier in this paper. The testers were very disappointed that drag and drop was not yet available. It is in a way, with a lot more programming. But since there will be hooks for doing drag and drop in 11g, I am looking forward to experimenting with that. There were a variety of smaller requests, like adding a reset button next to the find button, so when users entered query criteria, they could reset the parameters’ values back to their default with a button click. There was a af:panelTip that someone wanted to change the wording for, in order to get a particular point across better. There was also a general observation that I made: none of these testers had ever seen anything from ADF before. They all had notions about what a computer program should do for them, but there were certain things I was telling myself initially that were not true. With this particular application, we have to actually introduce the users to how this kind of web program works. So while we were not held down by our former standards, we had an additional training onus as well. Resources a) JDeveloper forums – work with experts and Oracle’s JDeveloper developers on line. I believe they rotate who takes the forum on what weeks. i) Regular JDev forum ii) 11g JDev forum iii) OC4J forum b) Various expert blogs for ADF gurus c) ADF Developer’s Guide d) Oracle Open World proceedings, 2006 (CD Pack available for purchase) e) Custom Login module related docs i) http://www.oracle.com/technology/products/jdev/howtos/10g/jaasec/index.htm ii) http://technology.amis.nl/blog/?p=1462 iii) http://download-uk.oracle.com/docs/cd/B25221_02/web.1013/b14429/loginmod.htm#sthref517 iv) http://www.oracle.com/technology/products/jdev/howtos/1013/oc4jjaas/oc4j_jaas_login_module.htm v) http://www.oracle.com/technology/products/jdev/howtos/10g/dynamicjdbchowto.html vi) THANK YOU FRANK NIMPHIUS!! FOR ALL YOUR TIMELY HELP… f) Overriding the page controller to not validate on partial submit: http://www.orablogs.com/fnimphius/archives/001787.html www.rmoug.org RMOUG Training Days 2008