6 Replies Latest reply on Jun 14, 2010 2:37 AM by Sean Wu

    Bug of Seam ComponentTest for EntityHome?

    Sean Wu Newbie

      To validate seam component test, I create a simple project with seam-gen:
      Only one user entity with userHome.
      As seam-gen, the userHome is a seam component with name userHome and add a simple sayHello method to it with return value is hello
      Here is the UserHomeTest code:



      public class UserHomeTest extends SeamTest {
      
          private static LogProvider log = Logging.getLogProvider(UserTest.class);
      
          @Test
          public void testSayHello() throws Exception {
              new ComponentTest() {
                  protected void testComponents() throws Exception {
                      String result = (String)invokeMethod("#{userHome.sayHello}");
                      log.info("Result: "+result);
                      assert result.equals("hello");
                  }
              }.run();
          }
      
      }




      It failed to pass the test:



      WARN  [org.jboss.seam.security.permission.PersistentPermissionResolver] no permission store available - please install a PermissionStore with the name 'org.jboss.seam.security.jpaPermissionStore' if persistent permissions are required.
      FAILED: testSayHello
      org.jboss.seam.InstantiationException: Could not instantiate Seam component: userHome
              at org.jboss.seam.Component.newInstance(Component.java:2144)
              at org.jboss.seam.Component.getInstance(Component.java:2021)
              at org.jboss.seam.Component.getInstance(Component.java:1983)
              at org.jboss.seam.Component.getInstance(Component.java:1977)
              at org.jboss.seam.Namespace.getComponentInstance(Namespace.java:55)
              at org.jboss.seam.Namespace.getComponentInstance(Namespace.java:50)
              at org.jboss.seam.el.SeamELResolver.resolveBase(SeamELResolver.java:148)
              at org.jboss.seam.el.SeamELResolver.getValue(SeamELResolver.java:51)
              at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:143)
              at org.jboss.el.parser.AstIdentifier.getValue(AstIdentifier.java:44)
              at org.jboss.el.parser.AstValue.getTarget(AstValue.java:34)
              at org.jboss.el.parser.AstValue.invoke(AstValue.java:95)
              at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
              at org.jboss.seam.core.Expressions$2.invoke(Expressions.java:175)
              at org.jboss.seam.mock.AbstractSeamTest$ComponentTest.invokeMethod(AbstractSeamTest.java:136)
              at com.monsanto.bizcard.test.UserHomeTest$1.testComponents(UserHomeTest.java:32)
              at org.jboss.seam.mock.AbstractSeamTest$ComponentTest.run(AbstractSeamTest.java:162)
              at com.monsanto.bizcard.test.UserHomeTest.testSayHello(UserHomeTest.java:30)
      Caused by: java.lang.IllegalArgumentException: Stack must not be null
              at org.jboss.seam.core.ConversationEntry.<init>(ConversationEntry.java:45)
              at org.jboss.seam.core.ConversationEntries.createConversationEntry(ConversationEntries.java:53)
              at org.jboss.seam.core.Manager.createConversationEntry(Manager.java:664)
              at org.jboss.seam.core.Manager.beginConversation(Manager.java:685)
              at org.jboss.seam.core.ConversationInterceptor.beginConversation(ConversationInterceptor.java:229)
              at org.jboss.seam.core.ConversationInterceptor.beginConversationIfNecessary(ConversationInterceptor.java:166)
              at org.jboss.seam.core.ConversationInterceptor.aroundInvoke(ConversationInterceptor.java:57)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
              at org.jboss.seam.transaction.TransactionInterceptor$1.work(TransactionInterceptor.java:97)
              at org.jboss.seam.util.Work.workInTransaction(Work.java:47)
              at org.jboss.seam.transaction.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:91)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
              at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
              at org.jboss.seam.core.SynchronizationInterceptor.aroundInvoke(SynchronizationInterceptor.java:32)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
              at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
              at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:185)
              at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:103)
              at com.monsanto.bizcard.action.UserHome_$$_javassist_seam_1.create(UserHome_$$_javassist_seam_1.java)
              at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
              at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:144)
              at org.jboss.seam.Component.callComponentMethod(Component.java:2249)
              at org.jboss.seam.Component.callCreateMethod(Component.java:2172)
              at org.jboss.seam.Component.newInstance(Component.java:2132)
              ... 39 more


      I think it is due to EntityHome since I move the sayHello method to User class
      and make it as a component with name of user, then I write the same component test for user component. It works and passes the test!!
      The only difference is the seam component type: UserHome extends EntityHome and User is an Entity. I've worked on it for days and read all of exception about SeamTest, could not instantiate seam component and stack must not be null, etc but still can not fix it and find the reason. Could somebody help?
      Thanks in advance.


        • 1. Re: Bug of Seam ComponentTest for EntityHome?
          Sean Wu Newbie

          This is the code of UserHome:



          @Name("userHome")
          
          public class UserHome extends EntityHome<User>
          {
              @RequestParameter Long userId;
          
              @Override
              public Object getId()
              {
                  if (userId == null)
                  {
                      return super.getId();
                  }
                  else
                  {
                      return userId;
                  }
              }
          
              @Override @Begin
              public void create() {
                  super.create();
              }
          
          }



          • 2. Re: Bug of Seam ComponentTest for EntityHome?
            Sean Wu Newbie

            Sorry, forget the sayHello method in the UserHome:


            public String sayHello() {
                    return "hello";
                }



            • 4. Re: Bug of Seam ComponentTest for EntityHome?
              Sean Wu Newbie

              I am very sure it is due to the EntityHome. I tested UserList wihch extends EntityQuery, it works.

              • 5. Re: Bug of Seam ComponentTest for EntityHome?
                Sean Wu Newbie

                If I change the scope to stateless with @Scope(STATELESS) on UserHome, it works and passes the test. So, the problem is about Coversation, I tried to begin and end it manullay, but still failed. The code:



                public class UserHomeTest extends SeamTest {
                
                    private static LogProvider log = Logging.getLogProvider(UserHomeTest.class);
                
                    // FAILED
                    @Test
                    public void testSayHello() throws Exception {
                        new ComponentTest() {
                            protected void testComponents() throws Exception {
                                String result = (String)invokeMethod("#{userHome.sayHello}");
                                log.info("Result: "+result);
                                assert result.equals("hello");
                            }
                        }.run();
                    }
                
                    // FAILED
                    @Test
                    public void testUserHome() throws Exception {
                        new ComponentTest() {
                
                            protected void testComponents() {
                                log.info("=== Start Conversation Manually ==");
                                String cid = ConversationIdGenerator.instance().getNextId();
                                List<String> cidStack = new ArrayList<String>();
                                cidStack.add(cid);
                                // cid is null
                                log.info("cid = "+Conversation.instance().getId());
                                Manager.instance().setCurrentConversationId(cid);
                                Manager.instance().setCurrentConversationIdStack(cidStack);
                                // cid is 1
                                log.info("cid = "+Conversation.instance().getId());
                                Conversation.instance().begin();
                                UserHome uh = (UserHome)Component.getInstance("userHome", true);
                                assert uh != null;
                                assert uh.sayHello().equals("hello");
                                Conversation.instance().end();
                                log.info("=== End Conversation Manually ==");
                            }
                        }.run();
                    }
                
                    // PASSED
                    @Test
                    public void testPlainUserHome() {
                        UserHome uh = new UserHome();
                        assert uh.sayHello().equals("hello");
                    }
                
                }


                Only testPlainUserHome passed the test, other two throw the same exception listed above.
                Oops! I need help!


                • 6. Re: Bug of Seam ComponentTest for EntityHome?
                  Sean Wu Newbie

                  Further progress: EntityHome component can not be instantiated for some weird reason while Entity component is instantiated correctly when seamtest meets them in the expression such as #{userHome.method}. You can set the EntityHome component manually in the seamtest. Here is my test code:



                  public class UserHomeTest extends SeamTest {
                  
                      private static LogProvider log = Logging.getLogProvider(UserHomeTest.class);
                  
                      // if I instantiate the component manually, it works
                      @Test
                      public void testSayHelloManually() throws Exception {
                          new ComponentTest() {
                              protected void testComponents() throws Exception {
                                  
                                  UserHome uh = new UserHome();
                                  Context conversation = Contexts.getConversationContext();
                                  conversation.set("userHome",uh);
                                  String result = (String)invokeMethod("#{userHome.sayHello}");
                                  log.info("Result: "+result);
                                  assert result.equals("hello");
                                  listSeamComponents();
                              }
                          }.run();
                      }
                  
                      // THIS DOES NOT WORK FOR SOME WEIRD REASON!!!
                      // SEAM CAN NOT INSTANTIATE THE userHome COMPONENT
                      @Test
                      public void testSayHello() throws Exception {
                          new ComponentTest() {
                              protected void testComponents() throws Exception {
                                  // seam should instantiate the userHome automatically
                                  String result = (String)invokeMethod("#{userHome.sayHello}");
                                  log.info("Result: "+result);
                                  assert result.equals("hello");
                                  listSeamComponents();
                              }
                          }.run();
                      }
                  
                     
                  
                      // PASSED
                      @Test
                      public void testPlainUserHome() {
                          UserHome uh = new UserHome();
                          assert uh.sayHello().equals("hello");
                      }
                  
                      public void listSeamComponents() {
                          log.info("Application context is active: "+Contexts.isApplicationContextActive());
                          log.info("Session context is active: "+Contexts.isSessionContextActive());
                          log.info("Coversation context is active: "+Contexts.isConversationContextActive());
                          log.info("------------------ Conversation Context -------------------");
                          Context conversation = Contexts.getConversationContext();
                          listComponentsInContext(conversation);
                  
                      }
                  
                      public void listComponentsInContext(Context context) {
                          log.info("# Component size: "+context.getNames().length);
                          for (String name : context.getNames()) {
                              Component component = Component.forName(name);
                              String componentInfo = component.getName() + ":" + component.getType() + ":" + component.getScope() + ":" + component.getTimeout() + ":" + component.isStartup() + ":" + component.isSynchronize();
                              if (!component.getName().startsWith("org.jboss.seam")) {
                                  log.info("# Customized Seam Component -- " + componentInfo);
                              }
                          }
                      }
                  
                  }