JSF2: NullpointerException at custom composite component - jsf

I've been trying to create an own component to "replace" the Richfaces spacer, which is no longer available in Richfaces 4.
I have found this link for the actual implementation: https://community.jboss.org/wiki/SpacerImplementationForJSF2OrRichFaces4
I tried to register the new taglib:
richext.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://java.sun.com/jsf/composite/richext</namespace>
<tag>
<tag-name>spacer</tag-name>
<source>../richext/spacer.xhtml</source>
</tag>
web.xml
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>WEB-INF/richext.taglib.xml</param-value>
</context-param>
changed the spacer.xhtml a little bit to:
<composite:implementation>
<h:panelGroup rendered="#{cc.attrs.height > 0}">
<br/>
</h:panelGroup>
<h:graphicImage value="../img/spacer.gif"
width="#{cc.attrs.width}px"
height="#{cc.attrs.height}px"/>
</composite:implementation>
I added
xmlns:richext="http://java.sun.com/jsf/composite/richext"
to the pages where I want to use the spacer.
My Files:
WebContent/WEB-INF/richext.taglib.xml
WebContent/richext/spacer.xhtml
WebContent/img/spacer.gif
Now, when accessing a page where I use the spacer (other pages work fine) I get a NullpointerException in the browser, not in the server log.
java.lang.NullPointerException
at org.apache.myfaces.view.facelets.tag.composite.CompositeComponentDefinitionTagHandler.apply(CompositeComponentDefinitionTagHandler.java:113)
at org.apache.myfaces.view.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:57)
at org.apache.myfaces.view.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:48)
at org.apache.myfaces.view.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:394)
at org.apache.myfaces.view.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:448)
at org.apache.myfaces.view.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:390)
at org.apache.myfaces.view.facelets.tag.UserTagHandler.apply(UserTagHandler.java:138)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:51)
at javax.faces.view.facelets.DelegatingMetaTagHandler.applyNextHandler(DelegatingMetaTagHandler.java:59)
at org.richfaces.view.facelets.html.BehaviorsAddingComponentHandlerWrapper.applyNextHandler(BehaviorsAddingComponentHandlerWrapper.java:53)
at org.apache.myfaces.view.facelets.tag.jsf.ComponentTagHandlerDelegate.apply(ComponentTagHandlerDelegate.java:294)
at javax.faces.view.facelets.DelegatingMetaTagHandler.apply(DelegatingMetaTagHandler.java:54)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:51)
at org.apache.myfaces.view.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:57)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:51)
at org.apache.myfaces.view.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:48)
at org.apache.myfaces.view.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:179)
at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.buildView(FaceletViewDeclarationLanguage.java:417)
at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:78)
at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:239)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:191)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1188)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:763)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:454)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:125)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:77)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:919)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1016)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:87)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:895)
at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1662)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:195)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:452)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:511)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:305)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:276)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)
at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)
at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1659)
Where did I go wrong? Am I missing something?
My Server is a Websphere 8.0.0.2 if that's important.
Thanks in advance

You don't need that richext.taglib.xml file and that web.xml entry at all. Just put the composite component in /resources/richext folder, exactly as explained in the answer you found. Your concrete problem is caused because you attempted to register a composite component as a tag file (which are two entirely separate concepts). The incorrect taglib file might have caused MyFaces to choke like that.
See also:
Composite component info
When to use <ui:include>, tag files, composite components and/or custom components?

Related

f:validateRegex always checked when deploy a jsf2.1 project into weblogic12c

