Saturday, December 25, 2010

I am currently in the best seat in an IMAX 3-D version of Tron Legacy!!!! Been waiting most of my adult life for this sequel. Lol...

Friday, December 17, 2010

JSF 2.0 paper coming

I am on the hook to present JSF 2.0 New Features presentation to the NoVAJUG February 17 or so. It should be fun. JSF 2.0 is really cool. I will publish this presentation to slideshare when I get it fleshed out.

J-Integra

On the project I am at now we are using a product called J-Integra for COM. It allows us to control Excel (in our case...probably any MS Office tool) through DCOM in Java. We tried things like Apache POI and Actuate BIRT Spreadsheet Engine/API first, but the spreadsheet we had to control had visual basic macros in it which called C++ DLL's. And Java does not (yet) understand anything about VBA, so those efforts did not work for us.

The set up of J-Integra is fairly minimal. There is a license xml file which is emailed to you upon request, and you must rebuild their product's JAR files using their JAR rebuild command. Then you have 30 days.

At that time you can run something called comtojava (I think) and it generates a great many java/class files which do the DCOM calls. There are also a lot of interfaces in there defined.

The result is that you can open/create a workbook, manipulate it, and close the book. The opening actually opens a copy of Excel, so you have pretty much complete API access. It is almost like a testing tool.

Hope this helps.

Friday, October 29, 2010

kudos to JSF 2.0's f:ajax tag!

It has been verging on too long since my last blog entry.

I have been reading in JSF 2.0: the complete referece by Burns, Schalk and Griffin about the f:ajax tag, and the Ajax implementation in JSF 2.0.

It's really cool.

Here is my background with Ajax. I have implemented Ajax solutions in JSF apps using straight JavaScript. This was kinda hard but not too bad actually. But I am fairly comfortable with JavaScript. I have also worked with the JSF Blueprint auto-suggest component. This worked out rather well and hid much of the details of the JavaScript functionality behind a JSF component. I have also studied a bit more than half of Deepak Vohra's book Ajax in Oracle JDeveloper and seen what a huge number of ways there are to do Ajax...and that is just with Java! I have also been working with ADF 10g's PPR solutions and my own frame/iframe kluges for years as well.

I really like the simplicity of the f:ajax tag. For starters, I love that you can get some basic, useful Ajaxian functionality simply by including the f:ajax tag either inside or wrapped around you JSF tags! This basically would do the equivalent of submitting those fields when the default event for those JSF components fires. The default JavaScript client event for a component is a sensible value depending on whether it is an action component or a value-change component.

Then it is possible to have all the flexibility of doing Ajax from raw JavaScript.

It is certainly much much easier than having to construct a bunch of JavaScript then do a bunch of request hijacking from a PhaseListener, like in JSF 1.1 and 1.2.

Thumbs way up guys!

Wednesday, August 18, 2010

Value Change listener method hint

Here is an important fact. Amazing even.

If you have ever experienced where you have a difference in the behavior of your ADF Faces screen between when somebody when you do a commit by executing the commit Action binding, or doing a commit by pressing a commandLink which fires an action binding...I have some help for you.

In my (sample) senario, I had changed a name in the Name field on a screen. I wanted to get this change into the database, because there is a unique key constraint in the database on the table column associated with this name field. When I create a new record, I call a pl/sql procedure to do the work, then execute a query, then go to the screen where this name field is. The name field has a default value in it, but it is important that the end user change this name field. So I put a value change listener on the name field, so that if they change the name, a commit will be fired.

The only problem was that the value change listener method is called before the value in the fields gets written to the binding layer. So you have to force it prior to calling the commit.

If you have Steve Muench's EL helper class you can do the following in the value change listener method:

EL.set("#{bindings.Name.inputValue}", valueChangeEvent.getNewValue());
Works great!

Thursday, August 5, 2010

AjaxTags

As I continue to work through Deepak Vohra's Ajax in Oracle JDeveloper book, I was very impressed not only by the book (thanks Mr. Vohra!), but also AjaxTags.  I must be tag/jsp-oriented, because I tend to view just using javascript to do Ajax as being kind of messy.

It has not taken me very long to get the example in this book which demonstrates AjaxTags up and running.  There were a few gotchas.  For example, in the example there were only three javascript files which needed to be included in the jsp page using script tags with source attributes.  The book was written in 2006.  Now in 2010, using the next major version of AjaxTags there are 7 or 8 javascript files, which I had to include.   Also Vorha-ji used a "button" tag, which in my browser issued a submit.  If you are doing Ajax you don't want to use a button that automatically submits, so I switched to using an <input> tag with a type attribute with the value of "button".

With this example I could register a select list and a button to do Ajax transactions with (in the jsp) only the following two tags:

<ajax:htmlContent baseUrl="formservlet" source="catalogId" target="validationMessage"
parameters="catalogId={catalogId}"/>

<ajax:updateField action="updateForm" baseUrl="formupdateservlet"
parameters="catalogId={catalogId}" source="catalogId"
target="journal,publisher,edition,title,author"
parser="new ResponseXmlParser()"/>
So, in this example, you had to define two servlets, one called formservlet and one called formupdateservlet.  The ajax:htmlContent tag above made it so that if you changed the selected value of a select list with the id of catalogId, it would "doGet" on formservlet with the request parameter which has that selected value.  The value of the element with the id of "validationMessage" (as specified in the ajax:htmlContent tag above) is set to the text of the response of this servlet.  That is a lot of meaning to pack into a little tag...but that "meaning" is just what we want, time and time again...isn't it...with AJAX.

The second tag, ajax:updateField, keys off of a button whose id is updateForm (see the action attribute of the tag above).  This button click does a doGet on formupdateservlet, again passing the parameter of the current value of a select list with the id of catalogId.  The target attribute is a comma-delimited list of element ids in our form of various fields we have.  This servlet (formupdateservlet) produces XML, unlike the formservlet, which just produced text.  So we specify a parser in the tag above to handle the XML.  I think then that you just have to make your servlet produce elements which match these target element ids.  Again...very compact...but exactly what we are looking for.  The only javascript involved is the script tags which include the AjaxTags javascript libraries.  These are the ones I had to include:

<script src="prototype.js" type="text/javascript"></script>

<script src="scriptaculous.js" type="text/javascript"></script>
<script src="overlibmws.js" type="text/javascript"></script>
<script src="effects.js" type="text/javascript"></script>
<script src="controls.js" type="text/javascript"></script>
<script src="ajaxtags_controls.js" type="text/javascript"></script>
<script src="ajaxtags_parser.js" type="text/javascript"></script>
<script src="ajaxtags.js" type="text/javascript"></script>
Scriptaculous is used to make some of this happen, and is part of AjaxTags.  It has some support javascript files which I did not include.  It would probably be safest just to include all of them, since there are not that many.

That's it! 

I would like to explore this a bit more (since this example does not begin to cover AjaxTags functionality fully) and see how it performs when incorporated into JSF pages.

Wednesday, August 4, 2010

Continuing to look at Task Flows

I have a question now about Task Flows in Oracle ADF Faces/Bindings 11g.  I see from reading Frank Nimphius and Lynn Munnsinger's new ADF book, how you can make two page fragments talk to each other by creating an event map in the parent page's pageDef, and then raising events in one fragment's bindings, and "consuming" these events with a backing bean method in the other fragment.


What still does not make sense to me is...how does the binding know what event to raise?  Granted:  I am still messing with ADF Faces 10g, but af:tables, af:tree's, etc. have more than one event associated with them.  And yet in this book I do not remember reading a description of how and event raised in the binding knows what kind of event to raise...


For example if I select a node on a tree and that triggers a context event, and then I expand a node on a tree and that triggers a context event (if that is possible...?), where does the link occur between the binding event and the particular component event?


