simple JSF commandButton not hitting the action - jsf

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*/
}

Related

the name of the driver class for the datasource is missing

From How to set up a JDBC Connection Pool on Glassfish I would like to connect MyQueue to the Birds JDBC resource in Glassfish. I'm getting an error similar to: The name of the driver class for the datasource is missing; the only difference being that I'm using MySQl instead of PostgreSql:
birds resource:
successful ping:
(the ping does indicate that the connection properties are correct?)
facelets:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head></h:head>
<h:body>
This and everything before will be ignored
<ui:composition template="template.xhtml">
<ui:define name="navigation">
<ui:include src="menu.xhtml"/>
</ui:define>
<ui:define name="main">
<h1>bird</h1>
#{myQueue.next}
</ui:define>
</ui:composition>
This and everything after will be ignored
</h:body>
</html>
and the bean:
package dur;
import java.io.Serializable;
import java.util.logging.Logger;
import javax.inject.Named;
import javax.ejb.Singleton;
import javax.enterprise.context.ApplicationScoped;
//import javax.inject.Singleton;
#Named
#ApplicationScoped
#Singleton
public class MyQueue implements Serializable {
private static final long serialVersionUID = 403250971215465050L;
private final Logger log = Logger.getLogger(MyQueue.class.getName());
private int next = 1;
public MyQueue() {
}
public int getNext() {
log.info("next\t" + next);
return next++;
}
}
The bean and facelet are functioning correctly, I just want to connect MyQueue to the database. I would like to use JPA to connect to the database.
The option to edit the field is grayed out.
--------------------------------------------edit---------------------------------
Netbeans did some magic and created the connection (I think) by right clicking the enterprise app and select new -> glassfish > jdbc connection pool.
sun-resources.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Resource Definitions //EN" "http://www.sun.com/software/appserver/dtds/sun-resources_1_3.dtd">
<resources>
<jdbc-resource enabled="true" jndi-name="jdbc/birdsPool" object-type="user" pool-name="birdsPool">
<description/>
</jdbc-resource>
<jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="birdsPool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.ConnectionPoolDataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
<property name="URL" value="jdbc:mysql://localhost:3306/legacy?zeroDateTimeBehavior=convertToNull"/>
<property name="User" value="user"/>
<property name="Password" value="gtjropjre"/>
</jdbc-connection-pool>
</resources>
persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="EnterpriseBirdsJPA-warPU" transaction-type="JTA">
<jta-data-source>jdbc/birdsPool</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>
I'm a bit uneasy with sun-resources.xml and would prefer to see that configuration directly on glassfish. I'm not exactly sure that this will work, but it allowed netbeans to then create an entity class from this connection, so that seems like progress. Again, though, that sun-resources.xml isn't actually in glassfish makes this a less than perfect solution.
I had a similar problem, it is basically netbeans problem (that is why everything seems to be fine in the glassfish admin console).
To solve:
1. add mysql-connector-java-5.1.23-bin.jar to "{$installation_folder}\NetBeans 8.0.1\ide\modules\ext"
2. restart netbeans
now it should work as expected
this bug report is also relevant
To solve the same issue you had, I had to add a "driverClass" additional properties in your connection pool (beside "password", "user", "URL").
Its value would be "com.mysql.jdbc.Driver".
Source : http://www.blogarama.com/programming-blogs/194794-wings-hermes-berins-infosec-blog/259237-glassfish-netbeans-name-driver-class-for-datasource-missing

How to form #Named Backing Bean in JSF

