parsing error while including taglib - jsf-2

I'm trying to use Apache Commons Lang 3 in my JSF 2 application, and I followed BalusC's example
But when I included this line in my .xhtml page :
<%#taglib prefix="f" uri="/WEB-INF/functions.tld" %>
I have an error while parsing the page code.
How can I fix the problem?

The answer was targeted on a question whose asker is known to use JSF 1.x on JSP. The syntax which you've there is specific to JSP, the legacy predecesor of Facelets which is deprecated since JSF 2.0.
Get rid of the functions.tld file altogether. The proper JSF 2.x Facelets way of declaring a custom function based on an existing static method is as follows:
First create a /WEB-INF/functions.taglib.xml:
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
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"
version="2.0">
<namespace>http://example.com/functions</namespace>
<function>
<function-name>escapeJavaScript</function-name>
<function-class>org.apache.commons.lang.StringEscapeUtils</function-class>
<function-signature>java.lang.String escapeJavaScript(java.lang.String)</function-signature>
</function>
</facelet-taglib>
Then register it in /WEB-INF/web.xml:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/functions.taglib.xml</param-value>
</context-param>
(that step is unnecessary when it is placed in /META-INF of a JAR file which is in turn placed in /WEB-INF/lib)
Finally declare and use it as follows:
<html ... xmlns:func="http://example.com/functions">
...
<h:outputScript>var foo = '#{func:escapeJavaScript(bean.foo)}';</h:outputScript>
Note that I've updated the answer you found accordingly. Also note that this function is already provided out the box as #{of:escapeJS(bean.foo)} by JSF utility library OmniFaces, in case you're using it.

Related

How do I get IDE code completion to work with JSF 2.2 non-composite component attributes?

