0

I am trying to upgrade/use a custom converter that worked with JSF 2.2 (on Wildfly 13) to work on JSF 2.3 (with Mojarra 2.3.9.SP02 running on Wildfly 17.0.1)

The converter is used via its own tag defined in a tag library. Everything's fine as long as no tag attributes are used. The attributes are just not set in the converter. The setters never get called. But if I remove the managed = true from the converter the attributes are set but then the injection no longer works.

The converter is used like this:

<h:inputText id="text" value="#{welcome.text}">
    <cdijsf:converterWithAttr id="myConverter" attr="myAttrValue" />
</h:inputText>

Tag library:

<facelet-taglib version="2.3"
        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_3.xsd">
    <namespace>http://cdijsf.transdata.net/jsf</namespace>
    <tag>
        <tag-name>converterWithAttr</tag-name>
        <converter>
            <converter-id>cdijsf.ConverterWithAttr</converter-id>
        </converter>
        <attribute>
            <name>attr</name>
            <type>java.lang.String</type>
        </attribute>
    </tag>
</facelet-taglib>

And this is the converter code:

@Dependent
@FacesConverter(value = "cdijsf.ConverterWithAttr", managed = true)
public class ConverterWithAttr implements Converter<String> {

    @Inject
    private BeanManager beanManager;

    private String attr;

    public ConverterWithAttr() {
    }

    @PostConstruct
    private void init() {
      // If 'managed = true' beanManager is injected at this point.
      // If 'managed = false' beanManager is null at this point
    }

    @Override
    public String getAsObject(FacesContext context, UIComponent component, String value) {
        return value;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, String value) {
        return value;
    }

    public String getAttr() {
        return attr;
    }

    public void setAttr(String attr) {
        // If 'managed = true' setAttr is never called
        // If 'managed = false' setAttr is called
        this.attr = attr;
    }

}

faces-config.xml:

<faces-config version="2.3"
        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_3.xsd">
</faces-config>

And I also explicitly declare JSF 2.3 like this:

@FacesConfig(version = Version.JSF_2_3)
@ApplicationScoped
public class JsfConfiguration {

}

beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_2_0.xsd"
    version="2.0"
    bean-discovery-mode="annotated">
</beans>
Kukeltje
  • 12,223
  • 4
  • 24
  • 47
  • And as I am in the process of migrating my application from Wildfly 13 / JSF 2.2 to Wildfly 17 / JSF 2.3 the converter was working at least with JSF 2.2 and Wildfly 13. For Wildfly 11 I can't say. – Heiko Tappe Aug 19 '19 at 08:01
  • For the converter code: I'd say it looks pretty straight forward, don't you think? Do you have some converter code I can compare it to? – Heiko Tappe Aug 19 '19 at 08:01
  • I personally don't have any code for custom converters via tags (I use id's), but JSF itself has converters as does Omnifaces. Both of which the source is open. Omnifaces does not seem to use the taglib file, but has created a taghandler for the converters: https://github.com/omnifaces/omnifaces/blob/3.x/src/main/java/org/omnifaces/taghandler/Converter.java https://github.com/omnifaces/omnifaces/blob/3.x/src/main/java/org/omnifaces/converter/TrimConverter.java – Kukeltje Aug 19 '19 at 08:21
  • Yes, the taglib is picked up and the converter is used (getAsString and getAsObject are called). It's just that the setter of the attribute is never called. So attribute is always 'null'. – Heiko Tappe Aug 19 '19 at 08:34
  • Good shot. Yes, removing managed=true did the trick. But then injection for instance no longer works. Can't I have both? – Heiko Tappe Aug 19 '19 at 08:58
  • You need the converter to be injected somewhere? Since that is what `managed=true` enables if I read the specs correctly – Kukeltje Aug 19 '19 at 09:15
  • Yeah, sorry for not being exact enough in what I was saying. Fact is in JSF 2.2 it was possible for me to have a converter defined in a tag lib with attributes that was injection capable. Now trying to migrate to JSF 2.3 this doesn't seem to work any more. And the last couple of days googling for solutions didn't help. So I ended up asking for help here. – Heiko Tappe Aug 19 '19 at 09:16
  • No. I do not need the converter to be injected somewhere. I only need some injected fields inside the converter. – Heiko Tappe Aug 19 '19 at 09:18
  • That should work without `managed=true` if I read things correctly. What if you also remove the `@Dependent` – Kukeltje Aug 19 '19 at 09:22
  • Removing `@Dependent` unfortunately does not help either. – Heiko Tappe Aug 19 '19 at 09:33
  • Its Mojarra 2.3.9.SP02 – Heiko Tappe Aug 19 '19 at 09:45
  • And I added my faces-config.xml – Heiko Tappe Aug 19 '19 at 09:46
  • And what if you do https://stackoverflow.com/questions/52511992/injection-in-a-converter-does-not-work-in-jsf-2-3 – Kukeltje Aug 19 '19 at 10:02
  • I edited title and introduction. Better? – Heiko Tappe Aug 19 '19 at 10:39
  • Yes, I changed some little things though and removed a lot of my comments (that are you in the question – Kukeltje Aug 19 '19 at 10:47
  • The problem might be related/similar to what is described [here](http://showcase.omnifaces.org/taghandlers/converter): In managed mode a wrapper converter (CdiConverter) is created and delegates to the original converter (here: ConverterWithAttr). But the wrapper converter is missing the attribute. – Heiko Tappe Aug 19 '19 at 12:22
  • Yes, that is where I got my info from too (and the source), but it also states in other places that this `managed=true` makes the beans injectible in targets, not being the target of injections. The latter should just work without the `managed=true in my opinion otherwise it breaks backwardscompatibility in a major way – Kukeltje Aug 19 '19 at 13:10

0 Answers0