This site promotes and supports the development and deployment of JSF, Oracle ADF applications, and other web development topics. If you have interesting facts to share about any of these or any related technologies, please feel free to post a comment.
I have been using the iReport IDE for Jasper Reports template creation. One strange thing about this report of iReport: I do not see a way to see a compilation or a runtime error/message log. If an error occurs, by default the report simply does not run.
A friend of mine finally figured out a way to get some messaging out by using log4j: here was the note he sent to me:
I found a way to get iReport to log. If you start iReport from the .bat file supplied in the bin directory, you can add log4j configuration to JVM command; i.e., in the bin/startup.bat file, add the following to the java command: -Dlog4j.configuration=file:C:\bea\domains\oppenDomain\config-oppen\log4j.xml
I have recently started to study polymorphism more. My goal is to continue to improve my ability to think in Java. For example, with polymorphism if you have a cascading series of if statements which is meant to branch out like a case/switch statement and call the different methods that basically do the same type of things, you probably should refactor it to take advantage of polymorphism. I read the following article and it helped me create a solution to such a refactoring problem which was fresh and useful: http://www.javaworld.com/javaworld/javatips/jw-javatip30.html
I hope you find this example useful also. The syntax of this person's examples is not perfect, but the concepts are there, and there are enough parts of the example to put together some refactoring of your own as I described above.
I mostly wanted to check in because I am job hunting now and I want to keep things flowing.
I have been starting to work on the RMOUG site redeaux ;-) (with members-only site).
As I am looking for jobs I keep getting hit with jobs which want JSON, DWR, Prototype, and Dojo. I better get on the ball with these great tools.
At any rate, I worked with iBATIS caching. It is working very well. iBATIS seems so stable...I am sure there are bad things about it, but I cannot think of too many. :-)
I was reading about the differences between binding a UI JSP component to a UIComponent property in your backing bean using the binding property on the JSP component, and value-binding your JSP component to a model-level bean property in some class somewhere.
Well I figured out a couple of things: 1. One difference: if you believe in MVC you should keep your view-level stuff sepparate from your model level stuff. So using binding is better than value binding if you have the option. 2. The binding connection gets the values into the backing bean properties in phase two of the JSF lifecycle, where as it is the model update phase (phase 4 or 5) before you get it updated if you have a value binding connection. At least I think so... 3. From what I read it sounds like if the JSF container is in the process of rendering a UIComponent, that is no guarentee that any other UIComponent in that page's view has been put in the view (component tree) or rendered! This is for JSF 1.1. In JSF 1.2 it sounds like they have made it so that if rendering is occurring you can guarentee that all the view has been built already! I wonder if in JSF 1.1 a render of a particular UIComponent alway implies that the component has been inserted into the tree. It seems as if you would have to construct a tree in a way that would allow later traversal. And not just random nodes...although I do remember algorithms for BTree insertion that allowed you to insert random nodes and have them end up in a reasonable order...so who knows.
After today it looks as if choosing to use BigDecimal (for whatever reason) may have a challenge with regard to having both automated conversion and using a pattern to format your numbers.
So it sounds like it is time create a custom converter which extends the BigDecimal converter from JSF, and putting numeric patterns on top of it.
I will let you know how it goes...
...OK: it went well: I discovered that the creators of the application I am working on had already created such a converter. So I just use f:converter component, and reference the id of this component that was created; since the custom converters must be registered in faces-config.xml, you can just get the id from there if you are utilizing a pre-existing custom converter.
It turns out this converter hard-coded the format string. So I just loaded the resource bundle with the format string in it and use that instead. That way there is only once source in the application for the desired format string.
I just started reading the JSF Complete Reference by Schalk and Burns. I really did not want to do the examples using Tomcat since I am having a love affair with oc4j ;-) I also wanted to use JDeveloper. Oddly enough the authors really did not give much of a clue as to how to do plain ol' JSF within JDeveloper. The book seems to really want you to use the ADF stuff.
That's fine, but I am trying to learn the JSF stuff now that I have grown up on ADF stuff. I want to see what I missed.
So I now know what jar's I really need to make OC4J run on JDev and to be able to do JSF: 1. The normal stuff: commons-beanutils.jar, commons-digester.jar, commons-collections.jar, commons-logging.jar, commons-validator.jar, jsf-impl.jar, jsf-api.jar, jstl.jar, standard.jar, 2. The oc4j and servlet stuff: The rest of what you need is wrapped in something called JSP Runtime. This has the following jars: ojsp.jar, ojsputil.jar, oc4j.jar, oc4j-internal.jar, servlet.jar, and ojc.jar.
If you are working through this same book, the rest is in the book.
The direction of this blog is expanding a bit, since what I am doing is changing a bit. I am currently engaged in a JSF/iBatis/Spring project. So my focus has expanded. I am looking forward to learning new things; and to seeing more about what JSF is about.
Next week I will be starting development on some new tools: iBATIS, Spring, Jasper Reports, and (of course) JSF.
Should be a blast. I am already trying to get a grip on all this stuff. I think Spring may be my hardest challange; I am sure I will get a grip on it eventually.
I am looking forward to this position so I can round out my ADF-centric existence. ;-)
There is a bug in running some ADF programs in OAS 10.1.3.1 in the default installation. The fix involves giving the JVM a parameter of -XX:CompileCommand=exclude,oracle/sql/NUMBER,toBytes
But when I tried this in the opmn.xml, the hotspot compiler did not seem to recognize this exclude command. Very odd. There are alternate fixes to this problem however...like upgrading your JDK.
Since the end of my last engagement I am looking for work, studying to fill in things I need to learn to be more marketable, finishing up odds and ends on the last engagement.
Here are some noteworthy items: 1. If you are using Oracle AS and SSO with an ADF BC/JSF app (10g AS, 10.1.3.3.0 JDev...at least) there is a critical thing you need to know: a. Setting CacheNegotiatedDocs in Apache will cache pages b. change mod_osso.conf file to "OssoSendCacheHeaders off" In my last engagement we had done a. but not b. So none of the caching was working and the application was REALLY SLLLLLLOOOOOOWWWW. I thought I was going to lose my mind. It actually took my supervisor looking at AD4J output (see prior post in this blog) to get the idea that caching was not occuring. He saw the same files getting accessed over and over and over again! This is huge! It will make the difference between having a pleasant positive relationship with my former employer and a really crappy one. 2. In one of my interviews, the interviewer asked me about JSR 227. I could not answer him, but it seems like this at the very least encompasses the binding PageDef file, the need for DataControls (I think) and a bunch of other things. So while reading http://web1.jcp.org/en/jsr/detail?id=227 Supprisingly there are Navigation aspects to this JSR also...not just connections to data controls and methods in the model/business component/business service layer.
Oracle Application Diagnostics for Java is a helpful tool. It allows you to take a look at what your java application is doing and which parts of your program are using the most resources. I am just getting started on this tool, but it looks promising.
Here are some basic instructions to get you started...
NOTE: dumping the heap on my machine caused the machine to REBOOT. You might want to consider carefully before trying this on any important machine (like production). I have a question out to the Jdev forum on how to avoid this. I have a feeling this functionality would allow one a whole bunch more diagnostics to look at.
OK, the basic idea is…1. get the zip file from http://www.oracle.com/technology/software/products/oem/htdocs/jade.html 2. unzip it. 3. there is an install file in there to run called jam.msi. Put that on your machine and doubleclick. 4. Install the jade program wherever you want to; I think you might need to change the http port to something other than 80 though if you already have port 80 defined on your computer (you will be given the opportunity to do this during the installation). This installation will install a “Jam Console” service and a “Jam DB” service and make them turn on by default. 5. Once it is installed, you can start up a browser and go to http://ad4jhost:portyoujustchose/ 6. The default username and password is admin/welcome (note that the time out by default for the AD4J product is extremely small. If you are ever presented again with the login screen, just log in and start whatever you were going to do over.) 7. click the setup tab 8. click download agent on the menu bar 9. Click the download icon for the Java Agent EAR file for deployment on remote machine, or use the local machine if you host is localhost. Download that ear file. 10. Deploy this ear to the oc4j where you are running the application you want to diagnose. Now you should be able to run a trace.
To run a trace: 1. log in as above to ad4j console 2. click the java tab 3. click the show JVMs on the menu-bar. there should be a jvm listed. Under Threads column there should be an Active link. Click the Active link 4. now click the Trace Active Threads menu bar 5. Get ready to run your test in the aplication you want to diagnose.
6. Set Poll Duration field on AD4J Tracing All Active Threads screen to however you want to run the trace for. By default this value is set to 10 seconds. That is not enough time, BTW, to do much of anything. 7. Type in a description so you can identify the trace. 8. Click Start….immediately start your test in your application. 9. The Tracing All Active Threads screen will show you (usually) when it is done running…when the time is up. Also at that point there is a link to go look at the results of the trace. If you do not see this you can also press the Trace tab, and click a link on the trace you want to look at.
Here's another difference I notice about the af:form vs h:form. With the h:form it seems components in a form get id's like 'formid:componentid' when you do view source. However, with an af:form your component id is just 'componentid'. I am not 100% sure about this, but I think this is the case.
I know the title of this blog entry seems a little weird, but after the odd experience I just had with ADF, all I could say was "wow".
The sequence is long and drawn out, but I will try to recount the steps: 1. I was experiencing what I think is a bug with dialogs and the partial page rendering on a return from a dialog interacting with af:selectOneChoice within an af:table. After you return from the dialog, all your drop-down lists get cleared of their current value for some reason. 2. I took this as a bug and decided to try to work around it. 3. I discovered that even though the value of the list would clear, the underlying value the list was based on was still there. This explains why other components (like af:inputText, af:outputText, etc) show their values just fine after returning back from a dialog and doing a PPR. 4. So I thought, why not use javascript to reset the selected value of the list? 5. Then I found out af:selectOneChoice manifests its options tag with sequential values even if you give it other values programatically by basing the selectOneList on a list of SelectItem's...with non-sequential values. In otherwords if you look at "View Source" (in IE parlance) at a select list generated by an af:selectOneChoice, you will always see the value attribute in the option tag say 1, 2, 3, 4, 5, ... regardless what you may have done in your backing bean. So if you created an ArrayList of a single SelectItem(new Integer(5), "five"), the HTML would come out ...at least: that was my experience. I am reasonably sure that is what happens. I would have been really pleased if that is *not* what happens...so I worked it for a while. 6. I then discovered the plain-ol' JSF component f:selectOneMenu (the counterpart to af:selectOneChoice in the ADF Faces world). This produces HTML, the value of which matches the SelectItem you create to back it up...so... 7. You can reset the values with JavaScript... 8. That was almost the end of my ordeal, except that I also found an old trick I used on tables from Steve Muench does not work in this scenario. Have you ever used something like the following as a value binding in a list's value property?
When you pass a value in with the square brackets, you can override the "get" method of the HashMap (anonymously, I think it's called) so that, although your presentation component (i.e., the drop-down list) is saying that its f:selectItems sub-component has a HashMap to back it up, it actually has whatever the overridden "get" method returns to back it up.
9. Only trouble is...f:selectOneMenu is not that smart. It thinks this is a HashMap backing this f:selectItems up. af:selectOneChoice does not have a problem with this, but we can't use that component here, right?
10. So we use an approach that creates some List attributes in the backing bean to make accessor functions for.
At any rate, this gives us our list. And when you return from a dialog and the value is reset you can write javascript to reset the selected value to a hidden field which contains the value it should be set to, and which uses af:hiddenField with a value of #{row.whateverFKyouneed}
I had an interesting problem which you might be interested in knowing about.
The application I am building currently has a page where you open a dialog and can edit a particular child record. This update screen allows the user to change (among other things) the FK to the parent view object which is on the page the dialog returns to.
There is a little pencil icon. This opens the dialog. Save in the dialog window closes the window and saves the changes.
One of the change they can make as I indicated is to the parent data, which is the designation which parent the child record has.
The interesting thing here is that because I am using drop-down lists, I do not have direct access to the FK value when I need it. Specifically if they change the FK value I do not have the new value. If I use value change listener the new value there just shows the integer index into an array. The way to get at the value is to let a cycle go by and catch it once it has been set with a binding for the iterator. But I don't want to (or can't) wait that long. I need that new value now!
When I change the FK value, because of the way ADF automates coordination between parent/child VO instances, the new record is quickly lost! If I look at the current record in that VO instance fairly quickly after the change has been made, this binding layer says my child/FK record no longer exists under that parent/PK. But I really need that new value.
So where is it? Where can I go look? I know it is not totally lost because the child ends up in another parent; but right when I need it I can not find it.
So where to look: in the entity cache. How do we do that?
In the VO Impl code for the child I have code that does the following:
the first line gets the entity definition for the view object. I get the definition for the first entity associated with the VO because I know the VO only has one entity associated with it. Next I get the app module (again in my app there is only one), and use that to get the particular entity I am looking for. So I use findByPrimaryKey where I plug in the EntityDef and the Key for the particular VO row I am looking for. Once I have found it I get the attribute I am interested in. ParentFKId, in this case, is the FK which points back to the master record. So now I have my new value!
This short commentary is for a bug that has bitten me twice in recent ADF projects.
In the Oracle Application Server 10g, in the latest patch level, the default JVM that is used is 1.5.0_06-b05).
If you are getting something in your logs that looks like a compiler error, you might upgrade your JVM to 1.5.0_10 or above (staying with 1.5, I suppose). Oracle is aware that this gets rid of this problem. But since there is no AS 11g yet, my ADF development is still 10g.
On two different recent projects I have had problems. Both times in the logs it looks something like "...Current CompilerTask: opto: 602 oracle.sql.NUMBER.toBytes(Ljava/lang/String;I)[B (1034 bytes)..." The java VM would give an EXCEPTION_ACCESS_VIOLATION and restart itself which ended whatever we were doing. There were also indications that something called "PSYoungGen ...fromSpace" was all used up. The sysadmin here tried various adjustments to memory usage but none of them really helped much.
It is amazing. The more I work with the ADF and the surrounding technologies, the easier many things are becoming. I think it is wisdom to keep this in mind. For example, I wanted to have a master bullet list and a child af:table. I could not see a way to do it without putting the parent list in an af:table as well...so that is what I put it in.
A month later, I took another run at it; the problem I was having before is that to create the bulleted list I was using an af:forEach. There is no validation on each row like there is with an af:table on a submit. So if you want to set the current record, you cannot simply create a setCurrentRowWithKeyValue and pass it #{row.pkid} like you could with an af:table.
When taking another run at it, I first though of a complex thing I could do with binding, which might or might not have worked. I thought of an easier way of dealing with this problem in the meantime though: create an af:hiddenField with a ValueChangeListener that sets the current row. Then all you have to do is define the af:commandLinks you have in your bulleted list to have onclick defined to set the value of this hidden field to the value in the af:forEach. Something like the following:
I have had a great engagement over the last three months. I have resolved some questions about ADF I have had been looking for for a long time. A couple of items that come to mind is that: yes, you can do drag-and-drop in 10.1.3.3.0; it's just not as easy as it is in ver. 11g of JDev.
Also just today I resolved a problem I have had with JDev 10.1.3.3.0 and refreshing the screen in combination with partial page rendering. You can read more about this at http://forums.oracle.com/forums/thread.jspa?threadID=428798 . Towit, I have added links from the Oracle JDev Forum that have been helpful to me. Hope they help you.
Another topic (in my JDev forum links section, also, entitled "autoSubmit and mouse clicks") is very important to anybody who is trying to make 10.1.3.3.0 not have so many button clicks to get things done.
There is even an entry in there as I worked with Frank Nimphius and Oracle Tech Support to work out a bug in JDev.
I recommend you go though these links. They may be informative to you if you are developing in ADF.