I am going to deploy a jsf2.1(jsf2.1+spring3+primface-3.0.M3) project to weblogic 12c(jdk1.8).
Its a long story to make it work in weblogic12c,but there are still some problems,such as <f:validateRegex component, it always checked no matter whether there is empty or not,but it works fine in weblogic10.3.6(jdk1.7)
How can i fix it without change the pattern or other attributes?
My code:
<f:validateRegex pattern="^[0-9a-zA-Z;\s\r\*]+$" />
My weblogic.xml:
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app">
<container-descriptor>
<prefer-web-inf-classes>false</prefer-web-inf-classes>
<prefer-application-packages>
<package-name>javax.faces.*</package-name>
<package-name>com.sun.faces.*</package-name>
<package-name>com.bea.faces.*</package-name>
<package-name>net.sf.cglib.*</package-name>
<package-name>javax.annotation.*</package-name>
<package-name>org.primefaces.*</package-name>
</prefer-application-packages>
<prefer-application-resources>
<resource-name>javax.faces.*</resource-name>
<resource-name>com.sun.faces.*</resource-name>
<resource-name>com.bea.faces.*</resource-name>
<resource-name>META-INF/services/javax.servlet.ServletContainerInitializer</resource-name>
<resource-name>META-INF/services/com.sun.faces.spi.FacesConfigResourceProvider</resource-name>
<resource-name>META-INF/resources/javax.faces/jsf.js</resource-name>
<resource-name>META-INF/resources/javax.faces/jsf-uncompressed.js</resource-name>
</prefer-application-resources>
<!-- <prefer-web-inf-classes>true</prefer-web-inf-classes> -->
</container-descriptor>
</weblogic-web-app>
Thanks for your reading.
To avoid validation of empty field you can add this parameter to your web.xml (works in jsf 2.1)
<context-param>
<param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
<param-value>false</param-value>
</context-param>
In this post you can find some explanation and many others parameters.

Overriding PrimeFaces renderer not working when provided via module library

I have a very tricky problem when overriding JSF-renderers.
This is a part of my faces-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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"
version="2.0">
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.MenubarRenderer</renderer-type>
<renderer-class>de.mycompany.web.MenuRenderer</renderer-class>
</renderer>
</render-kit>
<factory>
<exception-handler-factory>de.mycompany.web.ValidationExceptionHandlerFactory</exception-handler-factory>
</factory>
</faces-config>
The structure of my web-project is following
webapp (building war), Dependencies to core and gui
core (building jar)
gui (building jar), Dependencies to core, containing xhtmls and #Named Beans, Dependency to com.sun.faces:jsf-impl Version 2.1.25
When I place the content of the faces-config.xml in
webapp/src/main/webapp/META-INF or
core/src/main/webapp/META-INF
both, the MenuRenderer and the ValidationExceptionHandlerFactory, are getting used. Yeah.
When I place the content of the faces-config in
gui/src/main/webapp/META-INF
the ValidationExceptionHandlerFactory is getting used, but not the MenuRenderer. WTF?
Also all other features (phase-listeners, system-event-listeners I use in my faces-config are working except ones in the render-kit-nodes.
What am I doing wrong?
You're trying to override a renderer supplied by another external library, not a standard renderer.
The loading order of faces-config.xml provided by external libraries is by default undefined. In your specific case, your library is apparently loaded before PrimeFaces library is loaded.
You can explicitly specify the loading order via <ordering> element in faces-config.xml. The name of the PrimeFaces library is primefaces. So, just add the below entry to your faces-config.xml. Make sure you supply your library a name too so that endusers can in turn reorder in their own faces-config.xml if necessary.
<name>yourlibrary</name>
<ordering>
<after>
<name>primefaces</name>
</after>
</ordering>
A real world example can be found in e.g. OptimusFaces which also extends PrimeFaces.

ValueChangeListener on custom component leads to PropertyNotFoundException

We have a custom JSF component that renders some buttons and a select box in a specific way. This is done by a class that extends UIInput. This custom component used in the xhtml templates like so:
<xx:fooComponent
value="#{fooBean.someProperty}"
valueChangeListener="#{fooBean.someMethodInBean}"
someOtherProperties="true" />
Now since we changed from JBoss 4.2.2 running JSF 2.0 to JBoss 7.1.1 running with the built-in JSF libs, it complains about someMethodInBean not being a property. Of course it's not a property, it's a method. Who in the world would bind a property to a valueChangeListener?
At first I thought, this had something to do with the method being in a superclass of the referenced bean, but that wasn't the case. Adding this particular method to FooBean did not make any difference.
So my question is, what did they change so that this breaks now and how can I fix it in a migrating-friendly way?
edit
The component is declared as such in our *.taglib.xml:
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<!-- ... -->
<tag>
<tag-name>fooComponent</tag-name>
<component>
<component-type>myProject.FooComponent</component-type>
</component>
</tag>
... which leads to this declaration in faces-config.xml:
<component>
<component-type>myProject.FooComponent</component-type>
<component-class>com.myproject.somemore.UIFooComponent</component-class>
</component>
... which leads to the class UIFooComponent extends UIInput.
edit 2
Now the taglib xml looks like this:
<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">
<tag>
<tag-name>fooComponent</tag-name>
<component>
<component-type>myProject.FooComponent</component-type>
</component>
<attribute>
<name>valueChangeListener</name>
<method-signature>void valueChanged(javax.faces.event.ValueChangeEvent)</method-signature>
</attribute>
</tag>
</facelet-taglib>
Still, he complains about fooBean not having the property someMethodInBean.
edit 3
The stack trace is:
Caused by: javax.el.ELException: /abc/abc.xhtml: The class 'com.myproject.managedbeans.foo.FooBean' does not have the property 'someMethodInBean'.
at com.sun.faces.facelets.compiler.AttributeInstruction.write(AttributeInstruction.java:94)
at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:82)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:302)
at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185)
at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1779)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
at org.apache.myfaces.tomahawk.application.ResourceViewHandlerWrapper.renderView(ResourceViewHandlerWrapper.java:93)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
... 21 more
This indicates that the tag attribute isn't been declared as a <method-signature> in the component's <tag> declaration in the .taglib.xml file as follows:
<attribute>
<name>valueChangeListener</name>
<method-signature>void valueChange(javax.faces.event.ValueChangeEvent)</method-signature>
</attribute>
Make sure that this is properly been declared as above.
Update: you need to make sure that you've declared the .taglib.xml file conform JSF 2.x Facelets XSD (and thus not a DTD as it was in legacy Facelets 1.x).
<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"
>
<!-- Tags here -->
</facelet-taglib>

