MyFaces Core
  1. MyFaces Core
  2. MYFACES-2573

NavigationHandler decoration/delegation not supported in 2.0.0-beta2

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: 2.0.0-beta-2
    • Fix Version/s: 2.0.0-beta-3
    • Component/s: JSR-314
    • Labels:
      None
    • Environment:
      PrettyFaces 2.0.4, Jetty

      Description

      http://code.google.com/p/prettyfaces/issues/detail?id=28

      Section 11.4.6 of the JSF spec states that when delegating NavigationHandler, it should accept (as a constructor parameter) the parent NavigationHandler to be decorated. This is no longer working in MyFaces 2.0.0-x.

      SEVERE: com.ocpsoft.pretty.faces.application.PrettyNavigationHandler
      java.lang.InstantiationException: com.ocpsoft.pretty.faces.application.PrettyNavigationHandler
      at java.lang.Class.newInstance0(Class.java:340)
      at java.lang.Class.newInstance(Class.java:308)
      at org.apache.myfaces.shared_impl.util.ClassUtils.newInstance(ClassUtils.java:343)
      at org.apache.myfaces.config.FacesConfigurator.getApplicationObject(FacesConfigurator.java:2094)
      at org.apache.myfaces.config.FacesConfigurator.configureApplication(FacesConfigurator.java:1871)
      at org.apache.myfaces.config.FacesConfigurator.configure(FacesConfigurator.java:515)
      at org.apache.myfaces.webapp.AbstractFacesInitializer.buildConfiguration(AbstractFacesInitializer.java:203)
      at org.apache.myfaces.webapp.Jsp21FacesInitializer.initContainerIntegration(Jsp21FacesInitializer.java:73)
      at org.apache.myfaces.webapp.AbstractFacesInitializer.initFaces(AbstractFacesInitializer.java:99)
      at org.apache.myfaces.webapp.StartupServletContextListener.contextInitialized(StartupServletContextListener.java:155)
      at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:645)
      at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:189)
      at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:978)
      at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:586)
      at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:349)
      at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:102)
      at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
      at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
      at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:162)
      at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
      at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
      at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
      at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:92)
      at org.eclipse.jetty.server.Server.doStart(Server.java:228)
      at org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:69)
      at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
      at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:433)
      at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:377)
      at org.mortbay.jetty.plugin.JettyRunWarMojo.execute(JettyRunWarMojo.java:68)
      at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:569)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:539)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
      at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
      at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
      at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
      at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
      at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
      at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
      at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
      Feb 22, 2010 11:15:56 PM org.apache.myfaces.webapp.AbstractFacesInitializer initFaces
      SEVERE: An error occured while initializing MyFaces: java.lang.InstantiationException: com.ocpsoft.pretty.faces.application.PrettyNavigationHandler
      javax.faces.FacesException: java.lang.InstantiationException: com.ocpsoft.pretty.faces.application.PrettyNavigationHandler
      at org.apache.myfaces.shared_impl.util.ClassUtils.newInstance(ClassUtils.java:353)
      at org.apache.myfaces.config.FacesConfigurator.getApplicationObject(FacesConfigurator.java:2094)
      at org.apache.myfaces.config.FacesConfigurator.configureApplication(FacesConfigurator.java:1871)
      at org.apache.myfaces.config.FacesConfigurator.configure(FacesConfigurator.java:515)
      at org.apache.myfaces.webapp.AbstractFacesInitializer.buildConfiguration(AbstractFacesInitializer.java:203)
      at org.apache.myfaces.webapp.Jsp21FacesInitializer.initContainerIntegration(Jsp21FacesInitializer.java:73)
      at org.apache.myfaces.webapp.AbstractFacesInitializer.initFaces(AbstractFacesInitializer.java:99)
      at org.apache.myfaces.webapp.StartupServletContextListener.contextInitialized(StartupServletContextListener.java:155)
      at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:645)
      at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:189)
      at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:978)
      at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:586)
      at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:349)
      at org.mortbay.jetty.plugin.JettyWebAppContext.doStart(JettyWebAppContext.java:102)
      at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
      at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
      at org.eclipse.jetty.server.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:162)
      at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
      at org.eclipse.jetty.server.handler.HandlerCollection.doStart(HandlerCollection.java:165)
      at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
      at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:92)
      at org.eclipse.jetty.server.Server.doStart(Server.java:228)
      at org.mortbay.jetty.plugin.JettyServer.doStart(JettyServer.java:69)
      at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:55)
      at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:433)
      at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:377)
      at org.mortbay.jetty.plugin.JettyRunWarMojo.execute(JettyRunWarMojo.java:68)
      at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:490)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:694)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:569)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:539)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:387)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:348)
      at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:180)
      at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
      at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
      at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
      at org.apache.maven.cli.compat.CompatibleMain.main(CompatibleMain.java:60)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
      at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
      at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
      at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
      Caused by: java.lang.InstantiationException: com.ocpsoft.pretty.faces.application.PrettyNavigationHandler
      at java.lang.Class.newInstance0(Class.java:340)
      at java.lang.Class.newInstance(Class.java:308)
      at org.apache.myfaces.shared_impl.util.ClassUtils.newInstance(ClassUtils.java:343)
      ... 45 more

        Activity

        Hide
        Jakob Korherr added a comment -

        Are you using some kind of ording in your faces-config files? Because if the faces-config file, which adds your NavigationHandler is the first one that gets loaded (also before the myfaces' standard-faces-config.xml) you will surely run into this problem, because there is no NavigationHandler implementation installed yet which could be wrapped.

        Otherwise it does work - I just tried it!

        Show
        Jakob Korherr added a comment - Are you using some kind of ording in your faces-config files? Because if the faces-config file, which adds your NavigationHandler is the first one that gets loaded (also before the myfaces' standard-faces-config.xml) you will surely run into this problem, because there is no NavigationHandler implementation installed yet which could be wrapped. Otherwise it does work - I just tried it!
        Hide
        Lincoln Baxter III added a comment -

        No, there is no special ordering. I've also just verified this again personally on Tomcat 6. This functions just fine when using Mojarra.

        PrettyFaces bundles its own faces-config.xml file, however:

        <?xml version="1.0" encoding="UTF-8"?>

        <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_0.xsd"
        version="2.0">

        <name>ocpsoft_pretty_faces</name>

        <application>
        <view-handler>com.ocpsoft.pretty.faces.application.PrettyViewHandler</view-handler>
        <navigation-handler>com.ocpsoft.pretty.faces.application.PrettyNavigationHandler</navigation-handler>
        </application>
        <lifecycle>
        <phase-listener>com.ocpsoft.pretty.faces.event.PrettyPhaseListener</phase-listener>
        </lifecycle>

        <component>
        <component-type>
        com.ocpsoft.pretty.Link
        </component-type>
        <component-class>
        com.ocpsoft.pretty.faces.component.Link
        </component-class>
        </component>
        <component>
        <component-type>
        com.ocpsoft.pretty.UrlBuffer
        </component-type>
        <component-class>
        com.ocpsoft.pretty.faces.component.UrlBuffer
        </component-class>
        </component>

        <render-kit>
        <renderer>
        <description>
        Renderer for the pretty link component.
        </description>
        <component-family>
        PRETTY_FACES_FAMILY
        </component-family>
        <renderer-type>
        javax.faces.Link
        </renderer-type>
        <renderer-class>
        com.ocpsoft.pretty.faces.component.renderer.LinkRenderer
        </renderer-class>
        </renderer>
        <renderer>
        <description>
        Renderer for the pretty urlbuffer component.
        </description>
        <component-family>
        PRETTY_FACES_FAMILY
        </component-family>
        <renderer-type>
        com.ocpsoft.pretty.UrlBuffer
        </renderer-type>
        <renderer-class>
        com.ocpsoft.pretty.faces.component.renderer.UrlBufferRenderer
        </renderer-class>
        </renderer>
        </render-kit>
        </faces-config>

        Show
        Lincoln Baxter III added a comment - No, there is no special ordering. I've also just verified this again personally on Tomcat 6. This functions just fine when using Mojarra. PrettyFaces bundles its own faces-config.xml file, however: <?xml version="1.0" encoding="UTF-8"?> <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_0.xsd " version="2.0"> <name>ocpsoft_pretty_faces</name> <application> <view-handler>com.ocpsoft.pretty.faces.application.PrettyViewHandler</view-handler> <navigation-handler>com.ocpsoft.pretty.faces.application.PrettyNavigationHandler</navigation-handler> </application> <lifecycle> <phase-listener>com.ocpsoft.pretty.faces.event.PrettyPhaseListener</phase-listener> </lifecycle> <component> <component-type> com.ocpsoft.pretty.Link </component-type> <component-class> com.ocpsoft.pretty.faces.component.Link </component-class> </component> <component> <component-type> com.ocpsoft.pretty.UrlBuffer </component-type> <component-class> com.ocpsoft.pretty.faces.component.UrlBuffer </component-class> </component> <render-kit> <renderer> <description> Renderer for the pretty link component. </description> <component-family> PRETTY_FACES_FAMILY </component-family> <renderer-type> javax.faces.Link </renderer-type> <renderer-class> com.ocpsoft.pretty.faces.component.renderer.LinkRenderer </renderer-class> </renderer> <renderer> <description> Renderer for the pretty urlbuffer component. </description> <component-family> PRETTY_FACES_FAMILY </component-family> <renderer-type> com.ocpsoft.pretty.UrlBuffer </renderer-type> <renderer-class> com.ocpsoft.pretty.faces.component.renderer.UrlBufferRenderer </renderer-class> </renderer> </render-kit> </faces-config>
        Hide
        Lincoln Baxter III added a comment -

        Have you tested decoration for ConfigurableNavigationHandler s? MyFaces is looking for a constructor with navhandler type NavigationHandler, but all NavigationHandlers in JSF2 are required to extend ConfigurableNavigationHandler.

        Decorating with NavigationHandler in the constructor is fine, but with ConfigurableNavigationHandler we get the exception.

        Show
        Lincoln Baxter III added a comment - Have you tested decoration for ConfigurableNavigationHandler s? MyFaces is looking for a constructor with navhandler type NavigationHandler, but all NavigationHandlers in JSF2 are required to extend ConfigurableNavigationHandler. Decorating with NavigationHandler in the constructor is fine, but with ConfigurableNavigationHandler we get the exception.
        Hide
        Jakob Korherr added a comment -

        So after thinking about this problem more in detail and after the discussion we had yesterday at the jsfdays, I'll sum up the outcome here:

        The problem is that the JSF 2.0 spec says that the internal NavigationHandler implementation should inherit ConfigurableNavigationHandler (which adds two additional methods to NavigationHandler) instead of NavigationHandler directly. So the pretty faces implementation expected a ConfigurableNavigationHandler in their custom NavigationHandler constructor to wrap the original NavigationHandler. This would only cause a small change on MyFaces to support this, but it comes with several problems: At first we would not be backwards compatible anymore, because this new fact is not true for JSF 1.x applications, so you would not be able to use a JSF 1.x NavigationHandler implementation. Of course we could easily solve this by allowing both constructors, the one that gets a ConfigurableNavigationHandler and the one that only gets a normal (JSF 1.x) NavigationHandler. However this opens another problem: When mixing more than two JSF 1.x and JSF 2.0 NavigationHandlers you will run into problems. Imagine the following scenario: the MyFaces NavigationHandler implementation (ConfigurableNavigationHandler) is wrapped by a JSF 1.x NavigationHandler which itself should again be wrapped in a NavigationHandler with a ConfigurableNavigationHandler-constructor, but there you only have a "normal" NavigationHandler (the JSF 1.x one) and not a ConfigurableNavigationHandler to provide to the constructor. Thus we have to do an implicit wrapping here.

        The discussed solution is to support both constructors and to wrap any NavigationHandlers which are no ConfigurableNavigationHandlers in a "double wrapper" ConfigurableNavigationHandler implementation, which wraps a ConfigurableNavigationHandler (the last one on the NavigationHandler chain) and a NavigationHandler and delegates handleNavigation() to the NavigationHandler and the other two methos to the ConfigurableNavigationHandler. This will work in all possible scenarios and you can always expect a ConfigurableNavigationHandler when getting the NavigationHandler from the Application object.

        Show
        Jakob Korherr added a comment - So after thinking about this problem more in detail and after the discussion we had yesterday at the jsfdays, I'll sum up the outcome here: The problem is that the JSF 2.0 spec says that the internal NavigationHandler implementation should inherit ConfigurableNavigationHandler (which adds two additional methods to NavigationHandler) instead of NavigationHandler directly. So the pretty faces implementation expected a ConfigurableNavigationHandler in their custom NavigationHandler constructor to wrap the original NavigationHandler. This would only cause a small change on MyFaces to support this, but it comes with several problems: At first we would not be backwards compatible anymore, because this new fact is not true for JSF 1.x applications, so you would not be able to use a JSF 1.x NavigationHandler implementation. Of course we could easily solve this by allowing both constructors, the one that gets a ConfigurableNavigationHandler and the one that only gets a normal (JSF 1.x) NavigationHandler. However this opens another problem: When mixing more than two JSF 1.x and JSF 2.0 NavigationHandlers you will run into problems. Imagine the following scenario: the MyFaces NavigationHandler implementation (ConfigurableNavigationHandler) is wrapped by a JSF 1.x NavigationHandler which itself should again be wrapped in a NavigationHandler with a ConfigurableNavigationHandler-constructor, but there you only have a "normal" NavigationHandler (the JSF 1.x one) and not a ConfigurableNavigationHandler to provide to the constructor. Thus we have to do an implicit wrapping here. The discussed solution is to support both constructors and to wrap any NavigationHandlers which are no ConfigurableNavigationHandlers in a "double wrapper" ConfigurableNavigationHandler implementation, which wraps a ConfigurableNavigationHandler (the last one on the NavigationHandler chain) and a NavigationHandler and delegates handleNavigation() to the NavigationHandler and the other two methos to the ConfigurableNavigationHandler. This will work in all possible scenarios and you can always expect a ConfigurableNavigationHandler when getting the NavigationHandler from the Application object.
        Hide
        Matthias Weßendorf added a comment -

        For the completeness, here is a bug that has been filed against the spec:

        https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=754

        Show
        Matthias Weßendorf added a comment - For the completeness, here is a bug that has been filed against the spec: https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=754

          People

          • Assignee:
            Jakob Korherr
            Reporter:
            Lincoln Baxter III
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development