Wicket
  1. Wicket
  2. WICKET-126

Reload Java Classes for Improved Developer Experience

    Details

      Description

      Currently in Wicket it is possible to reload the templates in DEVELOPMENT mode, but it is not possible to reload Java classes. That makes it very painful for the developer, as a server restart is required every time. One can still use hot code replace within the debugger, but that is not reliable and does not work every time, especially when the method signatures change.

      The attached experimental patch addresses that issue by providing a custom classloader and an adaptation of WicketFilter to allow reloading the Wicket application upon a class file change. As soon as a Java class is updated in the classes directories, the corresponding application is reloaded by WicketFilter. Also, bookmarkable pages are properly reloaded.

      On the TODO list:

      • allow to switch off class reloading
      • allow to specify the location of directories containing class files
      • porting to WicketServlet
      • more testing

      I wanted to share this code ASAP for you to test. It is based on branch 1.x.

      Note that part of the code comes from Apache Cocoon, released under the Apache license.

      1. 20061129-wicket-1.x-ReloadingClassLoader
        13 kB
        Jean-Baptiste Quenot
      2. 20061130-wicket-1.x-ReloadingClassLoader
        16 kB
        Jean-Baptiste Quenot
      3. 20061130-wicket-1.x-ReloadingClassLoader
        17 kB
        Jean-Baptiste Quenot
      4. 20061201-wicket-1.x-ReloadingClassLoader
        18 kB
        Jean-Baptiste Quenot
      5. WICKET-126-1.x.patch
        20 kB
        Eelco Hillenius
      6. WICKET-126-trunk.patch
        19 kB
        Eelco Hillenius
      7. 20061203-wicket-1.x-ReloadingClassLoader-includes
        17 kB
        Jean-Baptiste Quenot
      8. 20061203-wicket-1.x-ReloadingClassLoader-includes
        16 kB
        Jean-Baptiste Quenot
      9. 20061205-wicket-1.x-ReloadingClassLoader
        2 kB
        Jean-Baptiste Quenot
      10. 20070114-wicket-1.x-ReloadingWicketFilter
        1 kB
        Jean-Baptiste Quenot
      11. 20070114-wicket-1.x-ReloadingWicketFilter
        1 kB
        Jean-Baptiste Quenot
      12. 20070114-wicket-1.x-ReloadingWicketFilter
        1 kB
        Jean-Baptiste Quenot
      13. 20070114-wicket-1.x-ReloadingWicketFilter
        3 kB
        Jean-Baptiste Quenot

        Activity

        Hide
        Johan Compagner added a comment -

        We need first to have it configurable so that it works only in deployment mode (and i think by default it should still be off even in deployment)

        Also you only reload the classes. What happens to all the instances of that class?? They are still there and they are NOT updated by just reloading the class!
        So we have to flush everything in the second level cache. And invalidate all the http sessions.
        Else you get things like that 2 exact the same things are not equal..

        Show
        Johan Compagner added a comment - We need first to have it configurable so that it works only in deployment mode (and i think by default it should still be off even in deployment) Also you only reload the classes. What happens to all the instances of that class?? They are still there and they are NOT updated by just reloading the class! So we have to flush everything in the second level cache. And invalidate all the http sessions. Else you get things like that 2 exact the same things are not equal..
        Hide
        Johan Compagner added a comment -

        sorry i meant of course development mode. (and then also still by default off)
        Because i don't want it. I use now the ibm jdk that can hotswap much better then suns (method additions/renames/removes can be done)

        Show
        Johan Compagner added a comment - sorry i meant of course development mode. (and then also still by default off) Because i don't want it. I use now the ibm jdk that can hotswap much better then suns (method additions/renames/removes can be done)
        Hide
        Jean-Baptiste Quenot added a comment -

        Please find attached an updated patch:

        • Porting to WicketServlet
        • If an error occurs when the listener is notified, remove the watched object to avoid rethrowing the exception
        Show
        Jean-Baptiste Quenot added a comment - Please find attached an updated patch: Porting to WicketServlet If an error occurs when the listener is notified, remove the watched object to avoid rethrowing the exception
        Hide
        Jean-Baptiste Quenot added a comment -

        Replaces the previous one with same name.

        Show
        Jean-Baptiste Quenot added a comment - Replaces the previous one with same name.
        Hide
        Jean-Baptiste Quenot added a comment -

        This updated patch provides ReloadingWicketServlet and ReloadingWicketFilter, to be used in web.xml instead of WicketServlet and WicketFilter when wishing to activate the reloading of classes.

        Show
        Jean-Baptiste Quenot added a comment - This updated patch provides ReloadingWicketServlet and ReloadingWicketFilter, to be used in web.xml instead of WicketServlet and WicketFilter when wishing to activate the reloading of classes.
        Hide
        Eelco Hillenius added a comment -

        Thanks for the patches. Jean-Baptiste, what application servers did you test this on?

        So now the WicketFilter/ WicketServlet sets the context class loader.

        • might that interfere with non-Wicket code that depends on a certain context class loader (like the application server)?
        • shouldn't we keep a reference to the original loader and set that on the end of the request?
        • other cotchas you can think of?
        Show
        Eelco Hillenius added a comment - Thanks for the patches. Jean-Baptiste, what application servers did you test this on? So now the WicketFilter/ WicketServlet sets the context class loader. might that interfere with non-Wicket code that depends on a certain context class loader (like the application server)? shouldn't we keep a reference to the original loader and set that on the end of the request? other cotchas you can think of?
        Hide
        Eelco Hillenius added a comment -

        Slightly modified patch for 1.x

        Show
        Eelco Hillenius added a comment - Slightly modified patch for 1.x
        Hide
        Eelco Hillenius added a comment -

        Patch for trunk (2.0)

        Show
        Eelco Hillenius added a comment - Patch for trunk (2.0)
        Hide
        Jean-Baptiste Quenot added a comment -

        I tested this with Maven 2's jetty:run (version 6), with a standalone Jetty, and with Eclipse Jetty launcher (version 5).

        I don't know of other code that relies on the thread's context classloader, but you're right we could reset the original reference by the end of the request, just to be clean.

        One of the main gotchas I encountered when activating the reload feature is when using a component manager (like Spring): typically components are instantiated before WicketServlet or WicketFilter, so if the WebApplication relies on those components, they cannot be used as they are loaded in a different classloader (you get a ClassCastException because the same class loaded in two different classloaders is not the same class). To address that issue, I propose to provide means to include and/or exclude specific class name patterns, in order to only load the Wicket components through the reloading classloader. Cocoon does it already in its implementation of its custom ClassLoader. See http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/classloader/DefaultClassLoader.java?revision=477124&view=markup

        Show
        Jean-Baptiste Quenot added a comment - I tested this with Maven 2's jetty:run (version 6), with a standalone Jetty, and with Eclipse Jetty launcher (version 5). I don't know of other code that relies on the thread's context classloader, but you're right we could reset the original reference by the end of the request, just to be clean. One of the main gotchas I encountered when activating the reload feature is when using a component manager (like Spring): typically components are instantiated before WicketServlet or WicketFilter, so if the WebApplication relies on those components, they cannot be used as they are loaded in a different classloader (you get a ClassCastException because the same class loaded in two different classloaders is not the same class). To address that issue, I propose to provide means to include and/or exclude specific class name patterns, in order to only load the Wicket components through the reloading classloader. Cocoon does it already in its implementation of its custom ClassLoader. See http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/classloader/DefaultClassLoader.java?revision=477124&view=markup
        Hide
        Eelco Hillenius added a comment -

        Sounds good to me. How you reckon that would be configured? web.xml?

        Show
        Eelco Hillenius added a comment - Sounds good to me. How you reckon that would be configured? web.xml?
        Hide
        Jean-Baptiste Quenot added a comment -

        Yes, the feature to reload classes can be configured in web.xml. Use:
        <filter-class>wicket.protocol.http.ReloadingWicketFilter</filter-class>
        Instead of:
        <filter-class>wicket.protocol.http.WicketFilter</filter-class>

        Or if you use the servlet:
        <servlet-class>wicket.protocol.http.ReloadingWicketServlet</servlet-class>
        Instead of:
        <servlet-class>wicket.protocol.http.WicketServlet</servlet-class>

        Show
        Jean-Baptiste Quenot added a comment - Yes, the feature to reload classes can be configured in web.xml. Use: <filter-class>wicket.protocol.http.ReloadingWicketFilter</filter-class> Instead of: <filter-class>wicket.protocol.http.WicketFilter</filter-class> Or if you use the servlet: <servlet-class>wicket.protocol.http.ReloadingWicketServlet</servlet-class> Instead of: <servlet-class>wicket.protocol.http.WicketServlet</servlet-class>
        Hide
        Jean-Baptiste Quenot added a comment -

        Just a minor issue: the diff against SharedResourceRequestTarget.java was not supposed to be included. It only improves the error reporting by logging a full stacktrace instead of just an error message, but that is not required for reloading the classes of course.

        Show
        Jean-Baptiste Quenot added a comment - Just a minor issue: the diff against SharedResourceRequestTarget.java was not supposed to be included. It only improves the error reporting by logging a full stacktrace instead of just an error message, but that is not required for reloading the classes of course.
        Hide
        Eelco Hillenius added a comment -

        > he diff against SharedResourceRequestTarget.java was not supposed to be included

        Yeah, I noted that. Originally, I decided to not include the stack trace as I thought it was too much (non-)information. Did you run into a situation where the stack trace helped you track down a problem?

        Show
        Eelco Hillenius added a comment - > he diff against SharedResourceRequestTarget.java was not supposed to be included Yeah, I noted that. Originally, I decided to not include the stack trace as I thought it was too much (non-)information. Did you run into a situation where the stack trace helped you track down a problem?
        Hide
        Eelco Hillenius added a comment -

        >> Sounds good to me. How you reckon that would be configured? web.xml?

        > Yes, the feature to reload classes can be configured in web.xml. Use:
        > <filter-class>wicket.protocol.http.ReloadingWicketFilter</filter-class>

        I actually meant the feature to filter on certain classes. Would that be init parameters?

        Show
        Eelco Hillenius added a comment - >> Sounds good to me. How you reckon that would be configured? web.xml? > Yes, the feature to reload classes can be configured in web.xml. Use: > <filter-class>wicket.protocol.http.ReloadingWicketFilter</filter-class> I actually meant the feature to filter on certain classes. Would that be init parameters?
        Hide
        Jean-Baptiste Quenot added a comment -

        About SharedResourceRequestTarget.java: yes I needed the full stacktrace to diagnose classloading related problems.

        And about the class name pattern matching, I'd prefer doing it programmatically because they will be most probably static settings. The problem with init parameters is that the filtering would have to be specific to the corresponding WicketFilter, it would not be a global static setting, but an instance variable of ReloadingClassLoader.

        Show
        Jean-Baptiste Quenot added a comment - About SharedResourceRequestTarget.java: yes I needed the full stacktrace to diagnose classloading related problems. And about the class name pattern matching, I'd prefer doing it programmatically because they will be most probably static settings. The problem with init parameters is that the filtering would have to be specific to the corresponding WicketFilter, it would not be a global static setting, but an instance variable of ReloadingClassLoader.
        Hide
        Eelco Hillenius added a comment -

        yeah, this seems to be one of these rare occasions where static is better than the application scope.

        Show
        Eelco Hillenius added a comment - yeah, this seems to be one of these rare occasions where static is better than the application scope.
        Hide
        Eelco Hillenius added a comment -

        First batch is in with some tweaks. Default wicketfilter/servlet works fine, but next step is to focus on the reloading etc, which I haven't tested yet. Also tbd is filtering of classes to load with the custom class loader.

        Show
        Eelco Hillenius added a comment - First batch is in with some tweaks. Default wicketfilter/servlet works fine, but next step is to focus on the reloading etc, which I haven't tested yet. Also tbd is filtering of classes to load with the custom class loader.
        Hide
        Eelco Hillenius added a comment -

        Oh first batch == 1.3 only at this time.

        Show
        Eelco Hillenius added a comment - Oh first batch == 1.3 only at this time.
        Hide
        Eelco Hillenius added a comment -

        Working with two separate classloaders like this is pretty problematic; we end up having part of the classes loaded in one loader, and part of the classes - which depend on each other - loaded in another and then in some cases loaded twice with different class instances. I'm not an expert when it comes to class loading, but I can't see how that can work without plugin in in the application server directly. It looks to me like we don't 'own' enough of the class loading process to really get this working this way.

        If you want to play yourself, here is a patch:

        Index: /Users/eelcohillenius/Documents/workspace/wicket/src/main/java/wicket/protocol/http/WicketFilter.java
        ===================================================================
        — /Users/eelcohillenius/Documents/workspace/wicket/src/main/java/wicket/protocol/http/WicketFilter.java (revision 481678)
        +++ /Users/eelcohillenius/Documents/workspace/wicket/src/main/java/wicket/protocol/http/WicketFilter.java (working copy)
        @@ -400,6 +400,12 @@
        final Class factoryClass = Thread.currentThread().getContextClassLoader()
        .loadClass(appFactoryClassName);

        + Class c1 = factoryClass.getInterfaces()[0];
        + Class c2 = IWebApplicationFactory.class;
        + System.err.println(c1.getName() + " == " + c2.getName() + " ? " + c1.equals(c2));
        + System.err.println("cll1 == " + c1.getClassLoader() + ", cll2 == "
        + + c2.getClassLoader());
        +
        // Instantiate the factory
        return (IWebApplicationFactory)factoryClass.newInstance();
        }

        I would typically just use the debugger, but these system.err printlns illustrate what I mean. It would give a dump like this:

        Exception in thread "main" wicket.WicketRuntimeException: Application factory class wicket.spring.SpringWebApplicationFactory must implement IWebApplicationFactory
        at wicket.protocol.http.WicketFilter.getApplicationFactory(WicketFilter.java:414)
        at wicket.protocol.http.WicketFilter.init(WicketFilter.java:335)
        at wicket.protocol.http.ReloadingWicketFilter.init(ReloadingWicketFilter.java:75)
        at org.mortbay.jetty.servlet.FilterHolder.doStart(FilterHolder.java:95)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:38)
        at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:545)
        at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1133)
        at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:420)
        at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:457)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:38)
        at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:156)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:38)
        at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:119)
        at org.mortbay.jetty.Server.doStart(Server.java:210)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:38)
        ...

        You should be able to test this using for instance a spring web app or such.

        Any ideas?

        Show
        Eelco Hillenius added a comment - Working with two separate classloaders like this is pretty problematic; we end up having part of the classes loaded in one loader, and part of the classes - which depend on each other - loaded in another and then in some cases loaded twice with different class instances. I'm not an expert when it comes to class loading, but I can't see how that can work without plugin in in the application server directly. It looks to me like we don't 'own' enough of the class loading process to really get this working this way. If you want to play yourself, here is a patch: Index: /Users/eelcohillenius/Documents/workspace/wicket/src/main/java/wicket/protocol/http/WicketFilter.java =================================================================== — /Users/eelcohillenius/Documents/workspace/wicket/src/main/java/wicket/protocol/http/WicketFilter.java (revision 481678) +++ /Users/eelcohillenius/Documents/workspace/wicket/src/main/java/wicket/protocol/http/WicketFilter.java (working copy) @@ -400,6 +400,12 @@ final Class factoryClass = Thread.currentThread().getContextClassLoader() .loadClass(appFactoryClassName); + Class c1 = factoryClass.getInterfaces() [0] ; + Class c2 = IWebApplicationFactory.class; + System.err.println(c1.getName() + " == " + c2.getName() + " ? " + c1.equals(c2)); + System.err.println("cll1 == " + c1.getClassLoader() + ", cll2 == " + + c2.getClassLoader()); + // Instantiate the factory return (IWebApplicationFactory)factoryClass.newInstance(); } I would typically just use the debugger, but these system.err printlns illustrate what I mean. It would give a dump like this: Exception in thread "main" wicket.WicketRuntimeException: Application factory class wicket.spring.SpringWebApplicationFactory must implement IWebApplicationFactory at wicket.protocol.http.WicketFilter.getApplicationFactory(WicketFilter.java:414) at wicket.protocol.http.WicketFilter.init(WicketFilter.java:335) at wicket.protocol.http.ReloadingWicketFilter.init(ReloadingWicketFilter.java:75) at org.mortbay.jetty.servlet.FilterHolder.doStart(FilterHolder.java:95) at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:38) at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:545) at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1133) at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:420) at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:457) at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:38) at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:156) at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:38) at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:119) at org.mortbay.jetty.Server.doStart(Server.java:210) at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:38) ... You should be able to test this using for instance a spring web app or such. Any ideas?
        Hide
        Eelco Hillenius added a comment -

        Oops. And now for the printlns

        wicket.protocol.http.IWebApplicationFactory == wicket.protocol.http.IWebApplicationFactory ? false
        cll1 == wicket.application.ReloadingClassLoader@33c253, cll2 == sun.misc.Launcher$AppClassLoader@a9c85c

        Show
        Eelco Hillenius added a comment - Oops. And now for the printlns wicket.protocol.http.IWebApplicationFactory == wicket.protocol.http.IWebApplicationFactory ? false cll1 == wicket.application.ReloadingClassLoader@33c253, cll2 == sun.misc.Launcher$AppClassLoader@a9c85c
        Hide
        Johan Compagner added a comment -

        and then to also think about that what you test is already wrong because this output:

        cll2 == sun.misc.Launcher$AppClassLoader@a9c85c

        shouldn't even happen. That is the boostrap loader. Normally that class would be loaded by one of the many classloaders of a servlet container.
        But i know how you test with Jetty...

        This will be problematic all the way. The only thing i can think of is really chain all the classloaders.
        And the reloading classloader shouldn't load classes that the parent can load.
        So you have something like:

        bootstrap-tomcat base loader -> web app loader -> reloading classloader.

        and the reloading classloader has a special dir where he loads classes out of. then the other loaders can't see.
        And he only reloads those classes. So that is most likely wat is currently WEB-INF/classes
        That dir shouldn't be there. It should be somewhere else.

        Show
        Johan Compagner added a comment - and then to also think about that what you test is already wrong because this output: cll2 == sun.misc.Launcher$AppClassLoader@a9c85c shouldn't even happen. That is the boostrap loader. Normally that class would be loaded by one of the many classloaders of a servlet container. But i know how you test with Jetty... This will be problematic all the way. The only thing i can think of is really chain all the classloaders. And the reloading classloader shouldn't load classes that the parent can load. So you have something like: bootstrap-tomcat base loader -> web app loader -> reloading classloader. and the reloading classloader has a special dir where he loads classes out of. then the other loaders can't see. And he only reloads those classes. So that is most likely wat is currently WEB-INF/classes That dir shouldn't be there. It should be somewhere else.
        Hide
        Eelco Hillenius added a comment -

        > That is the boostrap loader. Normally that class would be loaded by one of the many classloaders of a servlet container.
        But i know how you test with Jetty...

        I test with the Jetty starter class that we provide with the project. I rarely use JettyLauncher for anything these days

        > and the reloading classloader has a special dir where he loads classes out of. then the other loaders can't see.
        And he only reloads those classes. So that is most likely wat is currently WEB-INF/classes
        That dir shouldn't be there. It should be somewhere else.

        Yeah, that what e.g. Jetty does in it's transforming class loader. But we'd have to take full control over the class loading/ replace the class loading of the container. That's just way out of scope for our framework.

        So Jean-Baptiste, if you don't have fresh ideas that we overlooked on how to tackle this, I think we should rollback the related changes.

        Show
        Eelco Hillenius added a comment - > That is the boostrap loader. Normally that class would be loaded by one of the many classloaders of a servlet container. But i know how you test with Jetty... I test with the Jetty starter class that we provide with the project. I rarely use JettyLauncher for anything these days > and the reloading classloader has a special dir where he loads classes out of. then the other loaders can't see. And he only reloads those classes. So that is most likely wat is currently WEB-INF/classes That dir shouldn't be there. It should be somewhere else. Yeah, that what e.g. Jetty does in it's transforming class loader. But we'd have to take full control over the class loading/ replace the class loading of the container. That's just way out of scope for our framework. So Jean-Baptiste, if you don't have fresh ideas that we overlooked on how to tackle this, I think we should rollback the related changes.
        Hide
        Jean-Baptiste Quenot added a comment -

        Handling of includes/excludes

        Default setup is:
        excludes.add("wicket.*");
        includes.add("wicket.examples.*");

        Code comes from Apache Cocoon under the ASL

        Show
        Jean-Baptiste Quenot added a comment - Handling of includes/excludes Default setup is: excludes.add("wicket.*"); includes.add("wicket.examples.*"); Code comes from Apache Cocoon under the ASL
        Hide
        Jean-Baptiste Quenot added a comment -

        Updated patch, to be able to get rid of the order of processing (inclusions handled before exclusions). Use a sign (+ or -) to include or exclude the pattern. Order is significant.

        patterns.add("-wicket.*");
        patterns.add("+wicket.examples.*");

        Show
        Jean-Baptiste Quenot added a comment - Updated patch, to be able to get rid of the order of processing (inclusions handled before exclusions). Use a sign (+ or -) to include or exclude the pattern. Order is significant. patterns.add("-wicket.*"); patterns.add("+wicket.examples.*");
        Hide
        Jean-Baptiste Quenot added a comment -
        • Use ArrayList instead of HashSet for the patterns to keep the order in which they were added
        • Add methods includePattern() and excludePattern()
        • Set default patterns in the static block
        Show
        Jean-Baptiste Quenot added a comment - Use ArrayList instead of HashSet for the patterns to keep the order in which they were added Add methods includePattern() and excludePattern() Set default patterns in the static block
        Hide
        Eelco Hillenius added a comment -

        Implemented for 1.3.x. Still has to be implemented for 2.0.

        Also needs some warnings in the documentation as to what extend it can be used.

        Show
        Eelco Hillenius added a comment - Implemented for 1.3.x. Still has to be implemented for 2.0. Also needs some warnings in the documentation as to what extend it can be used.
        Hide
        Jean-Baptiste Quenot added a comment -

        Do you intend to work on the trunk version? Otherwise I can provide the patch. It should not be difficult to port to trunk.

        Show
        Jean-Baptiste Quenot added a comment - Do you intend to work on the trunk version? Otherwise I can provide the patch. It should not be difficult to port to trunk.
        Hide
        Eelco Hillenius added a comment -

        It can be in trunk for now. Before we release (either 1.3 or 2.0), we have to decide where it ultimately will stay. Probably extensions, but I'd like to run a vote on that first.

        It would also be interesting to hear people's experiences with this filter.

        Show
        Eelco Hillenius added a comment - It can be in trunk for now. Before we release (either 1.3 or 2.0), we have to decide where it ultimately will stay. Probably extensions, but I'd like to run a vote on that first. It would also be interesting to hear people's experiences with this filter.
        Hide
        Igor Vaynberg added a comment -

        if you want to hear other's experiences you should probably post that to the user list i dont think people randomly read jira tickets.

        Show
        Igor Vaynberg added a comment - if you want to hear other's experiences you should probably post that to the user list i dont think people randomly read jira tickets.
        Hide
        Jean-Baptiste Quenot added a comment -

        Just attached a patch that contains an improvement to the Javadoc.

        Show
        Jean-Baptiste Quenot added a comment - Just attached a patch that contains an improvement to the Javadoc.
        Hide
        Jean-Baptiste Quenot added a comment -

        Adding support for ReloadingWicketServlet

        Show
        Jean-Baptiste Quenot added a comment - Adding support for ReloadingWicketServlet
        Hide
        Eelco Hillenius added a comment -

        Assigning this to you now JBQ. Don't know whether you consider this being done or that you are still working on it.

        Show
        Eelco Hillenius added a comment - Assigning this to you now JBQ. Don't know whether you consider this being done or that you are still working on it.
        Hide
        Jean-Baptiste Quenot added a comment -
        Show
        Jean-Baptiste Quenot added a comment - Note: part of the work in branch 1.x has been filed under WICKET-133 in revision 481653 See http://svn.apache.org/viewvc/incubator/wicket/branches/wicket-1.x/wicket/src/main/java/wicket/protocol/http/ContextParamWebApplicationFactory.java?r1=481653&r2=481652&pathrev=481653 Ported to trunk, closing now.

          People

          • Assignee:
            Jean-Baptiste Quenot
            Reporter:
            Jean-Baptiste Quenot
          • Votes:
            1 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development