12 Replies Latest reply on May 26, 2010 7:47 PM by Lincoln Baxter III

    AnnotationLiteral throws NPE on Glassfish v3 + SeamFaces

    Wolfgang Schwendt Newbie

      I started to evaluate Primefaces 2.0.2 together with Seamfaces 3.0.0-SNAPSHOT, running on Glassfish v3.


      For Glassfish I use the Windows-Installer distribution available at https://glassfish.dev.java.net/downloads/v3-final.html and then use the updater tool to update any modules to the most recent version available through the updater.  


      For the Glassfish package glassfish-cdi, which contains CDI/Weld, the latest version avaiblabe through the update mechanism is 3.0.1-19, packaged on 2010/05/19.   It contains


      Implementation-Title: Weld OSGi Bundle
      Built-By: janey
      Tool: Bnd-0.0.311
      Implementation-Vendor: Seam Framework
      Specification-Title: Weld OSGi Bundle
      Implementation-Version: 1.0.1.SP2
      Build-Time: May 12, 2010 11:23:40 AM PDT
      



      I use Primefaces 2.0.2 together with JSF 2.0.2-FCS Mojarra, and then everything works fine. But when I add
      I add Seamfaces 3.0.0-SNAPSHOT, I get the following NullPointerException.


      [code]
      [#|2010-05-24T11:47:02.079+0200|WARNING|glassfish3.0.1|javax.enterprise.system.container.web.com.sun.enterprise.web|_ThreadID=31;_ThreadName=http-thread-pool-8080-(1);|StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
      java.lang.NullPointerException
           at javax.enterprise.util.AnnotationLiteral.hashCode(AnnotationLiteral.java:321)
           at java.util.HashMap.getEntry(HashMap.java:344)
           at java.util.HashMap.containsKey(HashMap.java:335)
           at java.util.HashSet.contains(HashSet.java:184)
           at org.jboss.weld.resolution.ResolvableBuilder.checkQualifier(ResolvableBuilder.java:214)
           at org.jboss.weld.resolution.ResolvableBuilder.addQualifier(ResolvableBuilder.java:175)
           at org.jboss.weld.resolution.ResolvableBuilder.addQualifiers(ResolvableBuilder.java:194)
           at org.jboss.weld.manager.BeanManagerImpl.resolveObserverMethods(BeanManagerImpl.java:475)
           at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:647)
           at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:641)
           at org.jboss.seam.faces.event.SystemEventBridge.processEvent(SystemEventBridge.java:80)
           at org.jboss.seam.faces.event.DelegatingSystemEventListener.processEvent(DelegatingSystemEventListener.java:51)
           at javax.faces.event.SystemEvent.processListener(SystemEvent.java:102)
           at com.sun.faces.application.ApplicationImpl.processListeners(ApplicationImpl.java:1993)
           at com.sun.faces.application.ApplicationImpl.invokeListenersFor(ApplicationImpl.java:1969)
           at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:299)
           at com.sun.faces.application.ApplicationImpl.publishEvent(ApplicationImpl.java:243)
           at javax.faces.application.ApplicationWrapper.publishEvent(ApplicationWrapper.java:666)
           at javax.faces.application.ApplicationWrapper.publishEvent(ApplicationWrapper.java:666)
           at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1075)
           at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1080)
           at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1080)
           at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1180)
           at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
           at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
           at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
           at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
      


      Obviously, this exception is triggered by the SeamFaces-Event bridge.  With my post I'd like to ask whether this problem is already known.  Also, are there any working versions available which allow the use of Primefaces together with Seamfaces and JSF 2.0 on Glassfish v3?

        • 1. Re: AnnotationLiteral throws NPE on Glassfish v3 + SeamFaces
          Wolfgang Schwendt Newbie

          When I look at class javax.enterprise.util.AnnotationLiteral, method hashCode() (Weld API trunk SVN Rev. 6287), I do not understand the code 100% yet. But I'm wondering  (without a full understanding of the code) why value.hashCode() is called without any check whether value is null.




          package javax.enterprise.util;
          public abstract class AnnotationLiteral<T extends Annotation> 
                implements Annotation, Serializable
          {
          
             @Override
             public int hashCode()
             {
                int hashCode = 0;
                for (Method member: getMembers())
                {
                   int memberNameHashCode = 127 * member.getName().hashCode();
                   Object value = invoke(member, this);
                   int memberValueHashCode;
                   if (value instanceof boolean[])
                   {
                      memberValueHashCode = Arrays.hashCode((boolean[]) value);
                   }
                   else if (value instanceof short[])
                   {
                      memberValueHashCode = Arrays.hashCode((short[]) value);
                   }
                   else if (value instanceof int[])
                   {
                      memberValueHashCode = Arrays.hashCode((int[]) value);
                   }
                   else if (value instanceof long[])
                   {
                      memberValueHashCode = Arrays.hashCode((long[]) value);
                   }
                   else if (value instanceof float[])
                   {
                      memberValueHashCode = Arrays.hashCode((float[]) value);
                   }
                   else if (value instanceof double[])
                   {
                      memberValueHashCode = Arrays.hashCode((double[]) value);
                   }
                   else if (value instanceof byte[])
                   {
                      memberValueHashCode = Arrays.hashCode((byte[]) value);
                   }
                   else if (value instanceof char[])
                   {
                      memberValueHashCode = Arrays.hashCode((char[]) value);
                   }
                   else if (value instanceof Object[])
                   {
                      memberValueHashCode = Arrays.hashCode((Object[]) value);
                   }
                   else 
                   {
                      memberValueHashCode = value.hashCode();
                   }
                   hashCode += memberNameHashCode ^ memberValueHashCode;
                }       
                return hashCode;
             }
          

              

          • 3. Re: AnnotationLiteral throws NPE on Glassfish v3 + SeamFaces
            Wolfgang Schwendt Newbie
            many thanks Nicklas, I wasn't aware of the JIRA issue.

            While reading the JIRA-issue:  As I don't have enough knowledge about CDI/Weld internals yet, I do not understand Pete's comment "Should throw an IAE with a message about this, not just NPE". 

            Further I don't understand why the issue is just classified as "minor" and not with higher importance. As described in my first post, without this issue resolved it is not possible to use Primefaces and Seamfaces successfully together.   And that would be a pity, because CDI/Weld together with JSF 2.0 is really a nice combination, much more appealing than Spring + JSF!



            • 4. Re: AnnotationLiteral throws NPE on Glassfish v3 + SeamFaces
              Wolfgang Schwendt Newbie
              "many thanks Nicklas, I wasn't aware of the JIRA issue."

              if the creation for the JIRA issue is shown in the EST time zone rather than European time, then you filed the JIRA issue AFTER I posted here. Big thanks again.  I hope that the issue will be resolved soon because I'd love to use Java EE6 incl. CDI/Weld + JSF 2.0 + Primefaces together on Glassfish v3   (or JBoss 6, as soon as the latter runs more stably).
              • 5. Re: AnnotationLiteral throws NPE on Glassfish v3 + SeamFaces
                Nicklas Karlsson Master

                Yep, I filed it afterwards. The fix is minor so I think it will be done anyway.


                The issue should of course be fixed but I wonder if its more an issue of the literals being constructed strangely


                   private class ComponentLiteral extends AnnotationLiteral<Component> implements Component
                   {
                      private final String value;
                
                      public String value()
                      {
                         return value;
                      }
                
                      public ComponentLiteral(String value)
                      {
                         this.value = value;
                      }
                   }
                



                Wonder if we should default to ""...?

                • 6. Re: AnnotationLiteral throws NPE on Glassfish v3 + SeamFaces
                  Wolfgang Schwendt Newbie

                  Wolfgang Schwendt wrote on May 24, 2010 13:16:


                  While reading the JIRA-issue:  As I don't have enough knowledge about CDI/Weld internals yet, I do not understand Pete's comment Should throw an IAE with a message about this, not just NPE


                  Looking further at the issue I assume that it's probably actually a SeamFaces/PrimeFaces issue rather than Weld issue.


                  The open question is why the SeamFaces EventBridge creates a ComponentLiteral with value null.  It does so when the PrimeFaces Datatable is used in dynamic (ie. AJAX-based lazy loading mode) and the table page is switched by way of the Primefaces paginator.


                      <ui:define name="content">
                          rowCount: #{primefaces_SimpleSortableDataModel.rowCount}<br/>
                          <h:form>
                              <p:dataTable value="#{primefaces_SimpleSortableDataModel}" rows="25" var="rowData"
                                           paginator="true"  dynamic="true" lazy="true">
                                  <p:column>
                                      <f:facet name="header">
                                          i
                                      </f:facet>
                                      #{rowData.i}
                                  </p:column>
                                  <p:column>
                                      <f:facet name="header">
                                          msg
                                      </f:facet>
                                      #{rowData.msg}
                                  </p:column>
                              </p:dataTable>
                          </h:form>
                      </ui:define>
                  </ui:composition>
                  


                  • 7. Re: AnnotationLiteral throws NPE on Glassfish v3 + SeamFaces
                    Nicklas Karlsson Master

                    Could the events fire with null components when AJAX is involved?

                    • 8. Re: AnnotationLiteral throws NPE on Glassfish v3 + SeamFaces
                      Wolfgang Schwendt Newbie
                      <blockquote>
                      _Nicklas Karlsson wrote on May 24, 2010 13:55:_<br/>
                      he issue should of course be fixed but I wonder if its more an issue of the literals being constructed strangely

                      </blockquote>

                      our post overlapped in time.  Yes, it appears to be an issue of the literals being constructed strangely.

                      Default "" (empty String) would  make the EventBridge lenient and very likely solve the problem (I'll test later). Still, I'm wondering why the the EventSource of the ComponentSystemEvent has an id with value null (a PrimeFaces issue?).



                      • 9. Re: AnnotationLiteral throws NPE on Glassfish v3 + SeamFaces
                        Wolfgang Schwendt Newbie

                        Nicklas Karlsson wrote on May 24, 2010 14:07:


                        Could the events fire with null components when AJAX is involved?


                        our posts overlapped again. Yes, obviously they can (when using PrimeFaces, althought this behavior may be a PrimeFaces bug). Otherwise it wouldn't have been possible to construct the ComponentLiteral with value null.  I'll take a look at that later.

                        • 10. Re: AnnotationLiteral throws NPE on Glassfish v3 + SeamFaces
                          Wolfgang Schwendt Newbie

                          The component (Event Source) with id null is a Resource component (org.primefaces.component.Resource). 


                          Primefaces components observe the JSF PostAddToViewEvent.  In reaction to this event they typically create one or more Resource components and add them to the JSF view via UIViewRoot.addComponentResource.  The Resource components represent the inclusion of JavaScript scripts which are needed by the Primefaces components.


                          typical example:


                          package org.primefaces.component.editor;
                          
                          
                          @ListenerFor(systemEventClass = PostAddToViewEvent.class)
                          public class Editor extends UIInput 
                          
                          
                               @Override
                               public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
                                    FacesContext facesContext = getFacesContext();
                                    javax.faces.component.UIViewRoot viewroot = facesContext.getViewRoot();
                                    Resource resource = null;
                                    if(!resourceExists(facesContext, "/yui/menu/assets/skins/sam/menu.css")) {
                                         resource = (Resource) facesContext.getApplication().createComponent("org.primefaces.component.Resource");
                                         resource.setName("/yui/menu/assets/skins/sam/menu.css");
                                         viewroot.addComponentResource(facesContext, resource, "head");
                                    }
                          
                          ...
                          
                          



                          During an AJAX request PreValidateEvents are fired. The added Resource resource components have id null.   Consequently, the SeamFacesEvent bridge creates a ComponentLiteral with value null.


                          • 11. Re: AnnotationLiteral throws NPE on Glassfish v3 + SeamFaces
                            Lincoln Baxter III Master

                            I think this is potentially a bug in Weld:


                            AnnotationLiteral.hashCode() should not be resulting in a NPE. See the else {} block. No null check is ever performed on 'value' before hashCode() is invoked.



                            AnnotationLiteral
                              @Override
                               public int hashCode()
                               {
                                  int hashCode = 0;
                                  for (Method member: getMembers())
                                  {
                                     int memberNameHashCode = 127 * member.getName().hashCode();
                                     Object value = invoke(member, this);
                                     int memberValueHashCode;
                                     if (value instanceof boolean[])
                                     {
                                        memberValueHashCode = Arrays.hashCode((boolean[]) value);
                                     }
                                     else if (value instanceof short[])
                                     {
                                        memberValueHashCode = Arrays.hashCode((short[]) value);
                                     }
                                     else if (value instanceof int[])
                                     {
                                        memberValueHashCode = Arrays.hashCode((int[]) value);
                                     }
                                     else if (value instanceof long[])
                                     {
                                        memberValueHashCode = Arrays.hashCode((long[]) value);
                                     }
                                     else if (value instanceof float[])
                                     {
                                        memberValueHashCode = Arrays.hashCode((float[]) value);
                                     }
                                     else if (value instanceof double[])
                                     {
                                        memberValueHashCode = Arrays.hashCode((double[]) value);
                                     }
                                     else if (value instanceof byte[])
                                     {
                                        memberValueHashCode = Arrays.hashCode((byte[]) value);
                                     }
                                     else if (value instanceof char[])
                                     {
                                        memberValueHashCode = Arrays.hashCode((char[]) value);
                                     }
                                     else if (value instanceof Object[])
                                     {
                                        memberValueHashCode = Arrays.hashCode((Object[]) value);
                                     }
                                     else 
                                     {
                                        memberValueHashCode = value.hashCode();
                                     }
                                     hashCode += memberNameHashCode ^ memberValueHashCode;
                                  }       
                                  return hashCode;
                               }