3

As an exercise, I'm creating some custom components in jsf 2.2 by using just annotations. For now I am not interested in a taglib for completion in the ui and since that exempts me from maintaining it, initial development is quicker. This al works perfectly. In this example I have one component that, for now, extends the PrimeFaces InputText (changing that does not make a difference), a clean faces-config (correctly 2.2 namespaced) and a simple page

component:

package my.custom.xforms;

import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.FacesComponent;

import org.primefaces.component.inputtext.InputText;

@FacesComponent(value = "xforms.input", createTag = true,
    namespace =  "http://www.w3.org/2002/xforms", tagName = "input")
@ResourceDependencies({
    @ResourceDependency(library="primefaces", name="primefaces.css"),
    @ResourceDependency(library="primefaces", name="jquery/jquery.js"),
    @ResourceDependency(library="primefaces", name="primefaces.js")}
)
public class Input extends InputText {

    public Input() {
        setRendererType("xforms.inputRenderer");
    }

    @Override
    public String getFamily() {     
        return "my.xforms.components";
    }
}

faces-config.xml

<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>

page

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:xf="http://www.w3.org/2002/xforms"
    xmlns:p="http://primefaces.org/ui">
    <h:head/>
    <h:body>
        <xf:input />
    </h:body>
</html>

This nicely shows a 'PrimeFaces' text input.

As an exercise, I added a tag that defines a model (internal to 'my' engine) that has no ui interaction. So my thought was to add a TagHandler (it does not need to manipulate the tags before it either, so maybe I should just extend UIComponentBase, but that is not the 'issue' now). TagHandlers cannot be created via annotations from what I can see, so I created a taglib.xml and put just my TagHandler in there.

taghandler

package my.custom.xforms;

import java.io.IOException;

import javax.el.ELException;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.view.facelets.ComponentHandler;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.FaceletException;
import javax.faces.view.facelets.TagConfig;
import javax.faces.view.facelets.TagHandler;

public class ModelTagHandler extends TagHandler {

    public ModelTagHandler(TagConfig tagConfig) {
        super(tagConfig);
    }

    public void apply(FaceletContext faceletContext, UIComponent parent) throws IOException, FacesException, FaceletException, ELException {
        if (ComponentHandler.isNew(parent)) {
            System.out.println("XForms Model encountered");
        }
    }
}

new page

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:xf="http://www.w3.org/2002/xforms"
    xmlns:p="http://primefaces.org/ui">
    <h:head/>
    <h:body>
        <xf:model /> <!-- can be put in h:head to, does not make a difference -->
        <xf:input />
    </h:body>
</html>

taglib

<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://www.w3.org/2002/xforms</namespace>

    <tag>
        <tag-name>model</tag-name>
        <handler-class>my.custom.xforms.ModelTagHandler</handler-class>
    </tag>
</facelet-taglib>

To my surprise (well only partly), my custom component created with just annotations, stopped working with the following error.

/components/page.xhtml @12,33 <xf:input> Tag Library supports namespace: http://www.w3.org/2002/xforms, but no tag was defined for name: input

It only started working again if I put the custom component in my taglib to.

<tag>
    <tag-name>input</tag-name>
    <component>
        <component-type>xforms.input</component-type>
        <renderer-type>xforms.inputRenderer</renderer-type>
    </component>
</tag>

Is this expected behaviour? Or should the taghandler be declared in a different way? I tried a lot of combinations of keywords in google, but to no avail. Not finding a bug, nor any hint to do things differently, nothing.

I'm currently running all this in

  • Wildfly 8.0.0-Final (Mojarra 2.2.5-jbossorg-3 20140128-1641)
  • java7
  • PrimeFaces 5.1
  • OmniFaces 2.0.

I will try to run it on a newer WildFly tomorrow or just try to update to the latest Mojarra (maybe in a clean Tomcat or whatever).

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
  • I can't understand your example! in your taglib example which contains only `model` where is the associated component to your tag handler? how JSF will now that `model` is associated to the `Input` component? – Tarik Feb 21 '15 at 22:56
  • There is no relation between the input an model. One is a component (Input) the other a taghandeler (model). The model tagHandler wil not even be used in the input at all, no no relation whatsoever – Kukeltje Feb 21 '15 at 23:01
  • Ok I thought it's the Tag handler of your custom component! Any way, IMO this is hapening because the namespace is unique, so when you use the same in you taglib file I think you are erasing the first one, try to work with two different namespaces – Tarik Feb 21 '15 at 23:50
  • Yes,the identical namespace plays a role, but creating a different namespace is out of the question. This would meen the xforms standard needs to change. I don't think they will do that for a jsf glitch. Imo it isa glitch since I read somewhere that adding a tag element takes precedence over the annotation. Fine, but ommitting a tag but having a taglib yet no tag overrides **all** annotations. I would have expected them to be merged – Kukeltje Feb 22 '15 at 00:22
  • Yes that would be good, but I don't think that it's the case while talking about the uniqueness of the namespace. Meanwhile, could this Q&A help you ? http://stackoverflow.com/questions/22247914/change-composite-components-namespace/22248772#22248772 – Tarik Feb 22 '15 at 00:42
  • The namespace is part of the component, so if the namespace does not match, the overriding is not applicable at all and you just have two components. And no, the Q&A does not add anything, since I already described I could 'correct' it this way. The currently is not a non correctable issue but just a weird behaviour that is unexpected but also not explained by the specs – Kukeltje Feb 22 '15 at 00:48
  • 3
    Reproduced. Problem is not the taghandler (taglib file can be kept empty). Problem is actually the taglib.xml file itself which is registered on the same namespace. Thing works fine in MyFaces. – BalusC Feb 23 '15 at 08:20
  • @BalusC: Ok, I did indeed not think the taghandler itself was the problem, but the namespace. I did just not try with an empty taglib with just the namespace. I'll file an 'issue' with mojarra then after trying the latest (or did you?) and thanks for trying myfaces, appreciated – Kukeltje Feb 23 '15 at 09:03
  • Running into the same problem with Mojarra, and assuming you opened an issue, could you link it here or in the question? – Stephan Jul 10 '15 at 08:55
  • Sorry, I did not create an issue. I switched to using 'full' components for different reasons. No time the coming weekend to do this. – Kukeltje Jul 10 '15 at 09:01
  • Created a spec issue to define the behaviour: https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1410. If that is accepted, then I'd imagine an implementation issue would follow. – Barney Nov 04 '15 at 03:41
  • Issues have been migrated. Issue from the previous comment is in https://github.com/javaee/javaserverfaces-spec/issues/1410 (issue still 'open') – Kukeltje Dec 27 '17 at 14:22

0 Answers0