I read somewhere that it's better to use CDI #Named instead of JSF #ManagedBean, because of CDI, so I'm trying to convert some of my code.
I'm trying to use #Named in JSF, but it's always unreachable.
When using #ManagedBean there was no problem.
I'm using it like #ManagedBean, as below
CustomerBacking.java
package com.wordpress.marczykm.backing;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
#Named("customer")
#RequestScoped
public class CustomerBacking {
#EJB
private CustomerService customerService;
public CustomerBacking() {
}
public String addCustomer(Customer customer) {
customerService.addCustomer(customer);
return "customer_overview";
}
public Customer getCustomer(){
return customerService.getCustomer();
}
}
index.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>EJB 3.0 Test</title>
</h:head>
<h:body>
<h:outputText value="#{customer.firstname}"/>
<h:form>
<h:outputText value="ImiÄ™"/>
<h:inputText id="firstname" name="firstname" value="#{customer.firstname}" /><br/>
<h:outputText value="Nazwisko"/>
<h:inputText id="lastname" name="lastname" value="#{customer.lastname}" /><br/>
<h:commandButton value="Dodaj" actionListener="#{customer.addCustomer}"/>
</h:form>
</h:body>
</html>
To sum up, looking at Netbeans sample CDI app, the bean which needs to be accesible by JSF page needs to:
have #Named annotation (javax.inject.Named)
have scope annotation (like #SessionScoped, #RequestScoped, #ViewScoped), but imported from javax.enterprise.context.*
doesn't have to have empty, non-argument constructor
and the thing that wasn't in my code is that, that the bean needs to implement Serializable (java.io.Serializable)
last thing is that if your app is a web application it needs a beans.xml (can be completly empty) in WEB-INF directory, if it is a bean app it have to be in META-INF directory
You don't mention which servlet container/application server and which CDI implementation version you're using.
I have no clue what Spring Tool Suite assumes as default, presumably it's Tomcat, Spring and no CDI at all, so you have to add and configure a CDI implementation (e.g. Weld or OpenWebBeans).
For CDI 1.0, you'll have to add a WEB-INF/beans.xml descriptor (which may be empty) to have your beans discovered. This is no longer necesary for CDI 1.1.

JSF do not execute the bean

im trying to learn JSF, but something i lost, cuz this button is not showing the message in eclipse console
the JAVA BEAN:
package beans;
public class protocoloBean {
public void incluirProtocolo() {
System.out.println("MSG");
}
}
the 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"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:button value="Protocolar"
action="#{protocoloBean.incluirProtocolo()}"></h:button>
</h:body>
</html>
and the faces-config:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.2" 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">
<managed-bean>
<managed-bean-name>protocoloBean</managed-bean-name>
<managed-bean-class>beans.protocoloBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<application/>
</faces-config>
what im doing wrong ? or i lost :(
Your JSF code is wrong. You're trying to fire an action using <h:button> when you need/want to use <h:commandButton>. <h:button> is intended for navigation purposes only. See here for a difference between them: Difference between h:button and h:commandButton
You should update your code to:
<h:body>
<ui:remove>
<h:button value="Protocolar"
action="#{protocoloBean.incluirProtocolo()}"></h:button>
</ui:remove>
<!--
Note that h:commandButton MUST ALWAYS be inside a h:form
Otherwise, the action won't fire
-->
<h:form>
<h:commandButton value="Protocolar"
action="#{protocoloBean.incluirProtocolo}" />
</h:form>
</h:body>
After updating your code, the log message will be printed as expected.
Since you're learning JSF 2.2, I would suggest start using JSF 2 features like barely using the faces-config.xml file for managed bean definitions. You could improve your code to this:
#ManagedBean
#SessionScoped
public class ProtocoloBean {
public void incluirProtocolo() {
System.out.println("MSG");
}
}
And your faces-config.xml file*:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.2" 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">
</faces-config>
* Yes, it is empty :).
Since you're new to JSF, I would recommend start declaring your beans as #RequestScoped or #ViewScoped instead of #SessionScoped. You cn read more info about this here: How to choose the right bean scope?
two mistakes in your code:
the first character of your class name should be Captialized. You should use "ProtocoloBean" insteads of "protocoloBean"
Action attribute is used for redirect page, the method type must be String instead of void. If you just want to execute some code, then you should use "actionListener" rather than "action", in this case your method return type can be void, but make sure (ActionEvent action) is defined as your method input argument

#SessionScoped bean injected as #ManagedProperty of a #ViewScoped acts like #RequestScoped in MyFaces, works fine in Mojarra

Here is my simple example:
Index.xhtml in root:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Title</title>
</h:head>
<h:body>
<h:form>
<h:inputText value="#{index.variable}"></h:inputText>
<h:commandButton action="#{index.submit()}" type="submit"></h:commandButton>
</h:form>
</h:body>
</html>
Its ManagedBean:
import java.io.IOException;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
#ManagedBean
#ViewScoped
public class Index implements Serializable {
#ManagedProperty("#{sessionBean}")
private SessionBean sessionBean; /*getter&setter*/
private String variable; /*getter&setter*/
public void submit() {
sessionBean.setAsd(variable);
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
try {
context.redirect("next");
} catch (IOException ex) {
}
}
}
/next/index.xhtml:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Check variable</title>
</h:head>
<h:body>
#{sessionBean.asd}
</h:body>
</html>
SessionBean.java:
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class SessionBean implements Serializable {
private String asd;
public String getAsd() {
return asd;
}
public void setAsd(String asd) {
this.asd = asd;
}
}
If I use mojarra implementation everything works as expected: after form submitting, user gets redirected to root/ and see the value that was printed in the form of index.xhtml.
But if I use myfaces, asd becomes null right after existing form gets submitted. SessionScoped bean acts like RequestScoped
Why?
here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 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-app_3_0.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<listener>
<listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
<!--listener-class>com.sun.faces.config.ConfigureListener</listener-class-->
</listener>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
</web-app>
Server: Apache Tomcat 7.0.34
UPDATE: it works if we change the ViewScoped annotation of Index.java bean to RequestScoped or SessionScoped. But why?
I currently have a JSF 2.1 project written with the help of Mojarra. Just for experimenting, I changed the implementation to MyFaces and ran the application only to see issues similar to yours (all my injected #ManagedProperty variables end up null after a POST submit). I switched back to Mojarra and the app runs fine. So, basically something is different in the MyFaces implementation.
A bit of googling led me to this unresolved issue - MYFACES-3656. Here's an excerpt from the issue reporter on how to fix the issue:
If you set the org.apache.myfaces.SERIALIZE_STATE_IN_SESSION to false
and redeploy the application then everything works as expected.
How does this help? The answer is in the comments section:
I think the behavior described is expected (different to say that the
behavior described is desired or intentionally done in that way).
What's happening here is in MyFaces serialization is set to true by
default (some old lines from JSF 1.0 spec says so, even if RI does not
implement it in this way). In JSF 2.2 spec, SERIALIZE_STATE_IN_SESSION
param will be standardized and set to false by default.
Serialization causes that all beans under view scope are in fact
"recreated". If the param is set to false, the beans are stored into
session and on further requests are used, looking like everything is
ok, but that fact is not true because in a cluster configuration the
same application will fail.
Only the first time the view scope bean is created, the references
from managed-property takes effect, but if the bean is
serialized/deserialized, the references are not restored back, because
on the serialization step, even the application and session scope
beans are serialized too.
.....
How to solve it? I haven't found a decent solution to this issue. One
could think on just restore the view scope bean and reapply
#ManagedProperty annotations or entries found in faces-config.xml, but
the problem is the view scope bean still is storing information that
shouldn't be there from start (only marking the fields as transient
will do the trick). It is possible define an special mode were this
hack or some variant is done, but it will be only in myfaces and it
cannot be enabled by default.
Similar issue has been reported and replied with the above explanation in this mailing-list archive
Now, since in your case you are not explicitly setting a STATE_SAVING_METHOD, it defaults to server. Consequently, SERIALIZE_STATE_IN_SESSION comes into effect and defaults to true.
I tried your code with MyFaces on Tomcat and set SERIALIZE_STATE_IN_SESSION to false and it works. However, in the event, you set the STATE_SAVING_METHOD to client, nothing will work and you'll get a view state not found error.

How to see message.properties in a Jar using JSF?

Using: JSF 1.2, Facelets 1.1.15, GateIn 3.1 GA, Richfaces 3.3.3
I have some common .xhtml and backing bean in a JAR that our portlets can see. I did this by overriding ResourceResolver as described in other posts:
http://ocpsoft.com/opensource/create-common-facelets-jar/
How to use Facelets composition with files from another context
The portlets can load the XHTML and use the backing bean.
Here is my problem: I cannot get the xhtml to substitute the messages defined in messages_en.properties. I have tried moving the properties file outside of the JAR and placing directly in /lib folder. I have also tried putting a / in front of the name to try to get the resolver to find it. I have also put it in the components folder.
The common jar info is: I hava a my-portlet-common-resources.jar which resides in server/my-portal/lib. The jar is structured like so:
com/portlet/common/CustomResourceResolver.class
com/portlet/common/FilterCreateBean.class - backing bean for the common popup
messages_en.properties
faces-config.xml
META-INF/components/commonPopups.xhtml
META-INF/faces-config.xml - declares the FilterBean
META-INF/Manifest.mf
faces-config.xml contents:
<?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_1_2.xsd"
version="1.2">
<application>
<locale-config>
<default-locale>en</default-locale>
</locale-config>
<message-bundle>/messages_en.properties</message-bundle>
</application>
<managed-bean>
<managed-bean-name>FilterCreateBean</managed-bean-name>
<managed-bean-class>com.portlet.common.FilterCreateBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
Include the messages in commonPopups.xhtml (partial snip):
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<a4j:loadBundle basename="messages" var="msgs"/>
<rich:panel style="border-style:none;" id="addNewChainPanel">
<rich:modalPanel id="modalNewChainPanel" autosized="true">
<f:facet name="header"><h:outputText value="#{msgs['filterset.modal.new.title']}" /></f:facet>
</ui:composition>
This should work. Perhaps you already have a messages*.properties file in the classpath root of your main webapp. This one has then precedence in classloading. You need to put it in a more specific package. Put the JAR's one in for example the com/portlet/common folder so that it becomes member of the com.portlet.common package. This way it'll be available by:
<a4j:loadBundle basename="com.portlet.common.messages" var="msgs"/>
Unrelated to the concrete problem, the <message-bundle> entry in faces-config.xml has a completely different purpose. It's supposed to override JSF default validation/conversion messages which are returned by JSF default validators/converters. It is not intended to provide localized content. There you use the <resource-bundle> entry or <xxx:loadBundle> tag for. I'd remove that entry from the faces-config.xml.

Resources