JSF 2 Annotations with Websphere 7 (JEE5, JAVA 1.6) - jsf

I'm currently writing a simple JSF 2 app for WAS 7. When I define the bean via the faces-config.xml, everything works great
<managed-bean>
<managed-bean-name>personBean</managed-bean-name>
<managed-bean-class>com.prototype.beans.PersonBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
When I try to use the annotations below instead, the app failes.
package com.prototype.beans;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean(name="personBean")
#RequestScoped
public class PersonBean {
....
}
I've set the WAS classloader to Parent Last, and verified in the logs that Mojarra 2.x is loading.
[5/17/10 10:46:59:399 CDT] 00000009 config I Initializing Mojarra 2.0.2 (FCS b10) for context '/JSFPrototype'
However, when I try to use the app (which had worked with XML based config) I see the following
[5/17/10 10:48:08:491 CDT] 00000016 lifecycle W /pages/inputname.jsp(16,7) '#{personBean.personName}' Target Unreachable, identifier 'personBean' resolved to null
org.apache.jasper.el.JspPropertyNotFoundException: /pages/inputname.jsp(16,7) '#{personBean.personName}' Target Unreachable, identifier 'personBean' resolved to null
Anyone know whats going wrong?

Looks like I may have resolved my own issue (again). The problem looks like it was caused by an improper schema location/config on the faces config. Here's what I am using now, and it seems to work.
<?xml version="1.0"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
</faces-config>

the bean name in should be the name of your bean class
so change beanName in faces-config.xml as
<managed-bean-name>PersonBean</managed-bean-name>

Related

Can't find beans annotated with #ManagedBean