JSF 2.1 - Facelet cache factory configuration

I am using Mojarra 2.1.2 and want to configure the facelet cache factory. I tried the following in my WEB-INF/faces-config.xml but it does not seem to work.
<factory>
<facelet_cache_factory>org.valuesource.custdb.web.extension.SimpleFaceletCacheFactory</facelet_cache_factory>
</factory>
You shouldn't use underscores. Use hyphens.
<facelet-cache-factory>
No one XML element of faces-config.xml uses underscores. Note that the FaceletCacheFactory was introduced in JSF 2.1, so ensure that your faces-config.xml root declaration conforms JSF 2.1:
<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_1.xsd"
version="2.1">

Custom Facelets components and attributes defined in taglib

Defining custom components in Facelets is easy and quick but there's one thing I can't figure out.
Is it possible with Facelets to define what attributes my custom component has? I.e: I've created a component which is used in such a way:
<blue:modalWindow id="editFeesWizard" width="500" height="440" title="Wizard">
and is defined in taglib.xml as follows:
<!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>...</namespace>
<tag>
<tag-name>modalWindow</tag-name>
<source>components/modalWindow.xhtml</source>
</tag>
</facelet-taglib>
Taglib doesn't contain any information on component's attributes (id, width, height, title) and IDE cannot therefore check my syntax nor can it suggest attributes while I'm typing.
I cannot find anything on this subject in Facelets documentation. Thought you could help. Thanks!
It seems there isn't a way. But even if there was, I don't think Eclipse (for example) would be able to handle it and offer autocomplete. That's why you can define a .tld, containing the attributes:
<?xml version="1.0" encoding="utf-8"?>
<taglib
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1">
......
</taglib>
Just for the sake of autocompletion. Ugly, I know.
I don't know about before, but it is possible now. Just add:
<tag>
<tag-name>mycustomtag</tag-name>
<source>tags/mycustomtag.xhtml</source>
<attribute>
<description>What does this do?!</description>
<name>attribute</name>
</attribute>
</tag>
I'm looking forward to being able to create composite components using JSF 2 and facelets; from what I've read, it seems very quick and easy, and you define what attributes your composite component accepts.

Resources