How to register JSF ExceptionHandlerFactory programmatically in Spring Boot

657 Views Asked by At

I'm using Joinfaces to build a JSF + Spring Boot application and Omnifaces is packed with it.

When the View expires and I navigate I get the ViewExpiredException. When I execute Ajax, the page does nothing and the error shows in the console.

Is it possible to register the org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory programatically with Spring, without having to add a .xml (web, faces-config) to my project?

1

There are 1 best solutions below

2
On

Use the following to set up a custom exception handler sans web.xml:

FactoryFinder.setFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY,"org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory");

The trick here is to make sure this line is executed as early in the startup as possible; once FactoryFinder.getFactory() has been called by the JSF runtime, it's too late to change the configured handler.

The good thing is that I actually can't find anywhere in the Mojarra codebase where the exception handler factory is being set by default, so you probably could execute this maybe in the constructor (not the @PostConstructor) of any @ApplicationScoped bean. You could also do it in a static initializer of the ame bean.

Additionally, you could do it in a FacesInitializer. So asssuming you're running Mojarra, you'll need to setup the handler very early on in the startup process of the servlet context

public class YourWebAppInitializer extends FacesInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext ctxt) throws ServletException {

        AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext();
        root.register(YourSpringConfigClass.class);
        ctxt.addListener(new ContextLoaderListener(root));
        FactoryFinder.setFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY,"org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory");
    }
}

The WebApplicationInitializer is a standard interface supported by Spring for bootstrapping a web application and I'm assuming you already have that in place because you don't have a web.xml - feel free to replace the contents of the onStartup method with whatever you have in your actual implementation. The key thing here is to make sure you set the factory there, which is pretty early in the startup of the application.

Also note that you can hand set the actual ExceptionHandler on any given instance of FacesContext (although I haven't tested this to see how it'll behave or whether it'll perform well)