This has more to do with events and production/consumption of them across bounded task flows for page fragments. The example in the book is as follows. On a page there is a panel splitter. On the left side is a tree with deparment nodes and employee nodes under each department node. On the right side is either a department or an employee data update screen with fields and a save buttons. The selection of a dept or emp node on the left gives you an update screen on the right with the correct row queried up. The left and right side are both regions with bounded task flows inside containing page fragments. the parent page (the one with the splitter) has the task flow bindings on it, plus it has the event map defined on the task flow bindings.

So the part I am confused about currently is when you click the tree and the tree binding raises an event, you just enter in the page def for the tree the xml element <events> with and <event> sub-element in it. In the event map you map this event producer to the consumer page/bindings on the right to get a sub-dynamic task flow to either show a emp or dept page fragment. But I do not see where it says what kind of event is getting generated. Surely a tree node can generate more than one kind of event. for example a node can be clicked/selected. Also a node can be disclosed/opened or closed/shut/collapsed/whatever.

I think the following comes close to answering my original question (taken from FUSION DEVELOPER'S GUIDE 11g):

You can raise a contextual event for an action binding, a method action binding, a value attribute binding, a tree binding, a table binding, or a list binding. For action and method action bindings, the event is raised when the action or method is executed. For a value attribute binding, the event is triggered by the binding container and raised after the attribute is set successfully. For a range binding (tree, table, list), the event is raised after the currency change has succeeded. Value attribute binding and range binding contextual events may also be triggered by navigational changes. 

Contextual events are not the same as events raised by UI components. For a description of these types of events, see the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework. Contextual events can be used in association with UI events. In this case, an action listener that is invoked due to a UI event can, in turn, invoke a method action binding that then raises the event.

What is confusing to me is the documentation says you can associate an event with bindings of different types, and that the binding-associated events are not the same as ui component-associated events. But then they turn around and say that these binding-associated events all happen in response to actions for which there are component listener properties. So I naturally would assume that we would then says that...these binding-associated events are raised in direct response to the corresponding component event.

From a high level, anyway, it appears that for these binding-associated events we are triggered by a particular event in association with that binding. For range bindingg (tables, trees) the big event is changing of "row currency". (OR POSSIBLY NAVIGATION). Action/Method: when the thing is executed. Attribute -- when the value is set. So I guess the payLoad is different in each case? For the row currency, is the default payload the row? I think for the action, the payload is whatever the action or method returns...? the attribute...the new value? More reading...

Wednesday, July 21, 2010

Continuing Impressions of JSF 2.0 Cookbook


7/16/2010 9:36:01 PM


 

After just having gone through the selectOneMenu custom car converter example, I have to admit it does seem to use JSF to best advantage. I have often wondered why SelectItem takes an Object as its key value. I kept thinking: why isn't this just a String? This example answers that question. I learned that a converter is called for each item in the select list to come up with the options element values within the generated select list.


 

This must be one of those powerful examples that the author was speaking of in his forward. Nice! I am glad to have this example as a reference, and look forward to trying to these list concepts right from now on.


 

7/18/2010 7:41:48 PM

OK, the next example is just a tweak of the first example; the code as shown in the book, however, does not work. However it is very close to what does work. The value of the selectManyCheckbox should be a list of CarBeans. And the rendering page should have the dataTable having a value of the same list. In the managed bean I defined such a list and in initialized it to an empty ArrayList of CarBeans. After this adjustment this example worked fine. After looking at his example code this is what his example did; it would be good however if in his book, he were to mention changing the datatype of the selectedCar property.


 

The next example is fine and is explained fine, although the names of his variables were odd. Calling a number converter "number" and calling the number that was being converted "numbery" was bizarre. I guess the author had his reasons.


 

This next example is good. It is exposing some converters in other JSF component sets – RichFaces in this case. I am looking forward to trying it out and starting to get a feel for some JSF component offerings other than the ones I am currently familiar with.

Monday, July 5, 2010

First Impressions of new Book


Overall I think the cookbook is pretty good. I am not very far in it yet, but it seems like the author is a lively creative technically proficient person who will probably do a good job covering some intermediate/advanced JSF 2.0 implementation topics. I would say beginner also, but I think there is too much left out to really call this a manual that helps beginners.

If you would like to see my first impressions as I had them please keep reading…

6/25/2010 6:35:24 PM

Sounds like Anghel Leonard (author) has some good experience writing books and developing Java and maybe other technologies.

When reading a technical manual I always study the table of contents. After doing so I am usually more excited about what I am reading because I am aware, not only aware of what the book covers, but also of topics and combinations of things that I have never thought of before. That is certainly the case with Mr. Leonard's book's Table of Contents. I come away from his TOC thinking that if I can learn about 1/7th of what is in this book I will be learning quite a bit! He covers not only JSF 2.0, but apparently how it integrates with 30 or 40 other technologies. So: I am looking forward to continuing to read. On to the Preface…

"What this book covers" is an elaboration on the TOC. After reading that and the following section, "What you need for this book," I am beginning to wonder if this is more of a JSF book with some JSF 2.0 thrown in…? Not sure there seems to be some indication that you can use this book with JSF 1.2 or 2.0. I am wondering how that would/will be accomplished? At any rate, even if the subject matter had little or nothing to do with JSF 2.0, the range of topics seems amazing…and I am still looking forward to continuing my read…although…if JSF 2.0 is not so much the focus, maybe the book should not be called JSF 2.0? OK, I will shut up and continue reading to see what Mr. Leonard's bent is.

The who is this book for section: I am not a newbie to JSF, but I would love a look at some "best JSF practices," so I can improve my coding ability and compare the code I have seen in projects that others have written, and code that I have written and see how it compares/sizes up.

I just noticed something kind of funny. In order to assure that copyright is maintained for the e-book copy they gave me, they have given me a pdf with a not at the bottom saying this book is registered to me, then it gives my address, but instead of <city>, <state> <zipcode> …they have put <city>, <county> <zipcode> …I guess I am easily amused. Just like when I first started trying to learn a bit about Hindi, I learned that /dood/ means "friend". I found this funny because "dude" in English is sort of slang for "guy", or about 15 other meanings…probably including "friend"…in fact some people communicate *only* using the word "dude" with different emphases and inflections. Aside over.

Well, I found my first typo on page 8; typos are probably the price you pay for getting relevant textbooks out before they are out of date… I can live with typos, as long as the example code works. I will download the errata, example code, netbeans, and other software needed for the exercises in this book (looks like about 25 different software packages!).

OK, now wait a minute. The author used a phrase "converter lifecycle." Strictly speaking it is the JSF Request Lifecycle he is referring to. And what is a "render page?" I know he knows what he is talking about, and I am probably picking at nits…so I will try to tone it down a notch.

I can tell that reading this manual will take some getting used to. I am not sure where the author is from, but I am having a bit of trouble negotiating his explanations. Right now, however, I am kind of tired; so perhaps this is an unfair statement. Maybe with more sleep and a little patience I will have a better "meeting of the minds" with Mr. Leonard.

I can tell he is covering the material. It kind of seems like he has 1000 different ideas in his mind in his head about a particular subject and the sentences he reveals come out like lottery balls. But let's face it: his goals for the audience of this book and the breadth of the topics he covers, this book may end up being more like trying to read War and Peace, by carefully tearing each page out of that book, stapling these pages to the Bonnyville Salt Flats in a straight line, fixing a camera pointing downward on the side of the Blue Flame car, and then trying to read this novel through the camera's eye view while the driver uses the line of pages as a guide-line to drive next to.

6/27/2010 7:49:26 PM


 

I think I am in a better frame of mind now. Sorry for the whining…anyone who might be reading this. I have downloaded the code and started filing errata on this text.


 

It is fairly embarrassing but I have never tried net beans. I downloaded version 6.9. Since I already had glassfish v3 installed. I saw from the startup script for my already-installed glassfish app server that the default domain name was domain1. So I was relieved when I gave Netbeans the install directory (c:\glassfish3 on my machine) and it found domain1 automatically and installed it. I just had to go to the window menu, services sub-menu, and specify I wanted to add a server by right-clicking the servers node and choosing "add server…".


 

Then I opened the Projects window, and right-clicked New Project…


 

I created a new Java EE project. It activated "Java Web". I took the defaults on this application. So it created an application with two Java EE modules: an EJB module, and a war module. These basically correspond to the model and viewController projects on a JDeveloper application. The war module had a libraries directory, to which I added the JSF 2.0 libraries. Then I created a new page under the war module's Web Pages folder. The page type I created was "JSF Page"; this allows you to create a facelets page. When I created a facelets page, netbeans automatically added a web.xml file.


 

Netbeans creates a default "hello world" facelets page. I was able to run it by right-clicking the .xhtml file I had created in the Projects Window, and choosing run file.


 

At that point I was able to simply put the code into the ide.


 

7/2/2010 6:26:56 PM


 

I like the simple example that Mr. Leonard starts off with. I wish that the text had not chosen to put a line break in the middle of the "faces-redirect" directive/parameter; the author used this feature but did not really explain why. The other JSF 2.0 book I read did not use this until they had explained why. Not sure which is the better approach. This directive does not work if there is a line break. I am assuming the sample code is OK in this regard so that one can check this. Probably though, since the line break does not throw an error, anyone that copies the text out of the book will never know that it was wrong, but perhaps they will see it and it will start their subconscious mind working on getting-used-to-seeing-it so that later, when it will probably be introduced in earnest, the learning will come easier.


 

But, as I said I do like the first example, because of its simplicity. This simplicity allowed me to find my feet with netbeans, to experiment with explicit conversion (explicitly using a double converter when the backing bean property is an int…just to see what it would do.


 

Aside: in case anyone is wondering why I am focusing so much on JSF 2.0 lately, I am thinking that Oracle will maybe keep using JSF and eventually adopt this standard…perhaps even soon. So, we will see; just trying to paddle ahead of the wave so I can surf to shore in style. End of aside.


 

I think the use of the term "recipe" in this book may not be the best word; while the code is enough for me, the beginning of the book says one sort of audience this book is supposed to cater to is people who know the basics of JSF and not much more. Such a user may not know anything about, say, setting up netbeans or glassfish and could be given a little more help possibly. Typically a recipe in a cookbook spells out precisely what you need to do to make it happen. Of course if you do not have a tablespoon, or know what a degree of temperature is, or what an oven or a stove is…well you have a problem. I will continue to reserve judgment.


 

The second example is a good example for f:convertNumber component; it shows lots of different usages for anybody needing them. At the moment I do not, but it is nice to know this resource exists for reference or to teach a beginner. Also I enjoyed seeing some usages of Max* attributes, as I have mostly used patterns when I needed them.


 

I really like the next example…especially the usage of locale. I have not used the locale features of JSF much, and it is nice to know there is that flexibility whenever we may need it.


 

The next recipe is a toughy. This seems like a tip/trick, of which it will take me a while to discover the true value. This recipe deals with JSF sometimes inconvenient habit of not being able to use a converter to deal with null values, because converters are not fired. This is an annoying feature of JSF. The nice thing about JSF 2.0 is that there have been some new additions to help alleviate this pain (NOTE TO SELF: GO RESEARCH WHAT THESE ARE AGAIN). But it is always good to have many ways to do something in case one particular method has side effects you do not like. So thank you very much, Mr. Leonard. I will have to read it through a few times and maybe implement the recipe before I completely get what it is doing.


 

This keeps occurring in this book. I can tell that Mr. Leonard is probably not a native English-speaker (just like I did not grow up speaking Romanian, which may be Mr. Leonard's nationality and native tongue). What keeps occurring is I keep getting distracted by certain usages of the English language. These usages may make sense in Romanian (assuming that is Mr. Leonard's native tongue), or they may be perfectly fine usages of this word in some dialect of English, or perhaps they sound like other English words and get swapped out for the correct word, or perhaps Mr. Leonard is just creative. At any rate, I am having trouble reading the text of this book quickly because of strange usages of interjections that are not used quite right (in my opinion), words that are close to some other word like "particularity", and words that are not helpful, like "Placebo.". In the case of particularity, I think he might have meant "peculiarity" or probably some other word. He seemed to want to say that the hash codes on null objects will be different than the hash codes of non-null objects when using this class. And the use of Placebo brings to mind the usage of a sugar pill instead of actual medicine. Maybe NullConverterObjectHelper would have been another choice that would have made more sense when read back.


 

Still though, I would have never thought of this approach; so: bravo, Mr. Leonard, for your creativity, and thanks for the tip and the insight into directly overcoming this problem.

7/5/2010 1:52:33 PM


 

I implemented his example, and now I see clearly what he was trying to accomplish: whereas before I thought he was trying to obtain a substitute for the required attribute for EditableValueHolder components, which would still run use the converter, I see in his example he is trying to also intercept an initial value as well of the managed bean property in question. I am not sure however why he decided to make hashcode Placebo return a value…why not just look for instanceof Placebo in the converter? I am also trying to decide in my own mind if Placebo was really the ideal name for this class. It's purpose is to substitute for a null value…but it serves a real purpose, unlike a real-life placebo…ah, who knows anyway…I know what he means.


 


 


 

Thursday, June 24, 2010

Reviewing JSF 2.0 cookbook

Well, readers, I am reviewing a book for Packt Publishing, called the JSF 2.0 Cookbook by Anghel Leonard.  My mind is open and I am expectant about the content, as it surely seems like good subject matter; I will be getting started reviewing it probably on the plane ride back to Denver tomorrow.

Here is more information about the book:  book link  

I will let you know my impressions for this book and the two other big ones I am working on as well, as usual.

Tuesday, June 22, 2010

Conversion and Validation in JSF 2.0


Well, we have all the old stuff plus some new stuff here. The most remarkable additions I can see here are that a validator tag can now wrap a set of tags…not just be a child in one that needs a validator added to it. So your page can have default validators. Another addition that I don't entirely understand the syntax of yet is Java EE 6 Bean Validation. This seems very useful, but the syntax is a bit odd to me. But mostly this is because I am not familiar with defining custom annotations. Also they seem to have come up with a new usage of generics…I guess it is the same, but the usage bent my mind in a new direction.

So let me elaborate. ("Go right ahead!" you are probably thinking) Let's say I start by removing the 'validator="#{userBean.validateEmail}"' code from my h:inputText tag. I do this because when I get everything switched to Bean Validation, I will not need this JSF tag validation any more. I then put the custom annotation @Email above my UserBean.java property declaration for the "protected String email;" property. If I recompile at this point I get an error: UserBean.java:18: Cannot find symbol…symbol: class Email… So the compiler knows this is an annotation but it does not know about it yet…because I have not created that class yet.

Now I define the class that defines my annotation (code taken from (Ed Burns, 2010)):

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;

@Documented
@Constraint (validatedBy = EmailConstraintValidator.class)
@Target ({ElementType.METHOD, ElementType.FIELD})
@Retention (RetentionPolicy.RUNTIME)
public @interface Email {
String message() default "{validator.email}";

    Class<?>[] groups() default {};

    Class<? extends ConstraintPayload>[] payload() default {};
}


If you have never defined your own annotation before there a lot of mysteries to unfurl in this class. The two bits I think are the most important is the part that points to the class where our validation code is stored (…validatedBy = EmailConstraintValidator.class…), and also the bit which stores what message will occur should the validation indicate that (in this case) our email is not valid.


 

OK: so now when I try to compile Email .java, I get a complaint that package javax.validation does not exist. This is my JSF 2.0 manual says the Constraint annotation lives. So that means there is a jar out there I need to find somehow. This is not surprising since my manual (Ed Burns, 2010) says that this is a Java EE 6 (container) thing and not just a JSF thing. So…where to look…I am using glass fish, so I imagine that Glass Fish knows about this jar. Maybe if I ask it nicely, it will tell me where it is kept.


 

OK, I went looking through administrator's console, and there is nothing jumping out at me…like "find a jar with a known class in it". Maybe JDev fine search will prove useful…well not so much. Of course I was trying to use the search files tool. Maybe there is a different tool?


 

Meanwhile I went on a manual hunt through all glassfish jar files with suspicious names. Like for example there is a javax.annotation.jar Well, then!! That certainly sounds promising! But when I used VIM to inspect the contents of this jar file…I found…no javax.annotation.Constraint!! Very odd. I also searched for javax and annotation in all the files under the glassfish installation directory. It was not there. So: maybe glassfish does not offer Bean Validation? I thought it did since it was Java EE 6. But maybe it is not the Enterprise edition or the weaseldoodle's edition or some-such. I will have to ask what is going on with this when I get out of the sky in back into internet areas.


 

OK: so this is a good URL to know to find this JAR… http://jcp.org/aboutJava/communityprocess/final/jsr303/index.html


 

Javax.constraints.ConstraintPayload.class seems to be a hard one to track down. The JSR says that the reference implementation is hibernate validator. When I open that up I see the source contains one jar called validation-api-1.0.0.GA.jar but this has no class in it called ConstraintPayload. It does have a "Payload" class in it however. So then I tried to do a mvn install on the online code for chapter 8 for (Ed Burns, 2010) and it all built ok. His source included references to ConstraintPayload…so I reasoned that he must have a different jar. So I looked in his pom.xml for this code and it referred to bean-validator.jar, and referred to org.glassfish (great! That is what I am using!) and also JBoss (darn…not what I am using) and something about Beta (yikes!!). Sure enough there is a bean-validator.jar in my glassfish distribution (yay!!) also with no mention of ConstraintPayload.class (damn, damn, damn). Apparently I have to download a jar from http://download.java.net/maven/2//org/glassfish/bean-validator/3.0-JBoss-4.0.0.Beta3A/bean-validator-3.0-JBoss-4.0.0.Beta3A.jar


 

Jeez! I am beginning to wonder whether they renamed ConstraintPayload.class to just Payload.class…


 

And of course…this is correct according to http://opensource.atlassian.com/projects/hibernate/browse/HV-319 "Hardy Ferentschik added a comment - 06/May/10 4:55 AM --javax.validation.ConstraintPayload got renamed into {javax.validation.Payload}} for the final release of the Bean Validation spec…" Well, OK then. So I am going with the jar that came with GlassFish!! That is: bean-validator.jar, and change my ConstraintPayload.class references to Payload.class.

So now the class that defines the Constraint annotation refers to the Validator. But the Validator class also makes reference to the annotation class. So neither one can finish compiling it seems…? This is kind of annoying…how does maven compile this shit as is? It must compile twice, the first time suspending failing compilation if there is this kind of cross-reference. It must be some kind of directive that is made just for annotations…OK: I'm a forgetful so-and-so: the class path must contain either jar's (that I knew) or directories that contain the base of packages you need during compilation. Interestingly I see that the java compiler compiled both files when I only explicitly asked for the compilation of one file:

In the C:\sandbox\jsf2-0book\facelets1\target\facelets1\WEB-INF\classes\com\jsfcompref\model directory, I issued a successful compilation command of EmailConstraintValidator.java, when it was dependent on another class called Email.java in the same directory. Email.java had not been compiled yet, but it was valid except for a reference to the EmailConstraintValidator.java class.

In the compilation command, javac -classpath jsf-api.jar;jsf-impl.jar;bean-validator.jar;..\..\.. EmailConstraintValidator.java, we see adding ..\..\.. gives visibility to the directory that contains the com\jsfcompref\model directory which is the base of the package that Email and EmailConstraintValidator declared as being located in.

Friday, June 18, 2010

SSL/SSO/JAZN-enable iAS 10.1.3 that is authenticated with 10.1.2 OID

So our client's topology was iAS 10.1.2 infra with OID on machine 1, and two mid-tiers on machine 2 -- one 10.1.2 Portal instance and the other 10.1.3 J2EE (OC4J) instance with added OHS (HTTP Server) to enable Oracle SSO.

We would create portal pages, and put iframe calls to web-apps in the 10.1.3 iAS. Since both were SSO-enabled authentication and authorization was no problem. I believe I have covered how to SSO/JAZN enable 10.1.3 a year or two ago on a different blog entry for this same blog.

However, when we added SSL (terminating at the Web Cache) this iframe arrangement did not work out so well. This is for several reasons: one the military establishment with which we were affiliated had the rule that only port 443 shall be used/seen by external users. With the iframe arrangement, there were additional HTTP ports (i.e., the 10.1.3 HTTP Server port) that needed to be open on everybody's firewalls. This was unacceptable to our end-users.

The second nastiness we encountered was that while our computer hostname was one thing (according to dns), there was another alias that pointed to the same IP which was the external users moniker of choice for our mid-tier computer. So the 10.1.3 mid-tier and SSO registration wanted to use the host name, while all external references were to the alias. So, when it came time to register the SSL certificate, we had to pick one...we thought. So we picked the external alias. Either choice would have created nasty certificate errors when the other name was attempted to be used, because a certificate is often for a particular name...although we learned that (for a fee, of course) our certificate company would allow wild-cards.

So our end users hated the certificate errors, so we called Oracle Support. We worked with them, and what we worked out...really...is the topic of this blog entry.

In short we implemented the section in the following Oracle doc Oracle Application Server Administrator's Guide 10g Release 3 (10.1.3.1.0) B28940

The above doc contains some information in section 6.4 entitled "Configuring Oracle Application Server 10.1.2 with Oracle Application Server 10.1.3"

Note that for the opmn.xml entry we saw that the port element showed a remote port, which we used to create an entry such as the following:
<notification-server interface="ipv4">
<port local="6100" remote="6202" request="6005"/>
<ssl enabled="true" wallet-file="$ORACLE_HOME/opmn/conf/ssl.wlt/default"/>
<topology>


</notification-server>
... where 6200 was the remote port of the portal mid-tier and 6202 was that of the 10.1.3 mid-tier...as you can see in the "port" element above. Note that all we added was the <toplogy> element and its nodes child as per the doc I mentioned.

Also per the aforementioned doc, we altered the mod_oc4j.conf file. We added additional Oc4jMount entries to tell the Web Cache (I think? or maybe the HTTP Server) of the Portal instance to communicate with 10.1.3 instance whenever it saw a context-root (i.e., the part of the JSF web-app url that is right after the domain but before the "faces" bit. It designates with J2EE/Java EE app you are referring to on the server you are addressing with your URL. Some of these entries looked like this:
Oc4jMount /ContextRoot1 ajp13://ourmachinename.oursite.org:8888
Oc4jMount /ContextRoot1/* ajp13://ourmachinename.oursite.org:8888
Oc4jMount /ContextRoot2 ajp13://ourmachinename.oursite.org:8888
Oc4jMount /ContextRoot2/* ajp13://ourmachinename.oursite.org:8888

Note that we obtained the 8888 port by doing an "opmnctl status -l" on the 10.1.3 site, and looking for the primary ajp port for the OC4J to which our apps were deployed.

httpd.conf on the Portal/Web Cache instance we had been using proxy and reverse proxy entries for these two apps (as designated by the ContextRoot* designations above. We had to comment those out.

I appologize that I cannot give more details about SSL enabling the topology, because I was not really involved more with that process. It was involved though, and took the people that knew what they were doing 3 hours to hand-enable a pre-existing production topology as I described. That might give you an idea of what was involved in this SSL enabling process for this technology stack.

Thursday, May 20, 2010

post-redirect-get in JSF 2.0

In Burns's and Schalk's JAVASERVER FACES 2.0: THE COMPLETE REFERENCE, the authors do some exercises regarding redirects. There are new facilities in JSF 2.0 to allow using redirect to easily follow the post-redirect-get convention (instead of the normal JSF post-forward convention). Now with these facilities we have bookmarkable url’s in our web browser. We also expose some of our parameters to whomever looks at their address line. Under some circumstances this is OK.

The conversion of a page that does not use this to one that does is pretty quick. I took the same book's registration application and converted it to use PRG (post-redirect-get) in one airplane ride (3 hours) and I only worked 2 of those hours, and I worked very slowly.

There are apparently two ways to communicate between pages that use redirect in JSF 2.0. One of them is to use a new “scope” called Flash. Flash allows you to store information between redirected pages; apparently request scope does not. Redirecting makes a second request, whereas the normal post-forward does the page/view navigation all in one request. So that means that things stored on request scoped managed beans will persist from one page to the next, while redirects will re-instantiate request scoped beans.

The other way to store stuff in between redirects is to pass parameters on the request url. Interestingly the new view parameter facility has the parameters defined on the page you are going to. If you define them on this page/view, then there they will be…on your request url, as if you had put them there yourself (which you did…indirectly ;-)

Interestingly enough, ADF 11g, the controller portion, has solved the same issue in JSF 1.2 with something called bookmarks. These bookmarks make a structure called a task flow compensate (like view parameters and redirecting combination in JSF 2.0) for the same issue. I suspect in the long run ADF will adopt JSF 2.0. I wonder if at that point, view parameters will have something to do with the implementation of bookmark parameters.

Thursday, May 6, 2010

thread dump for OC4J JVM

To get a thread trace on a JVM, make sure your opmn java-options in your start-options does not include -Xrs. (If you had to remove it, be sure to restart your AS (maybe the OC4J restart would be enough...)) This -Xrs option reduces signaling capability. Then (in UNIX) you get the JVM process id to kill. One way is through Enterprise manager. In 10.1.3.4 EM, in your topological list of oc4j's, you should have a link showing how many JVM's you have for each oc4j you have in you iAS. If you click on this, the resulting page will show you your process id. If you then type
kill -3 <theprocessidyoujustlookedup>
and hit enter, your opmn log (you know: the one in $ORACLE_HOME/opmn/logs that has your oc4j's name in the middle of it, with tilde's in the name...*THAT* log) should display a lovely thread dump.

I wanted a thread dump because such a thing seems to be how Oracle characterizes their bugs against their iAS. So for example they might say, if a thread dump shows the following...then you have this problem...and here's how to fix it.

Thanks to Mike Lehmann for his helpful article, which you can see, is just a click away; I basically took what he did, distilled it and added the things I had to go look up.

Thursday, April 22, 2010

JSF 2.0 exploration notes

As I embark along the path to learning JSF 2.0 from a having a fairly firm, intermediate grasp of JSF 1.1/1.2; I am following Burns and Schalk’s JSF 2.0: the complete reference. I got my current grasp of JSF in no small part from studying and referring to their book by the same name which pertained to JSF 1.1/1.2. In that former book they started you off doing the assembly of the deployable war by hand from the source code which they walked you through in the book in detail. The newer book starts similarly, except that the new book seems to rely on Maven to construct the war file. While I have maven installed on my machine, my lack of the downloadable pom file from the book’s on-line downloadable source code website, the book’s failure to spell out the pom file (probably due to size??) in the text of the book, the fact that I am on an airplane and unable to download anything, and my undeniable stubbornness – all these things add up me now assembling the exploded war directory by hand – according to the book’s documentation of what this exploded directory structure should look like and what it should contain. When I have this, I will use jar –c to build a war file because I just don’t have the patience to wait until I get off the plane to build my first JSF 2.0 program! I will have to go from memory and jar --help and experimentation to accomplish this. Wish me luck!
Some observations so far: jsf-api.jar and jsf-impl.jar seem to be all you need to compile a JSF 2.0 program (which does not use any external libraries). That is to say…no more standard.jar, or commons*.jar any more…which is not surprising, since JSF 2.0 is based on Facelets, and not JSP/JSTL etc. Also: no more faces-config.xml (if you don’t want to); you can go with all annotations if you want that.

After I installed java 1.6 JDK, set up the exploded directory copying the xhtml to the exploded directory’s root directory, copied the two jsf jars into the WEB-INF/lib and the source packages into the WEB-INF/classes directory of my exploded directory, and the web.xml file into my WEB-INF directory, I executed the following command:
javac -classpath ../../../../lib/jsf-api.jar;../../../../lib/jsf-impl.jar UserBean.java
…where UserBean.java is the book’s first sample class (backing bean/request-scoped-managed bean).
Then I went to the root directory of the exploded directory and executed the jar command to make the war:
C:\sandbox\jsf2-0book\personaltrainer\target\jsfreg>jar cvf jsfreg.war *
added manifest
adding: register.xhtml(in = 2690) (out= 730)(deflated 72%)
adding: WEB-INF/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/com/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/com/jsfcompref/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/com/jsfcompref/model/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/classes/com/jsfcompref/model/UserBean.class(in = 2305) (out= 109
1)(deflated 52%)
adding: WEB-INF/classes/com/jsfcompref/model/UserBean.java(in = 2378) (out= 757)
(deflated 68%)
adding: WEB-INF/classes/com/jsfcompref/model/UserBean.java~(in = 2377) (out= 754
)(deflated 68%)
adding: WEB-INF/lib/(in = 0) (out= 0)(stored 0%)
adding: WEB-INF/lib/jsf-api.jar(in = 591845) (out= 530662)(deflated 10%)
adding: WEB-INF/lib/jsf-impl.jar(in = 1816536) (out= 1682891)(deflated 7%)
adding: WEB-INF/web.xml(in = 883) (out= 384)(deflated 56%)

C:\sandbox\jsf2-0book\personaltrainer\target\jsfreg>dir
Volume in drive C is SW_Preload
Volume Serial Number is B2D3-A76F

Directory of C:\sandbox\jsf2-0book\personaltrainer\target\jsfreg

03/05/2010 07:56 PM <dir> .
03/05/2010 07:56 PM <dir> ..
03/05/2010 07:56 PM 2,219,418 jsfreg.war
02/28/2010 07:37 PM 2,690 register.xhtml
03/05/2010 07:10 PM <dir> WEB-INF
2 File(s) 2,222,108 bytes
3 Dir(s) 111,780,872,192 bytes free

I am confident (grin) that this war file will deploy ok on the glass fish web server that I downloaded and have yet to try (at least after I correct all my typos) from copying the book’s code manually.)

Looks like I am already using port 8080, so I will need to ask glassfish nicely to use some other port as its default… (or Oracle XE…that seems to be the other user of this port number…). Oh well: the trip back.

3/14/2010 8:23:25 PM

OK, I finally got my own code going…that is to say…the code I tried to copy manually form chapter 1 I finally got to run on glassfish app server.

Apparently I had made a number of critical typos, which has interesting results. The most interesting of these was the mistakes I made in the web.xml file:
1. In the root element (web-app?) the xsi:schemaLocation attribute’s value has a couple of places in it where it should say “…/xml/…”. For some reason I had mistakenly typed “…/sml/…”. This letter difference was enough to confuse the html server for glass fish in to responding with a 404 code, saying that a “resource” was missing. Obviously that was not a very helpful error. Once I got through that however there was …
2. In the servlet-mapping element I had a sub-element defined called url-mapping. I should have called this sub-element url-pattern instead. This however kept deployment from happening properly.

After solving these errors, I had to correct three minor typos in register.xhtml, then things worked fine. These typos were mine, not the book’s – I am sure.

Anyway, as I was getting things in running condition, I remembered reading that I could deploy on glass fish as an exploded directory. I had done such a thing on weblogic server (when it was still bea weblogic (10.3 I think)). Up until trying to do this on glassfish, I had been using the jar command above to package things up as a jar in between changes. I got pretty quick at it, but not quick enough to compete with the speed of working on an exploded directory and just recompiling when necessary.

So basically I just deployed the root directory I had been jar-ing up, and it worked fine. I made a change or to to the xhtml files, and hit f5; then I saw the changes I had just made. Great!

Back to the book now for more information…

4/16/2010 7:26 PM

So some new things I have learned today about JSF 2.0:
1. On page 96 of [Burns] is a section called invoking arbitrary methods in EL. This means that, for instance, if you have a method that returns a string you can conjure up an expression like the following, and put it right in the middle of your page: #{myManagedBean.myMethod(someOtherManagedBean.property1, anotherManagedBean.property2)} (BTW: the caveat here really got my attention: this kind of invocation in EL is only available if your EE6 container is Java-based. I was not aware there were any other EE6 containers besides Java-based EE6 containers.)
2. …

I next want to talk about Facelets. I have made a stab or two at working with Facelets. Now that I am studying JSF 2.0, Facelets is the standard, not JSP any more

So in my first experiment, I took the files (the little registration program in chapter 3) and tried to use the templating concepts presented in Chapter 4 a reality; so I got the template file and template client file which references the template through the ui:composition tag. But when I start referencing the template instead of the full page I had in the register.xhtml page I get the following errors:

• Warning: This page calls for XML namespace http://www.w3c.org/1999/xhtml declared with prefix body but no taglibrary exists for that namespace.
• Warning: This page calls for XML namespace http://www.w3c.org/1999/xhtml declared with prefix title but no taglibrary exists for that namespace.
• Warning: This page calls for XML namespace http://www.w3c.org/1999/xhtml declared with prefix tr but no taglibrary exists for that namespace.
• Warning: This page calls for XML namespace http://www.w3c.org/1999/xhtml declared with prefix tr but no taglibrary exists for that namespace.
• Warning: This page calls for XML namespace http://www.w3c.org/1999/xhtml declared with prefix html but no taglibrary exists for that namespace.
• Warning: This page calls for XML namespace http://www.w3c.org/1999/xhtml declared with prefix td but no taglibrary exists for that namespace.
• Warning: This page calls for XML namespace http://www.w3c.org/1999/xhtml declared with prefix table but no taglibrary exists for that namespace.
• Warning: This page calls for XML namespace http://www.w3c.org/1999/xhtml declared with prefix h1 but no taglibrary exists for that namespace.
• Warning: This page calls for XML namespace http://www.w3c.org/1999/xhtml declared with prefix head but no taglibrary exists for that namespace.
• Warning: This page calls for XML namespace http://www.w3c.org/1999/xhtml declared with prefix meta but no taglibrary exists for that namespace.
Here is the error I made to cause that:
<html xmlns="http://www.w3c.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets">
Can you see it? I could not, but the error message kept driving me back to this line…here is how it is supposed to be:

<html xmlns=http://www.w3.org/1999/xhtml …

Now can you see it? I had to see a file that was working side by side to get it. I typed “w3c” instead of “w3”. I thought w3c was the name of the domain. Oh, well: live and learn.

Thursday, April 8, 2010

ADF/BC JDBC to retrieve structured data from packaged function

Got a request for code to show how to retrieve a collection of structured data (Oracle Type Objects) using JDBC in an ADF/BC scenario. The first parameter is the name of the Oracle Type that is the collection of your structured data type.

public Object callStoredFunctionReturningArrayOfRecords(String pfunctionReturnType, String stmt,Object[] bindVars) throws SQLException {
oracle.sql.STRUCT [] returnArray = null;
String [] recordArray = null;
Connection conn = getDBTransaction().createStatement(1).getConnection();
//Connection conn = getConnection();
// Now, declare a descriptor to associate the host array type with the
// array type in the database.


ArrayDescriptor arrayDescriptor=ArrayDescriptor.createDescriptor(pfunctionReturnType, conn);
// example:  StructDescriptor structDescriptor = StructDescriptor.createDescriptor("TEST_ARR_OF_REC_TYPE", conn);


// Create the ARRAY objects to associate the host array
// with the database array.


oracle.sql.ARRAY returnARRAY = new oracle.sql.ARRAY(arrayDescriptor,conn,returnArray);

OracleCallableStatement st = null;
try {
// 1. Create a JDBC CallabledStatement
st = (OracleCallableStatement)getDBTransaction().createCallableStatement(
"begin ? := " + stmt + ";end;", 0);


// 2. Register the first bind variable for the return value
st.registerOutParameter(1, OracleTypes.ARRAY, pfunctionReturnType);
if (bindVars != null) {
// 3. Loop over values for the bind variables passed in, if any
for (int z = 0; z < bindVars.length; z++) {
// 4. Set the value of user-supplied bind vars in the stmt
st.setObject(z + 2, bindVars[z]);
}
}
// 5. Set the value of user-supplied bind vars in the stmt
st.executeUpdate();
// Associate the returned arrays with the ARRAY objects.


returnARRAY = (oracle.sql.ARRAY)st.getARRAY(1);
// OracleResultSet mainRS = (OracleResultSet)st.getResultSet();
// ARRAY anotherARRAY = mainRS.getARRAY(1);


// Get the data back into the data arrays.
// NOTE: I got an NPE on the following line at one point...not sure why...
// I saw this error in opmn log; not sure if returnARRAY was null or
// if there are special rules about casting null into an array.
Object[] oarray = (Object[])returnARRAY.getArray();
// Object[] oarray = (Object[])anotherARRAY.getArray();


for (int i = 0; i < oarray.length; i++) {
oracle.sql.STRUCT struct = (oracle.sql.STRUCT)oarray[i];//new STRUCT(structDescriptor, conn, recordArray);
StructDescriptor structDescriptor = struct.getDescriptor();
ResultSetMetaData rsmd = structDescriptor.getMetaData();
Object [] attrs = struct.getAttributes();
if (rsmd != null && attrs != null && attrs[0] != null && attrs[1] != null) {
getLogger().fine("nested row [" + i + "]: " + rsmd.getColumnLabel(1) +
" " + attrs[0].toString() + " " + rsmd.getColumnLabel(2) +
" " + attrs[1].toString());
}
}
// 6. Return the value of the first bind variable
return oarray;
} catch (SQLException e) {
throw new JboException(e);
} finally {
if (st != null) {
try {
// 7. Close the statement
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

Thursday, March 25, 2010

dojo and JSF integration page unload solution when auto-saving

If you have integrated dojo and JSF in the way described here in the authors' first method of integration, the you probably ran into a problem of how to copy the values back to the hidden field -- if you are trying to implement an auto-save feature.  In other words, if you want to allow a user to not have to click a link/button in order to save their changes then you must find some other client event to tap into.  I believe the authors of that article I referred to used an example for their first method which simply used onclick of a button to save back a value.

For the purposes of my auto-save feature, I went with something much more piggy:  onkeyup for the dojo field itself.  So with every keystroke I copy back the value to the hidden field.  This fix was quick, and it really is not that slow.

For a more efficient implementation, you could program javascript to wait 5 seconds after every keystroke, then check to see if the value has changed, but I wonder if the simple copy would be more efficient than all that...probably!

ADF dialog framework simplified?

If you can overcome about any (needless) fear you might have about implementing a custom JSF NavigationHandler, you can actually open up your applications for many new possibilities.

The focus of this blog post is not how to create custom JSF framework extensions.  It is just this:  every time you use ADF's dialog framework (where you create an navigation outcome of the form "dialog:...", set useWindow in the af:commandButton/Link to true, partialSubmit to true) it is possible to create a bit of custom NavigationHandler code that simply launches a dialog window programatically instead of doing the normal navigation function. 

I tried this out because I was "forced to" due to a quirk of af:commandButton/Link which somehow has useWindow property ignored when inside of an af:iterator.  So I tried to think of the spot where it made the most sense to programmatically call up the dialog...duh!  The NavigationHandler of course.

Wednesday, March 17, 2010

JSF 2.0, Part I.b.

Initially the example I got working was just the downloaded code from the book.  Since then I also found out why my own assembed version (copied from the text of the book) did not work.

The short answer is:  I made some typos.

The longer answer is that:  I discovered that in web.xml, the JSF runtime is very sensitive to inaccuracies in the root node attributes.  I guess I thought they were not that important, but jsf runtime could not even run my application without correcting a typo in these attributes.  Before I corrected this typo I kept getting a "resource cannot be found" or something like that.

After that correction, I still had several more typos, but for each there was a sensible JSF error to help me find it, unlike the first.

Also used maven to compile the book's examples...first on-line...then on a different example...offline.  maven is such a boon the way it downloads what it needs the first time you run it, so that if you run it again on the same pom...or one with similar dependencies...it uses what it downloaded the last time to assemble things.  Very cool.

I should also mention in Glassfish that I deployed my exploded directory also, so now I can change xhtml files on the fly and just refresh the page and I see my page with the new changes in it when running the Glassfish JSF 2.0 app.

Thursday, March 11, 2010

Just got my first JSF 2.0 program working on Glass Fish

I just got my first JSF 2.0 program working on Glass Fish.  Maybe I can be ahead of the power curve on this one!  I think I heard Frank Nimphius say something (unofficially) hinting that they might have plans to use JSF 2.0 2011...in ADF Faces. 

So I am studying JavaServer Faces 2.0: the complete reference by Burns and Schalk on airplane rides back and forth to/from VA from/to CO.  Also when I am on the treadmill in VA.

Also Frank Nimphius and Lynn Munsinger's new book as well.

I have submitted abstracts for both of these topics to both JavaOne and Oracle Open World...so I am under the gun now.  Nothing new there.

AD4J provides surgical improvements

I have talked about AD4J before.  I revisited it after doing some hands-on labs with it at Oracle Open World.  I still think I could use a huge manual of discussions on what to do with all the information they provide.  Maybe that is a class Oracle provides...I don't know.

I do know this...in my basic state of not knowing much about AD4J, I was able to do a default install (there is more to do on this install if you are using SSL, but if not the install takes hardly any time at all), deploy the agent app to my target OC4J container, and do a 60-second monitor of my system which resulted in lots of data.

It also has, right there in front of you, a list of the top 5 or 10 most "expensive" things that were going on while it was monitoring.  During the monitoring session, I was randomly darting about in my app which has been slow.

It gave my pl/sql calls a relatively high rating.  I checked it out...I was making 28 pl/sql calls unnecessarily with each request!!  I corrected this, and now my slow app is quite a bit faster!!  Thank you AD4J!!  (AKA Jade).

Tuesday, March 2, 2010

RowSetIterator example

Because of its utility I would like to give an example of a piece of RowSetIterator code which will help avoid row currency issues, even if your void object instance is used by a UI component:

I use it as a method in VOImpl class to help me navigate to a particular row without changing the row currency of the RowSetIterator of the VO instance that is also connected to a UI and could thereby cause row currency issues. (BTW this was a best practice I took out of the ADF Developers 10g Guide; my guess is that it is still best practice...but it might not be.):


  private AnotherViewRowImpl findRowMatch (Number pMenuId) {
        if (!this.isExecuted()) {
            this.executeQuery();
        }
        boolean lFoundMatch = false;
        TbReviewerCommentAnotherViewRowImpl lRow = null;
        RowSetIterator lRSI = this.createRowSetIterator(null);
        while(lRSI.hasNext()) {
            lRow = (TbReviewerCommentAnotherViewRowImpl)lRSI.next();
            if (pMenuId != null && pMenuId.equals(lRow.getMenuItemId())) {
                lFoundMatch = true;
                break;
            }
        }
        lRSI.closeRowSetIterator();
        if (!lFoundMatch) {
            lRow = null;
        }
        return lRow;
    }

Thursday, February 18, 2010

Tuesday, February 16, 2010

Books I'm Reading

JavaServer Faces 2.0: the complete reference by Ed Burns, Chris Schalk

Also

Oracle Fusion Developer Guide by Frank Nimphius and Lynn Munsinger

MetaObjectManager scope (I'm listening now...)

I recommend that people working with ADF on JDev 10.1.3 read the MetaObjectManager entry at the following URL: http://blogs.oracle.com/Didier/bc4j/

...especially if you are deploying applications to OC4J and have overridden the DatabaseTransactionFactory... you might have done this if you wanted to do a post-commit or pre-commit type move, as was laid out in the Oracle ADF Developer's Guide for 4GL Developers version 10.1.3.0.

I first noticed when I added this override that, odd crap began to occur with my and others' deployed applications. Essentially they all began trying to use my SAME DatabaseTransactionFactory, which is not what I intended at all. The scope of this AM Module configuration property is something called MetaObjectManager. This means that every app deployed to that same OC4J instance will have the same setting...presuming I was the first one to deploy an app with this property defined in my bc4j.xcfg to that OC4J instance. This is not a smart way to identify a global setting...i.e., hidden in an app.

I am repeating this because, for me at any rate, the topic apparently bares repeating.

Tuesday, February 9, 2010

jdbc calling procedures and DBTransaction isDirty()

Did you know that even if you create a callableStatement from the DBTransaction in your ADF/BC layer and call a database stored procedure, function, package, etc...that; and if that stored program unit that you called does DML and dirty's the transaction, the DBTransaction's isDirty() method will not go to true (unless it was true before the call)?

I did not; but now I do. And now: so do you, dear reader.

Thursday, February 4, 2010

cafebabe?

I just noticed that the first four bytes of every Java class file (magic number) that designates that file as a class file spells "cafebabe" in hexadecimal.

Who says geeks don't have a sense of humor.

Wednesday, February 3, 2010

Error Handling and the Binding layer

Well...

Jan has beat on the subject of error handling, and I believe Frank Nimphius and Steve Muench have both thrown in their two cents. But I still had some nagging questions, so I pressed him; he did amazing things, and I think I responded pretty well. It was not a bad day all in all.

Check this JDev thread out if you have been wondering about using operation bindings versus calling the app module methods directly.

Op binding/error handling thread on Oracle JDev Technet forum

Wednesday, January 13, 2010

Tomahawk Popup loss of focus

A while back I realized that when using the tomahawk popup component (t:popup) in my ADF faces page that I was having a problem: whenever I had a field (like an af:inputText) inside the popped-up region along with something else, I would get some behaviour I did not want: as soon as my cursor left the field (but stayed within the popup region) focus would leave the input field. This made it awkward when I wanted to have a search field in the popup. But I found a simple solution: in the inputText's onblur property, put the following code: try{ this.focus(); } catch(e){}

What this does is keep it there rather than lose focus. I would really like to know what code is making this field lose focus. I did some searching, but it was very slow going for me, and I needed a quick fix.

Friday, January 8, 2010

JSFBlueprint auto-suggest field enhancements

What follows is an listing of the javascript that goes with the auto-suggest field you can find in JSF Blueprints.

The original brought up a basic list of suggestions which could be mouse selected. I added code to allow you to arrow down and up directly if you did not want to reach for your mouse. Also I added code (per a suggestion by Frank Nimphius, Oracle Corporation), which would reduce the number of ajax calls...very important for many use-cases of this component.

gReq = "";
var req;
var requests;
var target;

function getElementX(element){
var targetLeft = 0;
while (element) {
if (element.offsetParent) {
targetLeft += element.offsetLeft;
} else if (element.x) {
targetLeft += element.x;
}
element = element.offsetParent;
}
return targetLeft;
}


function getElementY(element){
var targetTop = 0;
while (element) {
if (element.offsetParent) {
targetTop += element.offsetTop;
} else if (element.y) {
targetTop += element.y;
}
element = element.offsetParent;
}
return targetTop;
}

function getWidth(element){
if (element.clientWidth && element.offsetWidth && element.clientWidth < element.offsetWidth) {
return element.clientWidth; /* some mozillas (like 1.4.1) return bogus clientWidth so ensure it's in range */
} else if (element.offsetWidth) {
return element.offsetWidth;
} else if (element.width) {
return element.width;
} else {
return 0;
}
}

function initRequest(url) {
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
}

// ********** INSERTED CODE ***********************
// The general idea here is that, the end user is only interested in the
// latest request. As of right now (9/20/2009), I have not seen anything
// to indicate otherwise. Assuming this is true, I am hoping that
// we never have a corresponding backlog of request on the database end.
if (typeof(gReq) != 'undefined' && typeof(gReq.readyState) != 'undefined'
&& typeof(req) != 'undefined' && typeof(req.readyState) != 'undefined') {
// alert("gReq.readyState is " + gReq.readyState + ", and req.readyState is " +
// req.readyState);
gReq.abort();
}
gReq = req;
//1/1/2010, mfons, The above was a brilliant idea, but it did nothing I can discern: still
// querying every keystroke. So now I
// will try waiting .5 seconds before registering the keystroke...if
// they are still typing I will keep waiting until I get something
// that has not changed...then query. See doCompletionDelayed()
// function below.
// ************ END OF INSERTED CODE **************
}

