jsfoverridingfaces-configcustom-renderer

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

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?


Solution

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