Problem: I get code completion on the tags but not the attributes.
I am working on a new web application using
Java 8
JSF 2.2.14
PrimeFaces 6.1
Netbeans 8.2
We are using a library that is provided to us in JavaScript (generated from Typescript sources). I have written a non-composite component to wrap this library and keep all that JavaScript code hidden and in one place. It initializes the the library and provides attributes to pass JavaScript callback functions to the library (so we still have to write some JavaScript).
snippet from the JSF .xhtml file
<script type="text/javascript">
function jscallbackHandler() { alert("function called!");}
</script>
<myComponent:initialize callback1="jscallbackHandler" />
This tag invokes my class to write a lot of JavaScript into the page to setup and initialize the library.
I am using the #FacesComponent annotation to declare my classes as custom components.
snippet from 'InitMyComponent.java' file
#FacesComponent(createTag = true,
tagName = "initialize",
namespace = "https://com.my.project/myComponent",
value = InitMyComponent.FAMILY)
public class InitMyComponent extends UIComponentBase { ... }
This is working except for IDE code completion and I can't find documentation or examples for JSF 2.2 components that show how to declare attributes and hook them into the project. I have seen many examples of earlier JSF 2.x components that use a taglib.xml to define the attributes for code completion, but it seems to be 'at odds' with features of the JSF 2.2 style annotation. I have to remove most of the attributes of the annotation (basically revert to a JSF 2.0 style annotation) or I get "Expression Error: Named Object ... not found". I have also gotten Tag Library supports namespace, but no tag was defined for name. If I just provide a component name to the annotation that matches the one in the taglib file it works, but just no code completion.
I have a FACELETS_LIBRARIES name/value pair in a context-param tag in the web.xml to declare where my facelet-taglib file is located.
snippet from the 'web.xml' file
<!-- Enable IDE autocompletion on component attributes -->
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/myComponent.taglib.xml</param-value>
</context-param>
I have a facelet-taglib file named 'myComponent.taglib.xml' in my WEB-INF directory (same place as faces-config.xml and web.xml).
UPDATE: Responding to the comment by Kukeltje, I updated my facelet-taglib file to version 2.2, but I still get "No Suggestions" from my IDE... also updated the namespaces in my .xhtml JSF source file (even though this site said the older versions were still supported
https://jsflive.wordpress.com/2013/05/16/jsf22-namespaces/)
snippet from the 'myComponent.taglib.xml' file
<?xml version="1.0"?>
<facelet-taglib 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-facelettaglibrary_2_2.xsd">
<namespace>http://java.sun.com/jsf/composite/components</namespace>
<composite-library-name>myComposites</composite-library-name>
<namespace>https://com.my.project/myComponent</namespace>
<tag>
<tag-name>initialize</tag-name>
<component>
<component-type>InitMyComponent</component-type>
</component>
<attribute>
<name>callback1</name>
<required>false</required>
<type>java.lang.String</type>
</attribute>
</tag>
The faces-config.xml file - defines the javaee and schema namespaces, and version 2.2 but it is otherwise 'empty'.
<?xml version="1.0" encoding="UTF-8"?>
<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>
I am fine with having to type in all the attributes but I just can't seem to find the proper way to hook this feature into my project.
Note: I have experimented with using a composite component. The code completion for attributes worked, but then I lost code completion for the tags. I'm just writing out JavaScript to setup and call a JavaScript library's initialize function but also, I would really love to pass a JavaScript object back to a bean on the server when my callback function is invoked. I am currently using a BalusC provided solution that involves p:remoteCommand and updating hidden input fields. I would greatly prefer to provide reference to the bean using EL in an attribute of my custom component.

Custom taglib results in MethodNotFoundException

What I want to do is declare a common datatable header as a composite component. But this answer set me straight since it was not rendered:
How to create a composite component for a datatable column?
Basically it instructed me to try my own taglib and this works really well except my header has a link in it that does reRender. When this link is pressed MethodNotFoundException is thrown.
This is my custom taglib:
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
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"
version="2.0">
<namespace>http://stackoverflowdummy.com/dumb/components</namespace>
<tag>
<tag-name>tableHeader</tag-name>
<source>tags/tableHeader.xhtml</source>
<attribute>
<description></description>
<name>value</name>
</attribute>
<attribute>
<description>The listener that handles sorting</description>
<name>sortAction</name>
<method-signature>java.lang.String action()</method-signature>
</attribute>
<attribute>
<description>The property that holds the current id to sort on
</description>
<name>sortValue</name>
</attribute>
<attribute>
<description>The component that needs to be updated after changes
</description>
<name>reRender</name>
</attribute>
</tag>
</facelet-taglib>
I tried without method-signature and I also tried removing "action". My web.xml does include the taglib like this:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/cc.taglib.xml</param-value>
</context-param>
I also tried with "facelets.LIBRARIES" but it made no difference.
<h:commandLink value="#{o.label}" action="#{sortAction}" immediate="true" reRender="#{reRender}">
<f:setPropertyActionListener target="#{sortValue}" value="#{o.column.sortId}" />
</h:commandLink>
End usage is defined like this:
sortAction="#{myBean.sort}"
That bean has a method called with signature String sort(); and it works really well if I just define it and skip using my own tag. However everything works with the tag except the action method...
The JavaBean Specification gives multiple ways on how to call a method. In fact, you can call a action the normal way #{actionBean.actionMethod}, but also the way #{actionBean['actionMethod']}.
The sorting Action you are giving is transferred as a MethodExpression, which compared to ValueExpressions gave me problems in some JSF Environments.
What I'd like you to try testwise is, to give the action as two separate (value) parameters:
sortActionBean="#{myBean}"
sortActionMethod="sort"
and call those in the template as #{sortActionBean['sortActionMethod']}. A good article on this topic is Passing action methods facelets tags.
Hope it helps...

Facelet Method call where property required

Is it possible to invoke a method where property is expected in JSF 2.0 Facelet EL. For example:
<h:outputText value="#{pojo.methodName}" />
where pojo is an instance of POJO and methodName is the name of method. An error would be thrown because JSF expects to find getMethodName method.
Before someone asks why one would need this, consider any value we want to display in text which is computed and we don't have required getter method and no source code.
Update after BalusC Answer:
No rename possible because no source code available. methodName() didn't work. The only difference is that in actual code its chained pojo.
<h:outputText value="#{pojo1.pojo2.methodName()}" />
Since other properties are working for pojo2, I assume that its methodName which can not be invoked. Server says "The class does not have the property methodName"
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
Empty faces-config
<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>
P.S. environment JBoss 6 and JSF 2
Add parentheses:
<h:outputText value="#{pojo.methodName()}" />
(which only works in EL 2.2, which is part of Java EE 6, so it only works out box in Tomcat 7, Glassfish 3, etc, see also Invoke direct methods or methods with arguments / variables / parameters in EL)
Or just rename the method:
public String getMethodName() {
// ...
}

Geting 404 error when request is made from JSP

I am trying to learn Struts2, but I am unable to create a working hello world application. It's giving a 404 (page not found) error when request is made from JSP. I kept all the lib files in the lib folder, placed struts.xml inside classes folder, but I am still getting this error.
Here is the view:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello World</title>
</head>
<body>
<form action="HelloWorld">
<input type="submit">
</form>
</body>
</html>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
This is my struts.xml file
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="default" extends="struts-default">
<action name="HelloWorld" class="vaannila.HelloWorld">
<result name="SUCCESS">/success.jsp</result>
</action>
</package>
</struts>
This is the error:
HTTP Status 404 - /Testi/HelloWorld
type Status report
message /Testi/HelloWorld
description The requested resource (/Testi/HelloWorld) is not available.
Apache Tomcat/6.0.33
This is the same question that you posted in Struts2 : Using form action just a bit more verbose.
You're problem is in the form tag you are using. It's not a struts form tag and the action attribute in a struts form tag is handled differently in a action attribute in an HTML tag.
I think my answer in Struts2 : Using form action should work for you.
PS: if you haven't changed your action extension, you may be able to make this work by simply adding a .action onto the end of your standard HTML tag action:
<form action="HelloWorld.action">
...
</form>
I would suggest to create a new folder under tomcat.webapps folder and place all your files according to the standards and give a try if you are using any IDE.
Try debugging from scratch,
first see if you are able to hit localhost:8080 sucessfully,
then try hitting a servlet(change the web.xml accordingly) to see if
you are able to go through.
Finally try hitting struts2 action. Make sure url-mapping you give is
correct.
I think this should be a mapping issue.
Can you post the error log content? and about the structure of the project.404indicatng the your server to able to locate the requested resources this can be a issue of your mapping or may be t unable to find the mapping file in class path.
you need to place struts.xml file in the class path so if you are using Eclipse just drop your struts.xml file inside src folder rest eclipse know how to handle this
Also the best way to learn struts2 is to download the sample applications from there official site
Example Applications:
this will help you to understand and learn struts2 better because
Sample application will help you to understand what structure one need to have
What all configuration files need to be placed and at what location
What are all required dependencies for a simple hello world application
Add imported lib to Action class
ex:
import com.opensymphony.xwork2.ActionSupport;
public class HelloWorldAction extends ActionSupport{
//....
//....
}

Issues while Upgrading Jsf1.0 to Jsf2.0

While upgrading application to Jsf2.0 created in Spring3 and Jsf1.0 (myfaces), i am facing some issues mentioned below.
I have done following steps to upgrade the application.
From IntelliJ IDEA:
* Open project settings/Monitor/Dependencies
* Removed facelet*jar, el*.jars, myfaces* jars from project
* Added jsf2.0.x ri mojarra jars and tomahawk1.1.9.jar
* Open project settings/monitor/web settings
* Under "modules and libs to package": remove el-.jars,facelet-jar and myfaces jars
* Added jsf2.0.x ri mojarra jars and tomahawk1.1.9.jar
* Removed erroneous class usages from our classes Lists.java and RegExValidator.java. In Lists.java, replace import with org.apache.commons.lang.LocaleUtils. In RegExValidator, replace import with "org.apache.myfaces.shared_tomahawk.util.MessageUtils".
Edit Web.xml:
* facelets.VIEW_MAPPINGS -> javax.faces.FACELETS_VIEW_MAPPINGS
* facelets.LIBRARIES -> javax.faces.FACELETS_LIBRARIES
* Change Faces Servlet to <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
* Change header to:
<web-app version="2.5"
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_2_5.xsd">
Edit faces-config.xml:
* Add header:
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">
* Remove line "<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>"
After doing all the steps mentioned above getting the following error:
A literal value was specified for attribute actionListener that is defined as a deferred method with a return type of void. JSP.2.3.4 does not permit literal values in this case
Actually Jsf2.0 el expressions #{myBean.property} are not getting resolved thats why its showing the above error.
Can anybody guide me, what is missing, so that i can successfully migrate application to Jsf2.0
Thanks in Advance,
Dhillon
A literal value was specified for attribute actionListener that is defined as a deferred method with a return type of void. JSP.2.3.4 does not permit literal values in this case
This EL validation error means that you've somewhere a
<h:commandButton actionListener="somestring" />
instead of
<h:commandButton actionListener="#{someBean.actionListener}" />
or
<h:commandButton action="somestring" />
(instead of h:commandButton you can also read any UICommand component like h:commandLink)
Just locate/lookup the culprit in the code and fix it accordingly.
Upgrade web-app version="3.0" to latest. Previously web-app version is 2.5 at that time I got error, after upgrade to 3.0 issue resolved.
<?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">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

Resources