wicket-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jeremy Thomerson <jer...@wickettraining.com>
Subject Re: JRebel and wicket
Date Thu, 18 Nov 2010 13:08:12 GMT
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" <martijn.dashorst@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

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message