Custom component in JSF2 not being called - jsf-2

I'm creating a custom tag in my application but for some reason it's not working, I followed this tutorial (which is the clearest one that I found to put here as reference) but, like other tutorials that I did, my custom tag ins not called.
WEB-INF/example.taglib.xml
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
version="2.0">
<namespace>http://example.com/facelettags</namespace>
<tag>
<tag-name>hello</tag-name>
<handler-class>example.MenuTagHandler</handler-class>
</tag>
</facelet-taglib>
My tag handler class
package example;
public class MenuTagHandler extends TagHandler {
private String name = "Anonymous";
public MenuTagHandler(TagConfig config) {
//other constructor stuff
Logger.getLogger(MenuTagHandler.class).info("aaaa");
//other constructor stuff
}
#Override
public void apply(FaceletContext context, UIComponent parent) throws IOException {
Logger.getLogger(MenuTagHandler.class).info("aaaa");
UIComponentBase c = new UIComponentBase() {
#Override
public void encodeEnd(FacesContext ctx) throws IOException {
ResponseWriter w = ctx.getResponseWriter();
w.write(String.format(
"<p>Hello %s! I am FaceletTag.</p>",
name));
}
// abstract method in base, must override
#Override
public String getFamily() {
return "com.example.facelettag.test";
}
};
parent.getChildren().add(c);
}
}
My .xhtml file
<?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">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:exampler="http://example.com/facelettags" >
<example:hello />
</ui:composition>
The rendered result is
<example:hello></example:hello>
Unfortunately nothing is printed in the log, does anyone have any idea on why it is not calling the tag handler?

If the *.taglib.xml file is not inside the /META-INF of a JAR file which is placed in /WEB-INF/lib and thus won't be automatically detected and registered (like as in case of all those 3rd party JSF component libraries like PrimeFaces, RichFaces, etc), then you'd need to manually register it in webapp's web.xml as follows:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/example.taglib.xml</param-value>
</context-param>
Unrelated to the concrete problem, please note that what you've so far is not a custom component. This is a custom taghandler which in turn creates an anonymous instance of UIComponentBase. This is not necessarily the "best" practice. If you do not need to perform any actions related to the component tree during view build time, then you do not need the taghandler part at all. Just create a fullworthy #FacesComponent class instead.
See also:
When to use <ui:include>, tag files, composite components and/or custom components?

Related

Bean or property class for managed bean cannot be found

I'm trying to make a simple JSF hello world, with JSF 2.0, JBoss AS 7.0
Here's my xhml file :
<!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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Page 1</title>
</h:head>
<body>
<f:view>
<h:outputLabel value="Hello Stock Manager Hello JSF again" />
<br/>
<h:outputLabel value="Tester Bean : #{testerBean.message}" />
</f:view>
</body>
</html>
and here's the managed bean class :
package prv.stockmanager.web.beans;
public class TesterBean {
private String message = "This is a message";
public TesterBean() {
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
And here's the faces-config (which is in the web-inf) :
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
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">
<managed-bean>
<managed-bean-name>testerBean</managed-bean-name>
<managed-bean-class>prv.stockmanager.web.beans.TesterBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property> <property-name>message</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
</managed-bean>
</faces-config>
The page works fine without exception if I remove the call to the managed bean. But when I call the managed bean I get this :
Bean or property class prv.stockmanager.web.beans.TesterBean for managed bean testerBean cannot be found.
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:265) [jsf-impl-2.1.3-b02-jbossorg-2.jar:2.1.3-SNAPSHOT]
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244) [jsf-impl-2.1.3-b02-jbossorg-2.jar:2.1.3-SNAPSHOT]
Is it because JBoss AS 7.0 is using JSF 2.1 jar file or something? Should I use JSF 2.1 then? How to change that?
Problem resolved, I figured out that Eclipse is not generating the class. I disabled the automatic build and it worked fine. There should be a problem with JBoss Studio that I am using.

Creating ICEfaces application example connecting beans and Facelets

