1 2 Previous Next 19 Replies Latest reply on Jun 3, 2009 7:08 PM by Dean Hiller

    Seam-wicket and hot deployment problem

    Daniele Gariboldi Newbie
      As suggested in the reference guide, I configured an eclipse-project to deploy through an ant script the instrumented classes under WEB-INF/dev, for hot deployment.
      It doesn't work for me.
      I use a bare minimum wicket application class and home class, and output a label from home.
      If I change the label string while running it doesn't change: tried to force build of project, used other browser but no success.
      If then I stop and restart tomcat, I see the new value, so instrumentation is OK but class isn't reloaded.

      I tried both launching tomcat whit Sysdeo plugin and launching from a java class, in debug, jetty: same result.
      Wicket and seam are in debug mode, classes are all compiled and instrumented and copied to WEB-INF/dev using an ant script, shortened version of seam examples scrpt.
      Before posting long configurations and code, anyone has a suggestion about what to check first ?
      Seam 2.1.1GA, tomcat 6, jetty 6, jdk 6_10 on Vista 64
        • 1. Re: Seam-wicket and hot deployment problem
          Clint Popetz Apprentice

          Can you post just the code you're using in your wicket page, i.e. what you're changing in order to propagate the label change?

          • 2. Re: Seam-wicket and hot deployment problem
            Daniele Gariboldi Newbie

            Here is the wicket code:


            import org.jboss.seam.wicket.SeamWebApplication;
            
            public class H24Application extends SeamWebApplication {
                 @Override<br/>
                 public Class<Home> getHomePage() {
                      return Home.class;
                 }
            
                 @Override
                 protected Class<Home> getLoginPage() {
                      return Home.class;
                 }
            
            }




            public class Home extends WebPage {
                 public Home() {
                      add(new Label("place", new PropertyModel(new TestModel(),"testdata")));
                 }
            }




            public class TestModel {
                 public String getTestdata() {
                      return "test1";
                 }
            }




            When I change test1 with test2 and reload my browser nothing change.
            Eclipse debugger signal code could be out of sync.


            • 3. Re: Seam-wicket and hot deployment problem
              Clint Popetz Apprentice

              I presume that all of the above classes live in /WEB-INF/dev in your deployment.  If that's not the case, let me know.


              When you hit reload, do you see a message that looks like:


              2009-01-23 12:17:40,687 INFO  [org.jboss.seam.init.Initialization] redeploying components



              in your server logs?

              • 4. Re: Seam-wicket and hot deployment problem
                Daniele Gariboldi Newbie

                I confirm all the above classes being under /WEB-INF/dev.

                No, I don't see that message in the log.

                If I put a breakpoint in my TestModel class and look at the call stack, I don't see org.jboss.seam.web.HotDeployFilter, should it be there?
                I see SeamFilter, WicketFilter, WebRequestCycle, SeamWebApplication, ...., TestModel (signed as out of sync).

                My components.xml is:


                <core:init debug="true"/>
                
                <core:manager conversation-timeout="120000"
                              concurrent-request-timeout="500"
                              conversation-id-parameter="cid"/>
                
                
                
                <persistence:entity-manager-factory name="h24"/>
                <persistence:managed-persistence-context name="entityManager"  auto-create="true"  entity-manager-factory="#{h24}"/>
                <transaction:entity-transaction entity-manager="#{entityManager}"/>
                
                
                <!-- security:identity authenticate-method="#{authenticator.authenticate}"/ -->
                
                <web:context-filter url-pattern="/resources/*"/>
                <web:redirect-filter url-pattern="/*"/>
                <web:multipart-filter create-temp-files="true" max-request-size="0" url-pattern="/*"/>
                <wicket:web-application application-class="it.depofarma.web.H24Application" />
                
                
                <component class="org.jboss.seam.web.MultipartFilter">
                  <property name="createTempFiles">true</property>
                </component>
                
                <async:quartz-dispatcher/>
                
                <mail:mail-session host="localhost" />



                • 5. Re: Seam-wicket and hot deployment problem
                  Clint Popetz Apprentice

                  That's very odd.  If you search for org.jboss.seam.web.hotDeployFilter in the logs, do you see this:


                  2009-01-23 08:59:21,437 INFO  [org.jboss.seam.Component] Component: org.jboss.seam.web.hotDeployFilter, scope: APPLICATION, type: JAVA_BEAN, class: org.jboss.seam.web.HotDeployFilter



                  How about this:



                  2009-01-23 08:59:22,687 INFO  [org.jboss.seam.servlet.SeamFilter] Initializing filter: org.jboss.seam.web.hotDeployFilter




                  Both of those should be present if debug=true, which it appears to be from your components.xml.


                  Also, make sure you don't have init.debug set to false in components.properties or seam.properties somewhere in the classpath.

                  • 6. Re: Seam-wicket and hot deployment problem
                    Daniele Gariboldi Newbie

                    I see:


                    23:30:59,991 DEBUG \[main\] seam.deployment.ClassDescriptor - could not load class (missing dependency): org.jboss.seam.transaction.EjbSynchronizations
                    ...
                    23:31:00,335 DEBUG \[main\] seam.init.Initialization - Using Java hot deploy
                    ...
                    23:31:00,651 INFO  \[main\] jboss.seam.Component - Component: org.jboss.seam.web.hotDeployFilter, scope: APPLICATION, type: JAVA_BEAN, class: org.jboss.seam.web.HotDeployFilter
                    ...
                    23:31:01,991 DEBUG \[main\] seam.contexts.Contexts - destroying: hotDeploymentStrategy
                    ...
                    23:31:02,036 INFO  \[main\] seam.servlet.SeamFilter - Initializing filter: org.jboss.seam.web.hotDeployFilter
                    ...



                    I don't see:


                    2009-01-23 12:17:40,687 INFO  [org.jboss.seam.init.Initialization] redeploying components
                    



                    In Seam with JSF, I had no problem editing classes being seam components, without using any special folder.
                    Why with wicket it's different? Is this only limited to wicket components (which are built and composed in a hierarchy by emploing constructors)?

                    Is mine an untested configuration?

                    • 7. Re: Seam-wicket and hot deployment problem
                      Clint Popetz Apprentice

                      Ahh, yes, this is a bug.  Seam only re-deploys the WEB-INF/dev when a @Named component is modified, which wicket components aren't. 


                      I never encountered this locally because early in the 2.1 cycle I got fed up with the slowness of the seam default deployment strategy (which scans every file in WEB-INF/dev on every hit) and wrote my own scanner that looks at a generated file in the top level of WEB-INF/dev, which I have my ant scripts touch if anything changed. 


                      I've made this an issue: JBSEAM-3914 .



                      As a workaround, here's the scanner I use.  Make your build scripts touch a something.mod (it just hast to end in .mod) in /WEB-INF/dev when any class changes there.  Create a root level file name seam-deployment.properties with the following contents:


                      org.jboss.seam.deployment.scanners=your.package.here.ModifiedFileScanner
                      org.jboss.seam.init.duplicateJarsPatterns=^tmp\\d+(\\S*.jar)
                      



                      And create this class, which should not hot deployed:


                      package your.package.here;
                      
                      import java.io.File;
                      
                      import org.jboss.seam.deployment.AbstractScanner;
                      import org.jboss.seam.deployment.DeploymentStrategy;
                      import org.jboss.seam.deployment.URLScanner;
                      
                      public class ModifiedFileScanner extends AbstractScanner {
                      
                           static boolean firstHotDeploy = true;
                           boolean isHotDeploy;
                           long timestamp = 0;
                           URLScanner delegate = null;
                           
                           
                           public ModifiedFileScanner(DeploymentStrategy strategy) {
                                super(strategy);
                           }
                           
                           @Override
                           public long getTimestamp() {
                                return isHotDeploy ? timestamp : delegate.getTimestamp();
                           }
                           
                           @Override
                           public void scanDirectories(File[] directories) {
                                
                                isHotDeploy = directories.length == 1 && directories[0].getName().equals("dev");
                                if (!isHotDeploy || firstHotDeploy || timestamp != 0) { 
                                     if (isHotDeploy)
                                          firstHotDeploy = false;
                                     if (delegate == null)
                                          delegate = new URLScanner(getDeploymentStrategy());
                                     delegate.scanDirectories(directories);
                                }
                                if (isHotDeploy && timestamp == 0)
                                     for (File child : directories[0].listFiles())
                                          if (child.getName().endsWith(".mod") && child.lastModified() > timestamp)
                                               timestamp = child.lastModified();
                           }
                      
                           @Override
                           public void scanResources(String[] resources) {
                                if (delegate == null)
                                     delegate = new URLScanner(getDeploymentStrategy());
                                delegate.scanResources(resources);
                           }
                      }
                      



                      • 8. Re: Seam-wicket and hot deployment problem
                        Erdem Agaoglu Newbie

                        How exactly did you configure eclipse to deploy through an ant script? And did this ModifiedScanner worked as expected? I mean like, save-wicket-component and refresh browser, just as other seam components do. Because i saw some site talking about eclipse not being able to execute ant tasks as compile-on-save.

                        • 9. Re: Seam-wicket and hot deployment problem
                          Daniele Gariboldi Newbie

                          First let me say I didn't managed to get my development environment setup according to my needs. I'm trying now a different and more near to metal stack, which let me change code at runtime without application restart.

                          Using Seam and JSF I had no problem developing in Eclipse + Sysdeo Tomcat plugin. Yet with wicket hot code change seams a little cumbersome to achieve.

                          I'll try Seam + wicket again during next months, when more info is available, but I share here infos on my last try.

                          You are right: I launched my ant script by hand inside eclipse, each time I did a change. I followed the hint above by Clint. It took me to add to my classpath ejb-api.jar too, which lent me to think something is wrong or not thought for a plain tomcat deployment.

                          My classes where instrumented, but not hot-reloaded on change. I put here my version of ant build, collapsed from the script bundled with seam examples:
                          Hope this helps


                          <?xml version="1.0"?>
                          
                          <project name="WicketBooking" default="copyWicketInstrumentedClasses" basedir="." >
                          
                               <!-- Naming -->
                               <property name="Name" value="Port of Seam Booking Example to use Wicket" />
                               <property name="example.name" value="jboss-seam-wicket-booking" />
                          
                               <property name="src.java.dir" value="src/java" />
                               <property name="src.web.dir" value="src/wicket" />
                               
                               <property name="jar.dir" value="lib/java_compiled.jar" />
                          
                               <property name="javac.debug" value="true" />
                               <property name="javac.deprecation" value="false" />
                          
                               <!--If this is set to true, wicket classes are instrumented at build time by seam's
                               WicketInstrumentationTask.  The resulting classes will be placed in WEB-INF/dev if debug=true,
                               else they'll go in WEB-INF/classes -->
                               <property name="instrumentAtBuildTime" value="true" />
                               <property name="build.web" value="build-web" />
                               <property name="build.instrumented" value="instrumented-web" />
                          
                            <property name="wicketClassDestination" value="webapp/WEB-INF/classes" />
                          
                               <!-- Libraries to include -->
                          
                               <property name="seam.wicket.lib" value="yes" />
                               <property name="seam.debug.lib" value="yes" />
                               <property name="wicket-extensions.lib" value="yes" />
                               <property name="wicket-datetime.lib" value="yes" />
                          
                               <!-- Seam Wicket integration, with required dependencies -->
                               <fileset id="seam.wicket.jar" dir="webapp/WEB-INF/lib">
                                    <include name="jboss-seam-wicket.jar" if="seam.wicket.lib" />
                                    <include name="wicket.jar" if="seam.wicket.lib" />
                                    <include name="wicket-ioc.jar" if="seam.wicket.lib" />
                                    <include name="slf4j-api.jar" if="seam.wicket.lib" />
                                    <include name="slf4j-log4j12.jar" if="seam.wicket.lib" />
                               </fileset>
                               <!-- Seam debug, with required dependencies -->
                               <fileset id="seam.debug.jar" dir="webapp/WEB-INF/lib">
                                    <include name="jboss-seam-debug.jar" if="seam.debug.lib" />
                               </fileset>
                               <!-- Dependencies for wicket -->
                               
                               <fileset id="wicket-extensions.jar" dir="webapp/WEB-INF/lib">
                                    <include name="wicket-extensions.jar" if="wicket-extensions.lib" />
                               </fileset>
                               
                               <fileset id="wicket-datetime.jar" dir="webapp/WEB-INF/lib">
                                    <include name="wicket-datetime.jar" if="wicket-datetime.lib" />
                                    <include name="joda-time.jar" if="wicket-datetime.lib" />
                               </fileset>     
                          
                               <!-- Build classpath -->
                               <path id="build.classpath">
                                    <fileset dir="webapp/WEB-INF/lib">
                                         <include name="*.jar" />
                                         <include name="jboss-seam-wicket.jar" />
                                         <exclude name="jboss-seam-debug.jar" />
                                    </fileset>
                               </path>
                          
                               <target name="init" >
                                    <mkdir dir="${jar.dir}" />
                               </target>
                          
                               <!-- Compile the source code, directly into the jar -->
                               <target name="compile" depends="init">
                                    <javac classpathref="build.classpath" destdir="${jar.dir}" debug="${javac.debug}" deprecation="${javac.deprecation}" nowarn="on" >
                                         <src path="${src.java.dir}" />
                                    </javac>
                                    <copy todir="${jar.dir}">
                                         <fileset dir="${src.java.dir}">
                                              <include name="**/*.component.xml" />
                                              <include name="**/components.xml" />
                                         </fileset>
                                    </copy>
                               </target>
                          
                               <target name="compile.web" depends="compile">
                                    <mkdir dir="${build.web}" />
                                    <javac destdir="${build.web}" debug="${javac.debug}" deprecation="${javac.deprecation}" nowarn="on">
                                         <src path="${src.web.dir}" />
                                         <classpath refid="build.classpath" />
                                         <classpath location="${jar.dir}" />
                                    </javac>
                               </target>
                          
                               <target name="instrument" depends="compile.web" >
                                    <taskdef name="instrumentWicket" classname="org.jboss.seam.wicket.ioc.WicketInstrumentationTask">
                                         <classpath>
                                         <pathelement location="lib/jboss-seam-wicket-ant.jar"/>
                                              <pathelement location="webapp/WEB-INF/lib/jboss-seam-wicket-ant.jar" />
                                              <pathelement location="webapp/WEB-INF/lib/jboss-seam-wicket.jar" />
                                              <pathelement location="webapp/WEB-INF/lib/javassist.jar" />
                                              <pathelement location="webapp/WEB-INF/lib/jboss-seam.jar" />
                                         </classpath>
                                    </taskdef>
                          
                                    <path id="instrument.path">
                                         <path refid="build.classpath" />
                                         <pathelement location="${jar.dir}" />
                                         <pathelement location="${build.web}" />
                                    </path>
                          
                                    <instrumentWicket outputDirectory="${build.instrumented}">
                                         <classpath refid="instrument.path" />
                                         <fileset dir="${build.web}">
                                              <and>
                                                   <filename name="**/*.class" />
                                                   <!-- only instrument things that have changed since last time -->
                                                   <modified>
                                                        <param name="cache.cachefile" value="instrumentcache.properties" />
                                                   </modified>
                                              </and>
                                         </fileset>
                                    </instrumentWicket>
                               </target>
                          
                               <target name="copyWicketInstrumentedClasses" depends="instrument" if="instrumentAtBuildTime">
                                    <mkdir dir="${wicketClassDestination}" />
                                    <copy todir="${wicketClassDestination}">
                                         <fileset dir="${src.web.dir}">
                                              <include name="**/*.html" />
                                              <include name="seam.properties" />
                                         </fileset>
                                         <fileset dir="${build.instrumented}" includes="**/*.class" />
                                    </copy>
                                    <touch file="webapp/WEB-INF/dev/signal-redeploy.mod"/>
                               </target>
                          
                          </project>
                          





                          • 10. Re: Seam-wicket and hot deployment problem
                            Erdem Agaoglu Newbie

                            Thanks Daniele,


                            With some little modification i managed to get my wicket components instrumented as well. we decided executing a small task after each change is not such a burden and go with it only to find another problem with wicket integration which seems to be a serious bug.


                            I found that wicketFilter is the first one in the FilterChain and when it detects the request as a WicketRequest and processes without problem, it thinks the request is done (request cycle is handled) and does not call chain.doFilter. thus other seam filters including hotDeployFilter are not processed. so we do not see any


                            [org.jboss.seam.init.Initialization] redeploying components



                            in our logs. This may also effect other filters such as redirectFilter and loggingFilter which i'm not sure about what they do. This style might be the intended behaviour but it definitely breaks hot-deployment.


                            I tried this with Seam 2.1.1.GA on both Jboss AS 5 as WAR and Tomcat w/o ejb-container. I'll try Seam snapshot with EAR soon and post the results here.

                            • 11. Re: Seam-wicket and hot deployment problem
                              Clint Popetz Apprentice

                              I found that wicketFilter is the first one in the FilterChain


                              Argh.  The WicketFilter is annotated with:


                              @Filter(within="org.jboss.seam.debug.hotDeployFilter")




                              But in this change the name of the hot deploy filter changed, as it was repackaged. 


                              This is now JBSEAM-3929 , and I'll get a patch up shortly.


                              • 12. Re: Seam-wicket and hot deployment problem
                                Daniele Gariboldi Newbie

                                If possible at all, Google Guice kind-of strict typing would have helped here ;-) ...

                                Many thanks to Erdem Agaoglu for his diagnosis, and Clint Popetz for his quick response

                                • 14. Re: Seam-wicket and hot deployment problem
                                  Clint Popetz Apprentice

                                  Daniele Gariboldi wrote on Feb 03, 2009 16:33:


                                  If possible at all, Google Guice kind-of strict typing would have helped here ;-) ...

                                  Many thanks to Erdem Agaoglu for his diagnosis, and Clint Popetz for his quick response


                                  Yes, I hate all things loosely-typed, more so every day that I maintain a large source base.  Under WebBeans (which Seam will be an implementation of) this would not have happened. 

                                  1 2 Previous Next