Hi

Use the standard vdl.createComponent(...) included since JSF 2.2. It has
the necessary code to do the trick properly. Please note in Myfaces this
method has been extend to support facelet tags too. It should work with the
view pool.

regards

Leonardo Uribe
On Jun 4, 2014 12:37 PM, "l.pe...@senat.fr" <l.pe...@senat.fr> wrote:

> Dear all,
>
> I am doing something dirty in my code. I dynamically instantiate and add
> tag components to my component tree, according to some information that I
> have at runtime.
>
> My instantiation method looks like :
>
>     public static UIComponent instantiateTagComponent(Location loc,
> String namespace, String localPrefix, String componentName,
> TagComponentParam params[]) {
>         final String ERROR_MESSAGE = "Erreur lors de l'instanciation d'un
> tag component";
>         FacesContext ctx = FacesContext.getCurrentInstance();
>         AbstractFaceletContext fctx = (AbstractFaceletContext)
> ctx.getAttributes().get(FaceletContext.FACELET_CONTEXT_KEY);
>         fctx.pushPageContext(new PageContextImpl());
>
>         FaceletViewDeclarationLanguage vdl = new
> FaceletViewDeclarationLanguage(ctx);
>
>         UIPanel panel = (UIPanel) ctx.getApplication().createComponent(
> UIPanel.COMPONENT_TYPE );
>
>         try {
>             Method createCompiler = FaceletViewDeclarationLanguage
> .class.getDeclaredMethod("createCompiler",FacesContext.class);
>             Method createFaceletFactory = FaceletViewDeclarationLanguage
> .class.getDeclaredMethod("createFaceletFactory",
> FacesContext.class,org.apache.myfaces.view.facelets.
> compiler.Compiler.class);
>             createCompiler.setAccessible(true);
>             createFaceletFactory.setAccessible(true);
>             org.apache.myfaces.view.facelets.compiler.Compiler compiler =
> (org.apache.myfaces.view.facelets.compiler.Compiler)
> createCompiler.invoke(vdl, ctx);
>             FaceletFactory ff = (FaceletFactory)
> createFaceletFactory.invoke(vdl, ctx, compiler);
>             TagLibrary tl = compiler.createTagLibrary();
>             TagConfig tc = new JSFUtilsTagUnit(tl, namespace, localPrefix,
> componentName,params,loc);
>             TagHandler th = tl.createTagHandler(namespace, componentName,
> tc);
>             Field declaredField = FaceletCompositionContext.
> class.getDeclaredField("FACELET_COMPOSITION_CONTEXT_KEY");
>             declaredField.setAccessible(true);
>             FaceletCompositionContextImpl faceletCompositionContextImpl =
> new FaceletCompositionContextImpl(ff,ctx);
>             Class<?> dfcClass = Class.forName("org.apache.
> myfaces.view.facelets.impl.DefaultFaceletContext");
>             Field fMCTX = dfcClass.getDeclaredField("_mctx");
>             fMCTX.setAccessible(true);
>             fMCTX.set(fctx, faceletCompositionContextImpl);
> FacesContext.getCurrentInstance().getAttributes().put((String)
> declaredField.get(null),faceletCompositionContextImpl);
>             FaceletCompositionContext mctx = (FaceletCompositionContext)
> FaceletCompositionContext.getCurrentInstance(fctx);
>             mctx.startComponentUniqueIdSection();
>             th.apply( fctx, panel );
>         } catch (IOException ex) {
>             log.error(ERROR_MESSAGE, ex);
>         } catch (InvocationTargetException ex) {
>             log.error(ERROR_MESSAGE, ex);
>         } catch (NoSuchMethodException ex) {
>             log.error(ERROR_MESSAGE, ex);
>         } catch (NoSuchFieldException ex) {
>             log.error(ERROR_MESSAGE, ex);
>         } catch (SecurityException ex) {
>             log.error(ERROR_MESSAGE, ex);
>         } catch (ClassNotFoundException ex) {
>             log.error(ERROR_MESSAGE, ex);
>         } catch (IllegalArgumentException ex) {
>             log.error(ERROR_MESSAGE, ex);
>         } catch (IllegalAccessException ex) {
>             log.error(ERROR_MESSAGE, ex);
>         }
>         finally {
>             fctx.popPageContext();
>         }
>         return panel;
>     }
>
> This is dirty, but this perfectly works for quite some time now, at least
> until I stick to
>
>     <context-param>
> <param-name>org.apache.myfaces.CACHE_EL_EXPRESSIONS</param-name>
>         <param-value>strict</param-value>
>     </context-param>
>
>
> if I change it to alwaysRecompile, the state is "not properly restored"
> and I end with and NPE like :
>
> 04/06/2014 12:29:41 ERROR [http-bio-8443-exec-56] - Exception occur!
> java.lang.NullPointerException
>     at org.apache.myfaces.view.facelets.el.FaceletStateValueExpression.
> getValue(FaceletStateValueExpression.java:107)
>     at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:68)
>     at org.apache.el.ValueExpressionImpl.getValue(
> ValueExpressionImpl.java:185)
>     at org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression
> .getValue(ContextAwareTagValueExpression.java:96)
>     at javax.faces.component._DeltaStateHelper.eval(_
> DeltaStateHelper.java:360)
>     at javax.faces.component.UIParameter.getValue(UIParameter.java:85)
>     at org.apache.myfaces.shared.renderkit.html.HtmlLinkRendererBase.
> addChildParametersToHref(HtmlLinkRendererBase.java:762)
>     at org.apache.myfaces.shared.renderkit.html.HtmlLinkRendererBase.
> renderOutputLinkStart(HtmlLinkRendererBase.java:861)
>     at org.apache.myfaces.shared.renderkit.html.HtmlLinkRendererBase.
> encodeBegin(HtmlLinkRendererBase.java:144)
>     at javax.faces.component.UIComponentBase.encodeBegin(
> UIComponentBase.java:596)
>     at javax.faces.component.UIComponentBase.encodeAll(
> UIComponentBase.java:526)
>     at org.primefaces.component.panelgrid.PanelGridRenderer.
> encodeDynamicBody(PanelGridRenderer.java:89)
>     at org.primefaces.component.panelgrid.PanelGridRenderer.
> encodeBody(PanelGridRenderer.java:60)
>     at org.primefaces.component.panelgrid.PanelGridRenderer.
> encodeEnd(PanelGridRenderer.java:49)
>     at javax.faces.component.UIComponentBase.encodeEnd(
> UIComponentBase.java:674)
>     at javax.faces.component.UIComponentBase.encodeAll(
> UIComponentBase.java:554)
>     at javax.faces.component.UIComponentBase.encodeAll(
> UIComponentBase.java:550)
>     at javax.faces.component.UIComponentBase.encodeChildren(
> UIComponentBase.java:635)
>     at javax.faces.component.UIComponentBase.encodeAll(
> UIComponentBase.java:541)
>     at org.primefaces.component.datatable.DataTableRenderer.
> encodeCell(DataTableRenderer.java:963)
>     at org.primefaces.component.datatable.DataTableRenderer.
> encodeRow(DataTableRenderer.java:923)
>     at org.primefaces.component.datatable.DataTableRenderer.
> encodeRows(DataTableRenderer.java:834)
>     at org.primefaces.component.datatable.DataTableRenderer.
> encodeTbody(DataTableRenderer.java:781)
>     at org.primefaces.component.datatable.DataTableRenderer.
> encodeTbody(DataTableRenderer.java:744)
>     at org.primefaces.component.datatable.feature.FilterFeature.encode(
> FilterFeature.java:119)
>     at org.primefaces.component.datatable.DataTableRenderer.
> encodeEnd(DataTableRenderer.java:77)
>     at javax.faces.component.UIComponentBase.encodeEnd(
> UIComponentBase.java:674)
>     at javax.faces.component.UIData.encodeEnd(UIData.java:1721)
>     at javax.faces.component.UIComponentBase.encodeAll(
> UIComponentBase.java:554)
>     at org.apache.myfaces.context.servlet.PartialViewContextImpl$
> PhaseAwareVisitCallback.processRenderComponent(
> PartialViewContextImpl.java:823)
>     at org.apache.myfaces.context.servlet.PartialViewContextImpl$
> PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:784)
>     at org.apache.myfaces.component.visit.PartialVisitContext.
> invokeVisitCallback(PartialVisitContext.java:213)
>     at org.primefaces.component.api.UIData.visitTree(UIData.java:692)
>     at fr.senat.faces.components.SenatDataTableCtrl.visitTree(
> SenatDataTableCtrl.java:239)
>     at javax.faces.component.UIComponent.visitTree(UIComponent.java:1032)
>     at javax.faces.component.UIComponentBase.visitTree(
> UIComponentBase.java:1191)
>     at javax.faces.component.UIForm.visitTree(UIForm.java:345)
>     at javax.faces.component.UIComponent.visitTree(UIComponent.java:1032)
>     at javax.faces.component.UIComponentBase.visitTree(
> UIComponentBase.java:1191)
>     at javax.faces.component.UIComponent.visitTree(UIComponent.java:1032)
>     at javax.faces.component.UIComponentBase.visitTree(
> UIComponentBase.java:1191)
>     at org.apache.myfaces.context.servlet.PartialViewContextImpl.
> processPartialRendering(PartialViewContextImpl.java:536)
>     at org.apache.myfaces.context.servlet.PartialViewContextImpl.
> processPartial(PartialViewContextImpl.java:415)
>     at org.primefaces.context.PrimePartialViewContext.processPartial(
> PrimePartialViewContext.java:60)
>     at javax.faces.context.PartialViewContextWrapper.processPartial(
> PartialViewContextWrapper.java:85)
>     at javax.faces.component.UIViewRoot.encodeChildren(
> UIViewRoot.java:516)
>     at javax.faces.component.UIComponentBase.encodeAll(
> UIComponentBase.java:541)
>     at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage
> .renderView(FaceletViewDeclarationLanguage.java:1891)
>     at org.apache.myfaces.application.ViewHandlerImpl.
> renderView(ViewHandlerImpl.java:313)
>     at javax.faces.application.ViewHandlerWrapper.renderView(
> ViewHandlerWrapper.java:57)
>     at javax.faces.application.ViewHandlerWrapper.renderView(
> ViewHandlerWrapper.java:57)
>     at javax.faces.application.ViewHandlerWrapper.renderView(
> ViewHandlerWrapper.java:57)
>     at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(
> RenderResponseExecutor.java:116)
>     at org.apache.myfaces.lifecycle.LifecycleImpl.render(
> LifecycleImpl.java:267)
>     at org.apache.deltaspike.jsf.impl.listener.request.
> DeltaSpikeLifecycleWrapper.render(DeltaSpikeLifecycleWrapper.java:111)
>     at javax.faces.lifecycle.LifecycleWrapper.render(
> LifecycleWrapper.java:31)
>     at javax.faces.webapp.FacesServlet.service(FacesServlet.java:200)
>     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
> ApplicationFilterChain.java:305)
>     at org.apache.catalina.core.ApplicationFilterChain.doFilter(
> ApplicationFilterChain.java:210)
>     at fr.senat.faces.filters.HibernateNoCacheFilter.doFilter(
> HibernateNoCacheFilter.java:123)
>     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
> ApplicationFilterChain.java:243)
>     at org.apache.catalina.core.ApplicationFilterChain.doFilter(
> ApplicationFilterChain.java:210)
>     at fr.senat.faces.filters.HibernateSessionConversationFilter.doFilter(
> HibernateSessionConversationFilter.java:128)
>     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
> ApplicationFilterChain.java:243)
>     at org.apache.catalina.core.ApplicationFilterChain.doFilter(
> ApplicationFilterChain.java:210)
>     at fr.senat.faces.filters.HibernateUserFromPrincipalFilter.doFilter(
> HibernateUserFromPrincipalFilter.java:43)
>     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
> ApplicationFilterChain.java:243)
>     at org.apache.catalina.core.ApplicationFilterChain.doFilter(
> ApplicationFilterChain.java:210)
>     at fr.senat.faces.filters.SessionCreationTrackingFilter.doFilter(
> SessionCreationTrackingFilter.java:48)
>     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(
> ApplicationFilterChain.java:243)
>     at org.apache.catalina.core.ApplicationFilterChain.doFilter(
> ApplicationFilterChain.java:210)
>     at org.apache.catalina.core.StandardWrapperValve.invoke(
> StandardWrapperValve.java:222)
>     at org.apache.catalina.core.StandardContextValve.invoke(
> StandardContextValve.java:123)
>     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(
> AuthenticatorBase.java:581)
>     at org.apache.catalina.core.StandardHostValve.invoke(
> StandardHostValve.java:171)
>     at org.apache.catalina.valves.ErrorReportValve.invoke(
> ErrorReportValve.java:99)
>     at org.apache.catalina.valves.AccessLogValve.invoke(
> AccessLogValve.java:947)
>     at org.apache.catalina.core.StandardEngineValve.invoke(
> StandardEngineValve.java:118)
>     at org.apache.catalina.connector.CoyoteAdapter.service(
> CoyoteAdapter.java:408)
>     at org.apache.coyote.http11.AbstractHttp11Processor.process(
> AbstractHttp11Processor.java:1009)
>     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.
> process(AbstractProtocol.java:589)
>     at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.
> run(JIoEndpoint.java:312)
>     at java.util.concurrent.ThreadPoolExecutor.runWorker(
> ThreadPoolExecutor.java:1145)
>     at java.util.concurrent.ThreadPoolExecutor$Worker.run(
> ThreadPoolExecutor.java:615)
>     at java.lang.Thread.run(Thread.java:744)
>
> In this case, the tag file is :
>
> <html
>       xmlns="http://www.w3.org/1999/xhtml";
>       xmlns:h="http://java.sun.com/jsf/html";
>       xmlns:f="http://java.sun.com/jsf/core";
>       xmlns:ui="http://java.sun.com/jsf/facelets";
>       xmlns:p="http://primefaces.org/ui";
>       xmlns:sc="http://www.senat.fr/taglib/sencommons";
>       xmlns:sf="http://www.senat.fr/taglib/senfunctions";>
>     <p:panelGrid columns="3" rendered="#{empty rendered or rendered}">
>         <h:outputLink value="#{facesContext.externalContext.
> requestContextPath}/elections/rapportElections">
>             <f:param name="code" value="#{circonum}"/>
>             <f:param name="format" value="pdf"/>
>             <f:param name="phase" value="#{phase}"/>
>             <p:graphicImage value="#{resource['pdf_petit.png']}"
> alt="PDF" title="PDF"/>
>         </h:outputLink>
>
>         <h:outputLink value="#{facesContext.externalContext.
> requestContextPath}/elections/rapportElections">
>             <f:param name="code" value="#{circonum}"/>
>             <f:param name="format" value="docx"/>
>             <f:param name="phase" value="#{phase}"/>
>             <p:graphicImage value="#{resource['word_petit.png']}"
> alt="DOCX (Word)" title="DOCX (Word)"/>
>         </h:outputLink>
>
>         <h:outputLink value="#{facesContext.externalContext.
> requestContextPath}/elections/rapportElections">
>             <f:param name="code" value="#{circonum}"/>
>             <f:param name="format" value="rtf"/>
>             <f:param name="phase" value="#{phase}"/>
>             <p:graphicImage value="#{resource['rtf_petit.png']}"
> alt="RTF" title="RTF"/>
>         </h:outputLink>
>     </p:panelGrid>
> </html>
>
> And the exception is raised when the #{circonum} parameter is evaluated.
>
> In FaceletStateValueExpression#getWrapped, line 73 :
>
> root.getAttributes().get(ComponentSupport.FACELET_STATE_INSTANCE);
>
> returns null, thus the NPE
>
> I know I do dirty things and understand that you have to cleaner things to
> do, but if one of the guru of this list could drop and eye and give me a
> hint on what to add...
>
> My apps work fine with org.apache.myfaces.CACHE_EL_EXPRESSIONS=strict,
> but alwaysRecompile is required to enable view pooling, and I would like to
> enable this.
>
> Thanks in advance,
>
> Ludovic
> |
> | AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT.
> |
>
>

Reply via email to