I'm new in developing web applications and I installed the ICEfaces plugin. I found this tutorial to learn how to work with it and the first given example dont work in my IDE.
Its about the last part of the tutorial where it shows how to use a dateTimeEntry in a webapp.
So I followed the instructions so that my index.xhtml looks like this:
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:icecore="http://www.icefaces.org/icefaces/core"
xmlns:ace="http://www.icefaces.org/icefaces/components"
xmlns:ice="http://www.icesoft.com/icefaces/component">
<h:body>
<form>
<ace:dateTimeEntry id="dateTimeEntryId"
value="#{yourBean.selectDateProperty}" timeZone="Canada/Mountain"
pattern="MMM/dd/yyyy" style="width: 729px; " renderAsPopup="true">
</ace:dateTimeEntry><br />
</form>
</h:body>
</html>
And my java bean like this:
package org.icefaces.view;
import java.io.Serializable;
import java.util.Date;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.icefaces.ace.event.DateSelectEvent;
#ManagedBean(name= "yourBean")
#ViewScoped
public class YourBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5058131064162864510L;
private Date selectDateProperty = new Date(System.currentTimeMillis());
public Date getSelectDateProperty() {
return selectDateProperty;
}
public void setSelectDateProperty(Date selectDateProperty) {
this.selectDateProperty = selectDateProperty;
}
public void dateSelectListener(DateSelectEvent event) {
setSelectDateProperty(event.getDate());
}
}
The structure of the project looks like this:
The point is, that in the tutorial there is no location given where to save the java beans. So I thougt it has to saved in the java resources directory, but I'm not sure because the app dont work. I just get a blank screen. The server and the configuration of it is valid I think because I can drop some Img or buttons and see the result in the browser. So I think I did not really understand how the java beans are connected with the xhtml files. I thougt it works with ManagedBean - attribute but I'm not sure about that.
Complete list of sample codes you can find here
http://anonsvn.icesoft.org/repo/icefaces3/trunk/icefaces/samples
Well I found out, that the connection of the javabeans and the variables in the xhtml file has to created in faces-config.xml in this form:
<managed-bean>
<managed-bean-name> [bean-name-of-java-class] </managed-bean-name>
<managed-bean-class> [fullpath-to-java-file] </managed-bean-class>
<managed-bean-scope>[scope]</managed-bean-scope>
</managed-bean>

JSF, Composite Component: method call with default attribute value as parameter

I am new to JSF and still learning. I tried searching for a solution to my specific problem described below but I could not find anything. If it because I was searching for the wrong things, please point me in the right direction, but hopefully it is something that hasn't been answered and an answer can benefit everyone.
The following example illustrates the problem I came across. The example is simplified to focus on the problem and to hide the complexities of the actual project in which the problem occurred.
Consider the following pages / classes:
/resources/test/custom.xhtml;
/test/CharsetProvider.java;
/test/CharsetHello.java;
/testWith.xhtml;
/testWithout.xhtml;
/resources/test/custom.xhtml
This is composite component with one attribute with a default value. The component simply takes the attribute value and passes it as an argument to the CDI bean described below in order obtain the model object used for output.
<?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:cc="http://java.sun.com/jsf/composite"
xmlns:h="http://java.sun.com/jsf/html">
<cc:interface>
<cc:attribute name="charset"
default="#{charsetProvider.defaultCharset}"
type="java.nio.charset.Charset" />
</cc:interface>
<cc:implementation>
<h:outputText value="#{charsetProvider.createCharsetHello(cc.attrs.charset).hello}"/>
</cc:implementation>
</html>
test/CharsetProvider.java
This is a CDI bean that simply contains a default value used throughout the application and has a method that creates an object used as the model for a component. The reason I use a CDI bean instead of a backing bean is because in my specific project the default value needs to be injected at runtime, but backing beans are not candidates for injection.
package test;
import java.nio.charset.Charset;
import javax.annotation.PostConstruct;
import javax.faces.bean.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class CharsetProvider {
private Charset defaultCharset;
#PostConstruct
protected void postConstruct() {
this.defaultCharset = Charset.forName("UTF-8");
}
public Charset getDefaultCharset() {
return defaultCharset;
}
public Charset getCharsetForName(String name) {
return Charset.forName(name);
}
public CharsetHello createCharsetHello(Charset cs) {
return new CharsetHello(cs);
}
}
test/CharsetHello.java
This is the "model" object. It simply converts "Hello world!" to a byte array and back using the given charset.
package test;
import java.nio.charset.Charset;
public class CharsetHello {
private static final String HW = "Hello World!";
private final byte[] data;
private final Charset cs;
public CharsetHello(Charset cs) {
this.cs = cs;
this.data = CharsetHello.HW.getBytes(this.cs);
}
public String getHello() {
return new String(this.data, this.cs);
}
}
testWith.xhtml
This is a test page that uses the composite component defined above by specifying a value for the component's attribute. The page renders properly, i.e. "Hello World!" prints on the screen.
<?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"
xmlns:test="http://java.sun.com/jsf/composite/test">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<test:custom charset="#{charsetProvider.getCharsetForName('UTF-16')}" />
</h:body>
</html>
testWithout.xhtml
This is a test page that does not pass a custom value to the component's attribute, intending to use the default value.
<?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"
xmlns:test="http://java.sun.com/jsf/composite/test">
<h:head>
<title>Test</title>
</h:head>
<h:body>
<test:custom />
</h:body>
</html>
The page above results in a JSF error page with the following message:
/resources/test/custom.xhtml #14,94 value="#{charsetProvider.createCharsetHello(cc.attrs.charset).hello}": Cannot convert UTF-8 of type class java.lang.String to class java.nio.charset.Charset
It seems that in the last case the default value is converted to a java.lang.String before being passed to the method.
First off, is this the expected behaviour and why?
If this is the expected behaviour, can you suggest a different implementation?
Thank you in advance!
This problem has exactly the same ground as this problem: FacesConverter forClass don't work with Composite Componet. The composite attribute value type is in Mojarra incorrectly been evaluated as java.lang.Object instead of the actual model type.
It's been reported as Mojarra issue 2568. It works in MyFaces 2.1.9.