/**
* 12/31/09, mfons - originally doCompletion() called the ajax for each keyclick,
* but really we only want to only call the db if the user has not typed anything new
* in a while. Credit for this idea goes to Frank Nimphius, Oracle Corp.,
* who responded to my query on the technet.oracle.com jdeveloper forum.
* However, I figured the coding out myself.
**/
function doCompletionDelayed(targetName, menuName, method, onchoose, ondisplay, oldTargetValue) {
var target = document.getElementById(targetName);
if (target.value == oldTargetValue) {
var menu = document.getElementById(menuName);
menu.style.left = getElementX(target) + "px";
menu.style.top = getElementY(target) + target.offsetHeight + 2 + "px";
var width = getWidth(target);
if (width > 0) {
menu.style.width = width + "px";
}
var url = "faces/ajax-autocomplete?method=" + escape(method) + "&prefix=" + escape(target.value);
initRequest(url);

if (!requests) {
requests = new Object();
}
requests.menu = menu;
requests.onchoose = onchoose;
requests.ondisplay = ondisplay;
requests.targetName = targetName;

req.onreadystatechange = processRequest;
req.open("GET", url, true);
req.send(null);
}
}

function doCompletion(ev, targetName, menuName, method, onchoose, ondisplay) {
var menu = document.getElementById(menuName);
var evt = (typeof(ev.keyCode) == 'undefined') ? window.event : ev; //IE reports window.event not arg
//alert('ev.keyCode is '+ev.keyCode+' and window.event.keyCode is '+ window.event.keyCode);
/*
Try #1: I am trying to allow people to select items with the arrow keys as
well. Not just on a click of the anchor.
*/
/****************ADDED CODE BEGIN***********/
if (typeof(evt) != 'undefined') { // in firefox, focus event may leave evt undefined.
if (evt.keyCode == 38 /*up*/ || evt.keyCode == 40 /*down*/) {
try {
var childAnchors = menu.getElementsByTagName("a");
var targetAnchor = childAnchors[0];
// Look for highlighted item. If found
for (var i = 0; i < childAnchors.length; i++) {
if (childAnchors[i].className == "selectedPopupItem") {
if (evt.keyCode == 38 && i > 0) {
childAnchors[i].className = "popupItem";
targetAnchor = childAnchors[i - 1];
}
else if (evt.keyCode == 40 && i < childAnchors.length - 1) {
childAnchors[i].className = "popupItem";
targetAnchor = childAnchors[i + 1];
}
else {
targetAnchor = childAnchors[i];
}
break;
}
}
targetAnchor.className = "selectedPopupItem";
} catch (e) { alert("error");}
return;
}
else if (evt.keyCode == 13 /*Enter*/){
try{
var childAnchors = menu.getElementsByTagName("a");
for (var i = 0; i < childAnchors.length; i++) {
if (childAnchors[i].className == "selectedPopupItem") {
try{
childAnchors[i].click(); // It appears that firefox has no "click()" defined for anchors??
} catch(e) {
childAnchors[i].onclick();
}
stopCompletion(menuName);
return;
}
}
} catch(e) {}
}
else if (evt.keyCode == 27 /* Escape */ ) {
stopCompletion(menuName);
return;
}
}
/****************more added code...***************/
// 1/1/2010, mfons, added the following call in order to avoid launching an
// ajax-request (i.e., doing a database query) for each keystroke.
// This wait make sure that the target value does not change for some
// time period (500ms at the moment) before actually doing the query.
var target = document.getElementById(targetName);
//alert(target.value);
setTimeout("doCompletionDelayed('" + targetName + "', " +
"'" + menuName + "', '" + method + "', '" + onchoose + "', " +
"'" + ondisplay + "', '" + target.value + "')", 500);
/****************ADDED CODE END***************/

}

