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
<ja...@carmanconsulting.com> 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 <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
>>>
>>
>

Reply via email to