struts 2 - action class is not mapped

I am starting to study struts 2. I followed the example here.
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<package extends="struts-default">
<action name="hello"
class="com.tutorialspoint.struts2.HelloWorldAction"
method="execute">
<result name="success">/HelloWorld.jsp</result>
</action>
</package>
</struts>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>HelloWorld3</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
index.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hello World</title>
</head>
<body>
<h1>Struts2</h1>
<form action="hello">
<label for="name">Please enter your name</label><br/>
<input type="text" name="name"/>
<input type="submit" value="Say Hello"/>
</form>
</body>
</html>
HelloWorldAction.java
package com.tutorialspoint.struts2;
public class HelloWorldAction{
private String name;
public String execute() throws Exception {
return "success";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
But after running and submitting the form, 404 error occurs.
type: Status report
message: /HelloWorld3/hello
description:The requested resource (/HelloWorld3/hello) is not available.
It does not produce any error in the console. I think the action class is not getting mapped. I know this kind of error is common to all struts beginners but I swear I've been googling this since yesterday.
struts.xml is inside /src/, I also tried putting it inside WEB-INF/classes, still got no luck.
I'm using eclipse gallileo and tomcat 6 inside it.
Replies are really appreciated.
My bad, just realized the web.xml is not the same with the web.xml in the tutorial. Also I forgot to specify the package name in struts.xml. After correcting these, I then encountered an error in the console,
java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
To solve this problem I added commons-lang3-x.y in the WEB-INF/lib directory together with other jars required by the tutorial to be added.
your class could extend ActionSupport class or Action Interface then only it will become an action class. And no need call the method execute explicitly by default it will call execute method. If you were overriding it you need to mention that method name.
And it's not mandatory to use ActionSupport class. This is basically a helper class which provides many out of the box features for you, but at same time Struts2 framework do not ask to use this class, all it want is an entry method for your action class with return type as String and which can throw a general Exception
beside validation or Internationalization this class also provides many other features like Action level Errors etc.
<action name="hello"
class="com.tutorialspoint.struts2.HelloWorldAction">
package com.tutorialspoint.struts2;
public class HelloWorldAction extends ActionSupport{
private String name;
public String execute() throws Exception {
return "success";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
add commons-lang3.x.y.z jar and commons-fileupload-x.y.z jar to your buildpath to avoid 'resource not available' error
http://viralpatel.net/blogs/tutorial-create-struts-2-application-eclipse-example/
You can get the Simple Struts 2 Example Demo with the jar files.

Facelets custom function not found

I'm writing a simple custom function in Facelets with a sample method. The problem is that the JSF 2 application fails to locate that function. The error message is:
/test.xhtml #15,73 rendered="#{test:isGranted('ONE_ROLE')}" Function 'test:isGranted' not found.
I've been checking and rechecking and can't find the problem. Any comment here would be really appreciated as it's clear that I'm missing something (but it seems that the steps involved are really simple).
Do you know if there are other requisites?
Thanks in advance.
The relevant code:
In the web.xml the tag XML descriptor is declared
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/test.taglib.xml</param-value>
</context-param>
The file test.taglib.xml:
<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://www.test.com/security/tags</namespace>
<function>
<function-name>isGranted</function-name>
<function-class>com.test.security.taglibs.IsGranted</function-class>
<function-signature>boolean isGranted(java.lang.String role)</function-signature>
</function>
</facelet-taglib>
The tag class:
public class IsGranted extends TagHandler {
public static boolean isGranted(String role) {
// Do nothing. Just a test.
return false;
}
}
And the test file:
<?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"
xmlns:test="http://www.test.com/security/tags">
<body>
<h:outputText value="You should NOT see this." rendered="#{test:isGranted('ONE_ROLE')}"/>
</body>
</html>
In your example you are declaring the sec namespace prefix but use the test prefix in your function call. But maybe that was just a copying mistake.
Another possible cause would be the header of your taglib file, which uses the facelets 1.0 DTD instead of the JSF 2.0 version. This might be problematic depending on your JSF implementation, for example for MyFaces see this bug report and discussion thread. The header for a JSF 2.0 taglib would be:
<facelet-taglib version="2.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-facelettaglibrary_2_0.xsd">

Resources