1 2 Previous Next 15 Replies Latest reply on Sep 11, 2009 11:12 PM by Harry Holt

    Seam-Wicket: Injected object is null at runtime

    David Haynes Newbie

      I am probably missing something obvious but can't seem to figure it out.


      My problem is that my injected object into a Wicket backing page POJO is coming out null.


      The Wicket page java has:


      ...
      @In(create true)
      private Foo foo;
      ...
      add(new Label("foo.tag", foo.getName()));



      This compiles cleanly but throws an exception at run time since the instantiated object 'foo' is null.


      My Foo object is very plain:


      @Name("Foo")
      public class Foo {
          protected String name "Secret Name";
          public String getName() { return this.name; }
          public void setName(String name) { this.name = name; }
      }



      The Wicket code is located in src/web and the Foo POJO is in src/main (although I also tried src/hot with no effect)


      If anyone has any ideas, I would love hear them. I am this close to getting this to work!


      -david-

        • 1. Re: Seam-Wicket: Injected object is null at runtime
          Clint Popetz Apprentice

          Wicket component classes have to be instrumented in order to have injections.  Unless you've specified otherwise with the <web:wicket/> filter definition in components.xml, your wicket components have to either:


          (a) be instrumented by the ant task at build time (see the manual)


          or


          (b) live in WEB-INF/wicket at runtime, so that the dynamic classloader will find them.



          This is documented in the wicket section of the manual.

          • 2. Re: Seam-Wicket: Injected object is null at runtime
            David Haynes Newbie

            Just to be clear here.


            Do you mean that the Foo.class needs to be instrumented or that Java backing pages need to be instrumented?


            If it is the latter, then that is what (I think) I am doing. The Foo.class is sitting under WEB-INF/classes and the various Wicket pages are sitting under WEB-INF/wicket.


            My reading of the manual says that if I instrument the classes at compile time then they should either go in WEB-INF/classes or WEB-INF/dev based upon whether I want to use a hot deployment strategy. Correct?

            • 3. Re: Seam-Wicket: Injected object is null at runtime
              David Haynes Newbie

              Additional question:


              Have I read the ant target incorrectly? Should the .java files be located under WEB-INF/wicket instead of the .classes they produce? That would certainly explain why they are not being instrumented.


              Also, thanks for helping me with this.

              • 4. Re: Seam-Wicket: Injected object is null at runtime
                Clint Popetz Apprentice

                David Haynes wrote on Jan 02, 2009 22:47:


                Just to be clear here.

                Do you mean that the Foo.class needs to be instrumented or that Java backing pages need to be instrumented?

                If it is the latter, then that is what (I think) I am doing. The Foo.class is sitting under WEB-INF/classes and the various Wicket pages are sitting under WEB-INF/wicket.

                My reading of the manual says that if I instrument the classes at compile time then they should either go in WEB-INF/classes or WEB-INF/dev based upon whether I want to use a hot deployment strategy. Correct?


                Yes, you are correct on all counts.  The Java wicket pages/components need to live in WEB-INF/wicket, and everything else lives in WEB-INF/classes.


                To see if your classes are being instrumented correctly, put a breakpoint in your wicket page in the debugger, and see if the class description has a WicketHandler field, which the instrumentation code puts there.



                • 5. Re: Seam-Wicket: Injected object is null at runtime
                  Clint Popetz Apprentice

                  The ant target task from wherever you point it to in your ant target. The result should go in WEB-INF/classes or WEB-INF/dev, depending on whether you want it hot deployed.

                  • 6. Re: Seam-Wicket: Injected object is null at runtime
                    David Haynes Newbie

                    I have tried a whack of combinations of things to get this to work and nothing seems to help. I am beginning to think that something else is wrong and I am getting a 'false positive' error condition.


                    With that in mind, I would like to restart this at first principles to see if I am having an issue somewhere else.


                    This is the HTML page:


                    <?xml version="1.0" encoding="UTF-8"?>
                    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
                    <html xmlns:wicket>
                        <head>
                            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
                            <title>Show Foo</title>
                            <link rel="stylesheet" type="text/css" href="style.css"/>
                        </head>
                        <body>
                                <h1>Show Foo</h1>
                                The Foo.name value is '<span wicket:id="foo.name">foo.name</span>'.
                                <p>
                                <a href="#" wicket:id="home-page-link">home page</a>
                                </p>
                        </body>
                    </html>




                    This is the java backing for the ShowFoo.html page:


                    package com.dhc.wicket.web;
                    
                    import com.dhc.wicket.action.Foo;
                    import org.apache.wicket.PageParameters;
                    import org.apache.wicket.markup.html.WebPage;
                    import org.apache.wicket.markup.html.basic.Label;
                    import org.apache.wicket.markup.html.link.Link;
                    import org.apache.wicket.model.PropertyModel;
                    import org.jboss.seam.annotations.In;
                    
                    public class ShowFoo extends WebPage {
                        @In(create = true)
                        private Foo foo;
                    
                        public ShowFoo() {
                            super();
                            init();
                        }
                    
                        public ShowFoo(final PageParameters params) {
                            super(params);
                            init();
                        }
                    
                        private void init() {
                            if( foo == null ) {
                                add(new Label("foo.name", "Object foo is null."));
                            } else {
                                add(new Label("foo.name", new PropertyModel(foo, "name")));
                            }
                            add(new Link("home-page-link") {
                                public void onClick() {
                                    setResponsePage(new HomePage());
                                }
                            }
                            );
                        }
                    }



                    This is the Foo class that I want to inject:


                    package com.dhc.wicket.action;
                    
                    import java.io.Serializable;
                    import org.jboss.seam.annotations.Name;
                    
                    @Name("Foo")
                    public class Foo implements Serializable {
                        protected String name = "Name goes here.";
                    
                        public String getName() {
                            return this.name;
                        }
                    
                        public void setName(String name) {
                            this.name = name;
                        }
                    }



                    When I compile these, the classes all go under WEB-INF/wicket in their appropriate package directories.



                    WEB-INF/wicket/com/dhc/wicket/action:
                    total 16
                    -rw-r--r-- 1 david david 1240 2009-01-05 12:18 Authenticator.class
                    -rw-r--r-- 1 david david  682 2009-01-05 12:18 Foo.class
                    
                    WEB-INF/wicket/com/dhc/wicket/web:
                    total 28
                    -rw-r--r-- 1 david david  769 2009-01-05 12:18 HomePage$1.class
                    -rw-r--r-- 1 david david  897 2009-01-05 12:18 HomePage.class
                    -rw-r--r-- 1 david david  523 2009-01-05 12:18 HomePage.html
                    -rw-r--r-- 1 david david  776 2009-01-05 12:18 ShowFoo$1.class
                    -rw-r--r-- 1 david david 1372 2009-01-05 12:18 ShowFoo.class
                    -rw-r--r-- 1 david david  606 2009-01-05 12:18 ShowFoo.html
                    -rw-r--r-- 1 david david  542 2009-01-05 12:18 WicketApplication.class



                    Running under JBoss 4.2.3 shows that the Foo object is null at run time.


                    Show Foo
                    The Foo.name value is 'Object foo is null.'.
                    
                    home page



                    I have no idea why the @In is not being honored and would really appreciate some new ideas on this.


                    Thanks
                    -david-

                    • 7. Re: Seam-Wicket: Injected object is null at runtime
                      Clint Popetz Apprentice

                      David Haynes wrote on Jan 05, 2009 18:42:


                      When I compile these, the classes all go under WEB-INF/wicket in their appropriate package directories.



                      Foo is a seam component, not a wicket component.  So it needs to go in either WEB-INF/classes or WEB-INF/dev.



                      The only thing that you should put in WEB-INF/wicket are Wicket components themselves, i.e. WebPage/Panel/MarkupContainer/etc subclasses and their inner classes.  WEB-INF/wicket is your view layer.  WEB-INF/classes (or WEB-INF/dev when hot deploying) contains everything else, i.e. dao, action, model, etc.


                      (Or just use the instrumentation ant task and forget about the above distinction, which is my preference.)

                      • 8. Re: Seam-Wicket: Injected object is null at runtime
                        David Haynes Newbie

                        Well I tried moving the Foo.class and Authenticator.class to WEB-INF/dev with the rest in WEB-INF/wicket and I still get the null Foo object.


                        So, I took your advice and added the instrumentation task and had everything move to WEB-INF/dev as shown below:


                        dev:
                        total 4
                        drwxr-xr-x 3 david david 4096 2009-01-05 17:16 com
                        
                        dev/com:
                        total 4
                        drwxr-xr-x 3 david david 4096 2009-01-05 17:16 dhc
                        
                        dev/com/dhc:
                        total 4
                        drwxr-xr-x 3 david david 4096 2009-01-05 17:16 wicket
                        
                        dev/com/dhc/wicket:
                        total 12
                        -rw-r--r-- 1 david david 1226 2009-01-05 17:16 Authenticator.class
                        -rw-r--r-- 1 david david  668 2009-01-05 17:16 Foo.class
                        drwxr-xr-x 2 david david 4096 2009-01-05 17:16 web
                        
                        dev/com/dhc/wicket/web:
                        total 28
                        -rw-r--r-- 1 david david 2994 2009-01-05 17:16 HomePage$1.class
                        -rw-r--r-- 1 david david 2617 2009-01-05 17:16 HomePage.class
                        -rw-r--r-- 1 david david  523 2009-01-05 17:16 HomePage.html
                        -rw-r--r-- 1 david david 3001 2009-01-05 17:16 ShowFoo$1.class
                        -rw-r--r-- 1 david david 3892 2009-01-05 17:16 ShowFoo.class
                        -rw-r--r-- 1 david david  606 2009-01-05 17:16 ShowFoo.html
                        -rw-r--r-- 1 david david 3026 2009-01-05 17:16 WicketApplication.class




                        I chekced that the class files in ../wicket/web are all instrumented components (NetBeans shows this) and that the two classes (Foo and Authenticator) are not. I still get a null Foo object at run time.


                        • 9. Re: Seam-Wicket: Injected object is null at runtime
                          Clint Popetz Apprentice

                          Is your WicketApplication class a subclass of SeamWicketApplication?


                          Also, if you put a breakpoint in the debugger, do you see seam's wicketFilterInstantiator in the stack trace?


                          Finally,if you post your components.xml, I can look for problems there.


                          (You can also put your entire project zipped up somewhere for me to grab, if that's easier.)

                          • 10. Re: Seam-Wicket: Injected object is null at runtime
                            David Haynes Newbie


                            Is your WicketApplication class a subclass of SeamWicketApplication?

                            It extends SeamWebApplication (which is what I think you meant)



                            package com.dhc.wicket.web;
                            
                            import org.jboss.seam.wicket.SeamWebApplication;
                            
                            public class WicketApplication extends SeamWebApplication {
                                @Override
                                public Class getHomePage() {
                                    return HomePage.class;
                                }
                            
                                @Override
                                public Class getLoginPage() {
                                    return HomePage.class;
                                }
                            }



                            Here is the components.xml file:


                            <?xml version="1.0" encoding="UTF-8"?>
                            <components xmlns="http://jboss.com/products/seam/components"
                                        xmlns:core="http://jboss.com/products/seam/core"
                                        xmlns:persistence="http://jboss.com/products/seam/persistence"
                                        xmlns:drools="http://jboss.com/products/seam/drools"
                                        xmlns:bpm="http://jboss.com/products/seam/bpm"
                                        xmlns:security="http://jboss.com/products/seam/security"
                                        xmlns:mail="http://jboss.com/products/seam/mail"
                                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                        xmlns:wicket="http://jboss.com/products/seam/wicket"
                                        xsi:schemaLocation=
                                            "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.1.xsd
                                             http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.1.xsd
                                             http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.1.xsd
                                             http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.1.xsd
                                             http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.1.xsd
                                             http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.1.xsd
                                             http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.1.xsd">
                            
                               <core:init debug="@debug@" jndi-pattern="@jndiPattern@"/>
                            
                               <component name="org.jboss.seam.debug.hotDeployFilter">
                                  <property name="urlPattern">*.seam</property>
                               </component>
                            
                               <core:manager concurrent-request-timeout="500"
                                             conversation-timeout="120000"
                                             conversation-id-parameter="cid"
                                             parent-conversation-id-parameter="pid"/>
                            
                               <persistence:managed-persistence-context name="entityManager"
                                                                 auto-create="true"
                                                      entity-manager-factory="#{wicketEntityManagerFactory}"/>
                            
                               <persistence:entity-manager-factory name="wicketEntityManagerFactory"
                                                  persistence-unit-name="wicket"/>
                            
                               <drools:rule-base name="securityRules">
                                  <drools:rule-files><value>/security.drl</value></drools:rule-files>
                               </drools:rule-base>
                            
                               <security:rule-based-permission-resolver security-rules="#{securityRules}"/>
                            
                               <security:identity authenticate-method="#{authenticator.authenticate}" remember-me="true"/>
                            
                               <event type="org.jboss.seam.security.notLoggedIn">
                                  <action execute="#{redirect.captureCurrentView}"/>
                               </event>
                               <event type="org.jboss.seam.security.loginSuccessful">
                                  <action execute="#{redirect.returnToCapturedView}"/>
                               </event>
                            
                               <mail:mail-session host="localhost" port="2525" username="test" password="test" />
                            
                               <!-- For use with jBPM pageflow or process management -->
                               <!--
                               <bpm:jbpm>
                                  <bpm:process-definitions></bpm:process-definitions>
                                  <bpm:pageflow-definitions></bpm:pageflow-definitions>
                               </bpm:jbpm>
                               -->
                            
                               <!-- Wicket support -->
                               <wicket:web-application application-class="com.dhc.wicket.web.WicketApplication" />
                            
                            </components>



                            I'm not sure how to set the breakpoint in NetBeans so that it works in JBoss (I'll have to find out) but the WicketFilterInstantiator component is being loaded.



                            18:46:43,961 INFO  [Component] Component: org.jboss.seam.wicket.web.wicketFilterInstantiator, scope: STATELESS, type: JAVA_BEAN, class: org.jboss.seam.wicket.web.WicketFilterInstantiator



                            I'll see about setting up some way for you to pick up the tar bundle for this.


                            Thanks for all your help.
                            -david-

                            • 11. Re: Seam-Wicket: Injected object is null at runtime
                              David Haynes Newbie

                              Clint:


                              Please send me an email (mailto:david.dhcinc@gmail.com) and I will send you instructions on how to pick up the project bundle. It is 60MB compressed since it include the lib directory. I can remove that if you want.


                              -david-

                              • 12. Re: Seam-Wicket: Injected object is null at runtime
                                David Haynes Newbie

                                Sometimes you can't see the forest for the trees...


                                Thanks to Clint's eagle eye, the error has nothing to do with wicket at all but with the face that the @Name(Foo) does not match the @In of 'foo'.


                                If anyone is interested, I did learn a whole whack about how to adjust the Ant scripts to support instrumented and uninstrumented wicket support and I will be making copious notes on the matter.



                                Clint has been really great helping me track this down.
                                Thanks again for all your help.


                                -david-

                                • 13. Re: Seam-Wicket: Injected object is null at runtime
                                  Daniele Gariboldi Newbie

                                  Hello, I'm setting up a project in eclipse for wicket, seam, JPA using tomcat 6 alone (no JBoss neither JBoss embedded).
                                  I'm interested in sharing your experience on the subject, expecially about the setup of source - destination folders.
                                  Putting wicket classes (Application and Home page) compiled under WEB-INF/wicket let them be instrumented (I see it in the debugger).
                                  But my model classes and DAO are under WEB-INF/classes and are not put in their contexts by injection, even if annotated as:



                                  @Scope(value=ScopeType.APPLICATION)
                                  @Name("accountDAO")
                                  @AutoCreate



                                  I read Clint Popetz:



                                  The only thing that you should put in WEB-INF/wicket are Wicket components themselves, i.e. WebPage/Panel/MarkupContainer/etc subclasses and their inner classes. WEB-INF/wicket is your view layer. WEB-INF/classes (or WEB-INF/dev when hot deploying) contains everything else, i.e. dao, action, model, etc.

                                  and I'm having a thread with him here about hot deployment.

                                  Here I would like to know if having seam and wicket components in two different folders works for you.

                                  My project works only if everything is under /WEB-INF/wicket. I use no ant instrumentation.

                                  Thanks

                                  • 14. Re: Seam-Wicket: Injected object is null at runtime
                                    David Haynes Newbie

                                    To answer your question. Yes having seam and wicket components in two different folders works for me but I use ant targets to instrument the wicket classes. There are only three targets that are needed so it is not that difficult.


                                    If you do not instrument your wicket classes, Clint's statement above is correct but I am wondering if the fact that you are expecting EJB behavior from Tomcat is getting in the way. (I have not used Tomcat for this, only JBoss AS.)


                                    1 2 Previous Next