Re: JRebel and wicket
Martijn Dashorst 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. > My first question would be if there is any way to recreate the state of the page object? Does it have to persist between all requests? E.g. if I go to a different page and come back will it be the same object? And if that's the case is it possible to add something like ?reload to the end of the URL to recreate the instance when necessary? That would likely be an easier solution than using addOrReplace(). Jevgeni Kabanov -- View this message in context: http://apache-wicket.1842946.n4.nabble.com/JRebel-and-wicket-tp3048578p3049236.html Sent from the Forum for Wicket Core developers mailing list archive at Nabble.com.
Re: JRebel and wicket
tapestry's component hierarchy is static and it separates state from actual objects via bytecode mangling. so there reloading works for a lot of cases, but will probably not work for the usecase martijn is talking about where you need to add new component and new state. there was a thread on tss about it when it first came out. -igor On Thu, Nov 18, 2010 at 7:53 AM, James Carman wrote: > 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 > 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 >> 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(this, >>> "counter))); >>> } >>> >>> >>> >>> add a link: >>> >>> public LinkCounter() { >>> ... >>> add(new Link("click") { >>> public void onClick() { >>> counter++; >>> }); >>> } >>> } >>> >>> Click me >>> >>> 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("minus") { >>> public void onClick() { >>> counter--; >>> } >>> }); >>> >>> Don't forget to modify the markup: >>> >>> >>> 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 >>> >> >
Re: JRebel and wicket
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 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 > 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(this, "counter))); >> } >> >> >> >> add a link: >> >> public LinkCounter() { >> ... >> add(new Link("click") { >> public void onClick() { >> counter++; >> }); >> } >> } >> >> Click me >> >> 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("minus") { >> public void onClick() { >> counter--; >> } >> }); >> >> Don't forget to modify the markup: >> >> >> 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 >> >
Re: JRebel and wicket
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 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(this, "counter))); > } > > > > add a link: > > public LinkCounter() { > ... > add(new Link("click") { > public void onClick() { > counter++; > }); > } > } > > Click me > > 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("minus") { > public void onClick() { > counter--; > } > }); > > Don't forget to modify the markup: > > > 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 >
Re: JRebel and wicket
Last time I tried to give JRebel some love this issue made me drop it again (If I remember the situation correctly): Imagine you are developing a new page "HomePage" which has a single component public HomePage() { add(new Label("foo", ...) { }); } later on add another component public HomePage() { add(new TextField("bar", ...) { }); add(new Label("foo", ...) { }); } --> JRebel throws a "SuperClassChangedError" when trying to replace HomePage$1 This also happens when you change a component type (e.g. Link --> BookmarkableLink) or in similar situations. It's a known limitation (and no change in sight) http://www.zeroturnaround.com/forum/topic.php?id=875 :-( Am 18.11.2010 um 15:19 schrieb Carl-Eric Menzel: > On Thu, 18 Nov 2010 14:25:40 +0100 > Martijn Dashorst wrote: > >> Relaxing the add() method has been proposed before (by Eelco). It is >> not something new, and if it helps people using jrebel to improve >> their productivity, that would be a great side effect. > > I agree it would be a good side effect, but not a change worth doing > just for the benefit of JRebel :) - only if the change adds something > worthwhile on its own. > > I just googled for Eelco's original proposal to give add() the > semantics of addOrReplace(), since I didn't even know about that > proposal. > > I agree with what you say about "final" and the clear semantics of > add() and addOrReplace(). I like the fact that with the current > semantics I can choose whether I want to definitely add (and get an > exception in case of a bug) or whether I want to, well, add or > replace :-) > > Usually I prefer a slight bit of additional typing over an > ambiguous/unclear API. > > Maybe someone who uses JRebel (I don't) can ask the JRebel guys about > better support for this. > > Carl-Eric > www.wicketbuch.de
Re: JRebel and wicket
On Thu, 18 Nov 2010 14:25:40 +0100 Martijn Dashorst wrote: > Relaxing the add() method has been proposed before (by Eelco). It is > not something new, and if it helps people using jrebel to improve > their productivity, that would be a great side effect. I agree it would be a good side effect, but not a change worth doing just for the benefit of JRebel :) - only if the change adds something worthwhile on its own. I just googled for Eelco's original proposal to give add() the semantics of addOrReplace(), since I didn't even know about that proposal. I agree with what you say about "final" and the clear semantics of add() and addOrReplace(). I like the fact that with the current semantics I can choose whether I want to definitely add (and get an exception in case of a bug) or whether I want to, well, add or replace :-) Usually I prefer a slight bit of additional typing over an ambiguous/unclear API. Maybe someone who uses JRebel (I don't) can ask the JRebel guys about better support for this. Carl-Eric www.wicketbuch.de
Re: JRebel and wicket
Yes, but the "final" is a special modifier - translated to wicket one would expect a method "addUnique(...)" and not the strict add we currently have - now we have a strict "add(..)" and a nonstrict "addOrReplace(..)" Best, Korbinian Am 18.11.10 14:49, schrieb Martijn Dashorst: Well, the compiler will give you an error when you do: final String foo = "Foo"; foo = "Bar"; The difference is in naming: add() currently does exactly what it says. addOrReplace does also exactly what it says. Having clear meaningful names is a good thing to have. Deprecating add in favor of addOrReplace() would have a different effect: more verbose (but meaningful) code... Martijn On Thu, Nov 18, 2010 at 2:40 PM, Korbinian Bachl - privat wrote: Hi, I don't use jRebel but the differentiation of the add and addOrReplace method is something that I still don't understand what it's good for. Actually if you do in java: String foo; foo = new String("world"); no one ever would think about throwing an error because one does foo = new String("no World"); later on This add(new Label("foo","message")); should behave IMHO the same as overwriting objects (and here we just put a new object to the add method) is just natural in java as everyone of us does it every day. IMHO: make addOrReplace deprecated in next 1.4 release and give add the same behaviour as current addOrReplace; in 1.5 addOrReplace can be stripped completely; my 2 cents - now flame on me :) Am 18.11.10 14:25, schrieb Martijn Dashorst: Relaxing the add() method has been proposed before (by Eelco). It is not something new, and if it helps people using jrebel to improve their productivity, that would be a great side effect. The workaround is indeed to go back to a different page and do the appropriate clicks again. Martijn
Re: JRebel and wicket
Well, the compiler will give you an error when you do: final String foo = "Foo"; foo = "Bar"; The difference is in naming: add() currently does exactly what it says. addOrReplace does also exactly what it says. Having clear meaningful names is a good thing to have. Deprecating add in favor of addOrReplace() would have a different effect: more verbose (but meaningful) code... Martijn On Thu, Nov 18, 2010 at 2:40 PM, Korbinian Bachl - privat wrote: > Hi, > > I don't use jRebel but the differentiation of the add and addOrReplace > method is something that I still don't understand what it's good for. > > Actually if you do in java: > > String foo; > > foo = new String("world"); > > no one ever would think about throwing an error because one does > > foo = new String("no World"); later on > > This add(new Label("foo","message")); should behave IMHO the same as > overwriting objects (and here we just put a new object to the add method) is > just natural in java as everyone of us does it every day. > > IMHO: make addOrReplace deprecated in next 1.4 release and give add the same > behaviour as current addOrReplace; in 1.5 addOrReplace can be stripped > completely; > > my 2 cents - now flame on me :) > > > > Am 18.11.10 14:25, schrieb Martijn Dashorst: >> >> Relaxing the add() method has been proposed before (by Eelco). It is >> not something new, and if it helps people using jrebel to improve >> their productivity, that would be a great side effect. >> >> The workaround is indeed to go back to a different page and do the >> appropriate clicks again. >> >> Martijn > -- Become a Wicket expert, learn from the best: http://wicketinaction.com
Re: JRebel and wicket
Hi, I don't use jRebel but the differentiation of the add and addOrReplace method is something that I still don't understand what it's good for. Actually if you do in java: String foo; foo = new String("world"); no one ever would think about throwing an error because one does foo = new String("no World"); later on This add(new Label("foo","message")); should behave IMHO the same as overwriting objects (and here we just put a new object to the add method) is just natural in java as everyone of us does it every day. IMHO: make addOrReplace deprecated in next 1.4 release and give add the same behaviour as current addOrReplace; in 1.5 addOrReplace can be stripped completely; my 2 cents - now flame on me :) Am 18.11.10 14:25, schrieb Martijn Dashorst: Relaxing the add() method has been proposed before (by Eelco). It is not something new, and if it helps people using jrebel to improve their productivity, that would be a great side effect. The workaround is indeed to go back to a different page and do the appropriate clicks again. Martijn
Re: JRebel and wicket
Relaxing the add() method has been proposed before (by Eelco). It is not something new, and if it helps people using jrebel to improve their productivity, that would be a great side effect. The workaround is indeed to go back to a different page and do the appropriate clicks again. Martijn
Re: JRebel and wicket
On Thu, 18 Nov 2010 13:52:32 +0100 Martijn Dashorst wrote: > 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? Good question. So far I'm +0.5 on just documenting it. Is it widespread enough to warrant changing the way Wicket works just to cater to a non-free(!) development tool? It seems to me that it would rather be an issue for the JRebel guys to address within their product. I'm not using JRebel at the moment, but according to what James wrote, it seems to work nicely even without this. Carl-Eric www.wicketbuch.de
Re: JRebel and wicket
I think there would be so many hidden gotchas that it is not worth it. The myriad of strange bugs that could come along with it would be much harder to figure out than the issues you describe of the constructor not running again. In most applications, it wouldn't be that difficult to start back at a bookmarkable page when you make an incompatible change. Jeremy Thomerson http://wickettraining.com -- sent from my "smart" phone, so please excuse spelling, formatting, or compiler errors On Nov 18, 2010 7:53 AM, "Martijn Dashorst" 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(this, "counter))); } add a link: public LinkCounter() { ... add(new Link("click") { public void onClick() { counter++; }); } } Click me 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("minus") { public void onClick() { counter--; } }); Don't forget to modify the markup: 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
Re: JRebel and wicket
Email them. They have a wicket plugin and they're very responsive On Nov 18, 2010 7:53 AM, "Martijn Dashorst" 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(this, "counter))); > } > > > > add a link: > > public LinkCounter() { > ... > add(new Link("click") { > public void onClick() { > counter++; > }); > } > } > > Click me > > 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("minus") { > public void onClick() { > counter--; > } > }); > > Don't forget to modify the markup: > > > 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
Re: JRebel and wicket
I've used jrebel pretty successfully with wicket. There are a lot more compatible changes you can make than non-compatible ones. On Nov 18, 2010 7:53 AM, "Martijn Dashorst" 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(this, "counter))); > } > > > > add a link: > > public LinkCounter() { > ... > add(new Link("click") { > public void onClick() { > counter++; > }); > } > } > > Click me > > 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("minus") { > public void onClick() { > counter--; > } > }); > > Don't forget to modify the markup: > > > 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
JRebel and wicket
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(this, "counter))); } add a link: public LinkCounter() { ... add(new Link("click") { public void onClick() { counter++; }); } } Click me 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("minus") { public void onClick() { counter--; } }); Don't forget to modify the markup: 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