Thursday, January 29, 2009

h:inputTextarea rows attribute does not work?

For the sun JSF 1.2 Sun implementation, has anybody noticed before that h:inputTextarea's rows attribute has no affect on the height of the textarea?

JSF 1.2 MyFaces implementation does fine though... very odd. I tried googling this issue and did not find it readily advertised. Maybe now it will be because of this blog entry.

Saturday, January 17, 2009

extra field!!!

I was doing a custom component in JSF, and I kept getting an extra input field with the clientId as the id attribute, and I did not know why. I searched the web and did not find anybody who had ever encountered this. Since it always came last in the component I could not even figure out a way to hide the thing because any JavaScript I put in the component came prior to the existance of the field. I do not do anything in my encodeBegin() that asks for this.

Then I started wondering if extending the UIInput component required something that I was not doing; either that I figured or it was putting this darn extra field.

After studying other custom components' code, it finally occurred to me that if you extend a custom component (like UIInput) you have to be mindful of what methods that component implements, and what it does in those implemented methods. Then you have to decide if you still want that particular part of the component you are extending.

In my case, UIInput used encodeEnd() method to actually produce its field, so I just overrode encodeEnd() and made it do nothing. Then I started to wonder why I even was extending UIInput instead of UIComponent or something...

I guess that is another lesson...

postback

I was doing some research on JSF custom components. I saw that one way to do AJAX in your custom components is to program the code needed to get your data right in your decode() in your component or in your renderer.

The problem I was having was that when I told the AJAX code to do the POST it was not acting in JSF request lifecycle like a postback had occurred. It was only running the first and last phases of this lifecycle...like it does when you first visit a page.

The solution? Apparently JSF determines if this page was a postback by looking at all the input fields (or textarea, etc), and seeing if they have a name attribute. If they do then they need to have an entry in the post "search area" that you send as a string to the AJAX "send" command. So that includes state saving field, and any other fields that are displayed or hidden that have a name...I think.

Anyway doing this got my decode() method to be called, and the JSF lifecycle to call all the phases.

Thursday, January 8, 2009

Making Eclipse (Ganymede) Create Your Custom JSF jar file

Apparently I am an IDE man. I know it is possible to remember the flags to run the jar command so that you can package up a set of directories, but I would rather let the IDE do the work.

But I am having a bit of difficulty making Eclipse do what I want.
I decided to package up one of my custom components into a jar file, so that someone (like me) could use the component by dropping the jar into their application’s WEB-INF/lib directory.

So I moved everything my components needed to a different project, and made the project path have every library it needed to build the java files. This worked fine.

When you want to create a jar file for your custom JSF component, your jar is pretty simple. The root directory of the jar contains package trees with class files on the leaves of these trees, and resource files like message bundles or anything else you would put in the src directory to have it on the class path.

In Eclipse-ese, creating a Jar is called “export…” So if you export to a Jar by right-clicking your project, selecting Export… from the context menu, and following the instruction in the Jar export wizard when all is said and done your classes will be in the right place if you select the src directory and the build directory that eclipse manages for you. But the META-INF directory that eclipse builds for you as a sibling to the WEB-INF file cannot stay where it is if your Jar is going to have the META-INF file in the right place. The right place for the META-INF file in your jar is in the root directory of the Jar. In the jar should be your faces-config.xml and your whatever.tld file where you describe your tags.

So my solution (which worked) was to move the META-INF from being a child of the Web Content directory, to being a sibling of the Web Content directory. Then you can simply check the box next to the META-INF directory, and it is moved to the right place.

Sunday, January 4, 2009

Thoughts on JSF 1.2

Here are some miscellaneous thoughts on JSF 1.2.

The differences between JSF 1.2 and JSF 1.1 are not huge. Essentially the main differences are that you need to use objects called ValueExpressions instead of ValueBindings. Similarly you need to use MethodExpressions instead of MethodBindings. Also you will be using JSP 2.1 instead of 2.0. Also you need to use W3C XML Schema designations for your config files instead of DTD’s. Also I think you need to use a container that can handle Java EE stuff instead of J2EE stuff…but I am not sure about that. Also some classes have been deprecated in 1.2 that were in use in 1.1; for example, in the Tag Handler classes you would define for a custom component, you will not be inheriting from the UIComponentELTag instead of UIComponentTag.

