Has anyone looked at how Tapestry solved this problem? I know they did some work to make sure reloading happened in a "smart" way.
On Thu, Nov 18, 2010 at 10:44 AM, Igor Vaynberg <igor.vaynb...@gmail.com> wrote: > invoking a constructor on a constructed class can lead to a lot more > weirder state problems. dont forget, constructors dont just add class, > they initialize state. invoking the constructor itself is not enough, > you also need to invoke field initializations that are inlined, etc. > at that point you might as well create a new instance of the page - > since that is what you are essentially doing. > > -igor > > On Thu, Nov 18, 2010 at 4:52 AM, Martijn Dashorst > <martijn.dasho...@gmail.com> wrote: >> I've been trying out jrebel and wicket a couple of times, and I >> thought it didn't work. It does, but the way Wicket development works >> is undoing most of the benefits of using jrebel. >> >> The idea of jrebel is to replace hotswap with something that actually >> works for normal development: adding methods, renaming them, creating >> new (anonymous inner) classes etc, without having to restart your >> application. And that works quite well... >> >> Until you start developing with Wicket. >> >> The problem is that our component hierarchy doesn't work well with >> code replacement. A typical workflow is that you navigate in your >> application to a page, and want to add a new component to it. So you >> go into that class: >> >> public class LinkCounter extends WebPage { >> public LinkCounter() { >> } >> } >> >> add a field: >> >> private int counter; >> >> add a label: >> >> public LinkCounter() { >> add(new Label("counter", new PropertyModel<Integer>(this, "counter))); >> } >> >> <span wicket:id="counter"></span> >> >> add a link: >> >> public LinkCounter() { >> ... >> add(new Link<Void>("click") { >> public void onClick() { >> counter++; >> }); >> } >> } >> >> <a href="#" wicket:id="click">Click me</a> >> >> All is well, and when you refresh the page (as long as you had a >> bookmarkable link to it) it shows the new label and link. You click >> the link and the URL changes from a bookmarkable URL to a link to a >> specific instance. >> >> Now you want to add another link: >> >> add(new Link<Void>("minus") { >> public void onClick() { >> counter--; >> } >> }); >> >> Don't forget to modify the markup: >> <span wicket:id="minus"></span> >> >> JRebel does its thing: adding the code to the constructor including >> the anonymous inner class. You refresh your page and are presented >> with a component not found exception: minus is added in the markup, >> but not in the java code >> >> The problem is that jrebel doesn't invoke the constructor (again) when >> replacing the code. Moving the code to onInitialize() might enable the >> jrebel plugin to call that method when it modifies a component class. >> This won't work because you typically then get: >> >> java.lang.IllegalArgumentException: A child with id 'counter' >> already exists: >> >> Now we could ask folks to use addOrReplace() instead of add(), or we >> could relax the multi add restriction to alleviate this problem. >> >> I wouldn't be against relaxing add() and deprecating addOrReplace(). >> >> Now calling onInitialize again on a constructed component might open >> up another can of worms. >> >> Is this something worth pursuing? Or should we just write an article >> with how to do jrebel no-redeploy wicket coding? >> >> Martijn >> >