function chooseItem(targetName, item) {
if (!requests.onchoose || requests.onchoose == "null") {
var target = document.getElementById(targetName);
target.value = item;
} else {
requests.onchoose(item);
}
}

function stopCompletion(menuName) {
var menu = document.getElementById(menuName);
if (menu != null) {
clearItems(menu);
menu.style.visibility = "hidden";
}
}

/* Stop completion shortly.
This is necessary because I want to stop completion from the blur
(focus loss event) of the completion text field, but that will also
happen, right BEFORE a link click in the completion dialog is processed.
If this is done synchronously, the link is deleted before it is processed
by stop completion. Therefore, I use the delayed variety which schedules
stop completion instead such that the link is processed first.
*/
function stopCompletionDelayed(menuName) {
/* Would like to shorten timeout but this seems to trip up Safari */
setTimeout("stopCompletion('" + menuName + "')", 400);
}

function processRequest() {
if (req.readyState == 4) {
if (req.status == 200) {
parseMessages(requests.menu);
} else if (req.status == 204){
clearItems(requests.menu);
}
}
}

function parseMessages(menu) {
clearItems(menu);
menu.style.visibility = "visible";
//alert(req.responseText);
var lItemsRE = new RegExp("<item>(.*?)</item>", "g");
var lItems = req.responseText.match(lItemsRE);
for (var i = 0; i < lItems.length; i++) {
//alert("item "+ i+ " is " + lItems[i].replace(lItemsRE, "$1"));
appendItem(menu, lItems[i].replace(lItemsRE, "$1"));
}

// var items = req.responseXML.getElementsByTagName("items")[0];
// for (loop = 0; loop < items.childNodes.length; loop++) {
//
// var item = items.childNodes[loop];
//alert('item is '+ item); // why is item null now? xml is coming back OK, it appears.
// appendItem(menu, item.childNodes[0].nodeValue);
// }
}

function clearItems(menu) {
if (menu) {
for (loop = menu.childNodes.length -1; loop >= 0 ; loop--) {
menu.removeChild(menu.childNodes[loop]);
}
}
}

function appendItem(menu, name) {
var item = document.createElement("div");
menu.appendChild(item);
var linkElement = document.createElement("a");
linkElement.className = "popupItem";
linkElement.href = "#";
linkElement.onclick = function() {
chooseItem(requests.targetName, name);
stopCompletion();
return false;
}
var displayName = name;
if (requests.ondisplay && requests.ondisplay != "null") {
displayName = requests.ondisplay(name);
}
linkElement.appendChild(document.createTextNode(displayName));
item.appendChild(linkElement);
}

This code has been tested against IE 7 and 8 and also the latest version of FF.

Please let me know if this is helpful.