You might take a look at (Vogel, L. (n.d.). JavaServer Faces 1.2 development with Eclipse WTP JSF Tooling - Tutorial. Retrieved from http://www.vogella.de/articles/JavaServerFaces/article.html) which shows how to get a project off the ground using JSF 1.2. I used Tomcat for my experiments. I would have liked to have also gotten it working with JDeveloper 11g since it uses a Java EE container. However I could not see an Enterprise Manager for the standalone 11g OC4J, and I did not want to learn how to use admin.jar, since that is how I supposed I would have to deploy to OC4J without EM working. Maybe now that 11g OC4J has gone into production now (I was still using a technical preview install) the EM will be in place…or maybe they are calling EM something else now…
Also Eclipse does not know how to talk to OC4J 11g yet. However it does know how to talk to Tomcat 6.0, which is compliant with JSF 1.2 and JSP 2.1 and Java EE and all that stuff. So I finally got Eclipse talking to Tomcat with all the right libraries. I put all the libraries needed in the build path and in the WEB-INF\lib path as well.

I also used Apache MyFaces JSF implementation. I think Apache Mojarra would have worked just as well, but again Eclipse may not know how to talk to GlassFish. I do not think it does. However if you want to use Apache Mojarra against other Java EE containers you are supposed to be able to do that. However, it appears to me that in order to actually deploy to any web server there is always a set libraries you need to include in order to be able to do this. It is not clear to me quite yet how to lay my hands always on this set of libraries, although I am thinking: probably the website of the app server in question…in the chapter on JSF perhaps?? Eclipse, if it knows how to deal with a server or a version of that server, will line up these magical libraries for the server if you specify what server you are using for a particular project. So if you are creating a new “Dynamic Web Project” of the JSF type, you can specify what server you want to deploy to (assuming you have set up Eclipse’s connection to your installation of whatever server you want to deploy to), and then those server-specific libraries will be lined up for you.

It looks like JSF 2.0 is in the works (ai yi yi!), so y’all better get it (and keep it) in gear!! J

Thursday, January 1, 2009

Good site

Got questions about JSF or JSP or how they fit together?

The following tutorial may just answer some questions for you!

http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html

Hah! I found it.

I am working my way through Schalk and Burns's JSF: The Complete Reference.

I skipped ahead to Chapter 10 because I promised my groupies (hah!) that I would put some juicy nuggets about custom JSF component definition in my paper for RMOUG (Rocky Mountain Oracle Users Group) in a month and a half.

So I had to study more about custom component definition.

As I worked through the chapters on that subject in this book, I got to one of the examples, and it just did not work. As I debugged the code, I saw that the component's property called listener (a MethodBinding) was being set in the component's Tag Handler class, in its setProperties() method.

Then, the component (on a different request) tried to do something with this listener value that was set...but lo! The value of this property was null.

That let me to ask a question that I have asked before, but had grown fuzzy on the answer. The question was...what scope are components at? Request? Session? Does scope even apply to this, since they are not managed beans?

The partial answer is that components by default span requests. But if you start adding extra properties to the component then you had better override a couple of properties, if your component or one of its ancestors implemented the StateHolder interface at some point. If you are extending UIInput for example, this already has implemented this.

So what are these properties you need to override? saveState() and restoreState(). In the following example, the "extra" property we are adding is called listener and is a MethodBinding object:
@Override
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
super.restoreState(context, values[0]);
listener = (MethodBinding) values[1];
}


@Override
public Object saveState(FacesContext context) {
Object values[] = new Object[2];
values[0] = super.saveState(context);
values[1] = listener;
return (values);
}

After adding these methods, the books example worked fine.

The name of the example component was HtmlHelloInputMB if anybody else is working through that same book.

I have informed the primary author through the email given on the books website, which has all the sample code for the book by the way: http://www.jsfcompref.com/