While upgrading the JSF version of an old web application from MyFaces 1.1 to MyFaces 2.2.12, I am trying to replace the <managed-bean> entries in my faces-config.xml file with #ManagedBean annotations directly in the bean classes. I am using Migrating from JSF 1.2 to JSF 2.0 as a general guide for the migration.
For example, I am replacing something like
<managed-bean>
<managed-bean-name>MyBean</managed-bean-name>
<managed-bean-class>some.package.MyBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
with
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class MyBean {
According to Are there going to be two instances for a bean if I write #managed bean annotation and define same in faces-config.xml, annotations are overwritten by corresponding entries in the faces-config.xml, so I deleted the <managed-bean> element in my faces-config.xml.
Since the project consists of several maven modules which are packed as jars individually before being deployed as a combined war file, I also tried to follow the advice from How does JSF find beans annotated with #ManagedBean? and added another META-INF folder containing a faces-config.xml to the submodule containing the bean, at the following location (respecting the accepted answer in How to reference JSF managed beans which are provided in a JAR file?):
MainProject
| SubModule
| |src
| | main
| | resources
| | META-INF
| | faces-config.xml
with the following content:
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
</faces-config>
Sadly, I still get the following error when trying to open the page that uses this specific bean:
javax.el.PropertyNotFoundException: Target Unreachable, identifier 'MyBean' resolved to null
Since I am using JSF for bean management, I followed the JSF part of the instructions in Identifying and solving javax.el.PropertyNotFoundException: Target Unreachable but even after verifying the individual points mentioned there, I still get the same error.
I am using Tomcat 7 as servlet container, which - according to http://tomcat.apache.org/whichversion.html - supports servlet specification up to version 3.0, which, in turn, should suffice for JSF 2.2, which - if I understand correctly - requires at least servlet spec 2.5, according to http://myfaces.apache.org/core22/.
I have already searched quite a lot for the cause of the problem (as mentioned, I tried several of the SO articles mentioned above), but still can't solve the problem. I would be very grateful for any help!
The answer can be found in the #ManagedBean Javadoc:
The value of the ManagedBean.name attribute is taken to be the managed-bean-name. If the value of the name attribute is unspecified or is the empty String, the managed-bean-name is derived from taking the unqualified class name portion of the fully qualified class name and converting the first character to lower case. For example, if the ManagedBean annotation is on a class with the fully qualified class name com.foo.Bean, and there is no name attribute on the annotation, the managed-bean-name is taken to be bean. The fully qualified class name of the class to which this annotation is attached is taken to be the managed-bean-class.
So your bean is named myBean and not MyBean. If you want it to be MyBean, provide the name with the annotation: #ManagedBean(name = "MyBean").

Setting view scope on JSF 2.2

On JSF 2.2 we don't have the option to set the View Scope on faces-config.xml .
So how should it be done? Is the view scope missing on JSF 2.2 ?
Thank you!
Use #ViewScoped annotation on managed bean:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class AViewScopedBean {
//managed bean contents...
}
If you don't like the annotations configuration (really odd), you can just set the view scope on faces-config.xml
<managed-bean>
<managed-bean-name>aViewScopedBean<managed-bean-name>
<managed-bean-class>some.package.AViewScopedBean</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>
Note that this only works on JSF 2. Check that your faces-config file is configured to handle JSF 2.x version:
<!-- relevant part of faces-config.xml file for this Q/A -->
<faces-config ... version="2.1">
Note: Warning make sure its Serializable
The error message is pretty straightforward:
java.io.NotSerializableException: com.bean.StatusBean2
This means that your com.bean.StatusBean2 must also implement the Serializable interface. From java.io.Serializable documentation:
When traversing a graph, an object may be encountered that does not support the Serializable interface. In this case the NotSerializableException will be thrown and will identify the class of the non-serializable object. (this is the error you're getting)
You can learn more about Java Serialization here: Java Serialization
From your question: is it necessary to implement serializable?, BalusC already posted a good answer/explanation: JSF backing bean should be serializable?
Thanks for #Luiggi Mendoza

How to mix annotations with faces-config.xml

Using JBoss 6.0.0.Final, Richfaces 3.3.3.Final, MyFaces 2.0.6, facelets 1.1.15.B1 (a limitation of RF 3).
I'm on a legacy project which contains hundreds of beans defined in faces-config.xml. I'd like to keep those defined in faces-config.xml but use annotations for new beans. However, when I've tried this I've not had success. The beans defined by annotation i.e.
#ManagedBean
#ViewScoped
public class Foobar implements Serializable {
// ...
}
The bean is not accessible from my JSF page. I believe I've specified the 2.0 version in my faces-config.xml by using the proper header.
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
Is there anything else I need to do in the faces-config.xml to allow annotations to also be used?
Annotated beans will fail in the following cases:
/WEB-INF/faces-config.xml is not declared to conform to JSF 2.0.
#ManagedBean is of javax.annotation package instead of javax.faces.bean.
Bean class is not been compiled/built into WAR's /WEB-INF/classes.
Bean is packaged in a JAR file which is missing /META-INF/faces-config.xml.
A wrong managed bean name is being used in EL, it should be the bean class name with 1st character lower cased according Javabeans spec. So in your particular example, #{fooBar} should work, but #{FooBar} won't.
Webapp is actually using JSF 1.x libs (you can read JSF version in server startup log).

simple JSF commandButton not hitting the action

I have the simplest little JSF example (JSF2 with GlassFish) and I can't figure out why the command button is not hitting the action method. This is what I have ... when I click the button, nothing happens.
What am I doing wrong?
testForm.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:form>
<h:messages />
<p/>
<h:inputText />
<p/>
<h:commandButton value="test1" action="#{testController.action1}" />
</h:form>
</html>
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<managed-bean>
<managed-bean-name>testController</managed-bean-name>
<managed-bean-class>com.app.controller.TestController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
TestController.java
package com.app.controller;
public class TestController {
public String action1() {
return "testPage2";
}
}
Eureka! After rebuilding the Eclipse project from scratch I realize what I did wrong. Apache MyFaces is in the project path and the app is being deployed on GlassFish which has it's own JSF implementation. The two JSF implementations don't want to play nicely together.
What a pain. And, you know, I made this exact same mistake once before. Eclipse should warn you about this or there should be some error reported in the GlassFish log or the h:messages tag.
1)For JSF2.0, Its not required to configure managed bean in Facesconfig.xml.
2)can use #managedban annotation.
package com.app.controller;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "testController")
#SessionScoped
public class TestController {
public String action1() {
return "testPage2";
}
/** Constructor, getters and setters*/
}

JSF config-annotations not processed

I am running a JSF 2 application on JBoss AS 6.
Somehow the Annotations, like #FacesComponent or #FacesValidator, etc are not processed by the container. If I annotate a Bean with #FacesValidator("fooValidator") and try to set the validatorId on some component to "fooValidator" I get:
Caused by: javax.faces.FacesException: Expression Error: Named Object: fooValidator not found.
at com.sun.faces.application.ApplicationImpl.createValidator(ApplicationImpl.java:1530) [:2.0.3-]
...
However, If I add
<validator>
<validator-id>fooValidator</validator-id>
<validator-class>foo.MyClass</validator-class>
</validator>
To my faces-config.xml everything works as expected. Same goes for components and converters.
Any idea why the annotations are not processed? I am out of ideas...
Thanks in advance...
Got it. It is very similar to this one: Why doesn't JSF 2.0 RI (Mojarra) scan my class' annotations?
My project uses a skinny war, so the lib folder in the war is empty/nonexistent. And to make it worse, the Controller Beans are not located in the war but in a seperate jar. As this jar is not in the war, the jsf annotation processor does not scan it.
I guess, I will restructure the project and likely throw out the skinny war. That should fix it.
So, you were using #Named instead of #ManagedBean on your managed beans? :)
This can happen if the faces-config.xml is not declared conform JSF 2.0 spec. Ensure that the root declaration look like this:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<!-- config here -->
</faces-config>

Resources