[jbossseam-issues] [JBoss JIRA] Updated: (JBSEAM-3594) Wicket instrumentation fails on inherited components

Pete Muir (JIRA) jira-events at lists.jboss.org
Fri Oct 31 11:12:21 EDT 2008


     [ https://jira.jboss.org/jira/browse/JBSEAM-3594?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Pete Muir updated JBSEAM-3594:
------------------------------

    Fix Version/s: 2.1.1.CR1
         Assignee: Pete Muir


> Wicket instrumentation fails on inherited components
> ----------------------------------------------------
>
>                 Key: JBSEAM-3594
>                 URL: https://jira.jboss.org/jira/browse/JBSEAM-3594
>             Project: Seam
>          Issue Type: Bug
>    Affects Versions: 2.1.0.CR1
>            Reporter: Clint Popetz
>            Assignee: Pete Muir
>             Fix For: 2.1.1.CR1
>
>         Attachments: seam-wicket-inheritance.patch
>
>
> Most wicket configuration is done in the constructor, and much component re-use takes place through page and panel inheritance.      
> The generic case in question is:
> class base { 
>   public base() { 
>     add("id",overriddenMethod());
>   }
>   public Component overriddenMethod() {  ...  }
> }
> public class sub extends base { 
>   public sub() { 
>     super();
>     ...
>   }  
>   public Component overriddenMethod() { ... } l
> }
> The subclass WicketHandler initializer won't have run by the time the overriddenMethod has been invoked, so its wicketHandler instance will be null, and the overriddenMethod will throw a null pointer exception.   What I've done is to make the javassist preamble/postamble avoid that NPE by checking to make sure the handler is not null before doing anything.  Since WicketHandler.create() uses the runtime class of the target component, the interception that happens for the base.<init> in the above example will ensure that injections happen for the subclass before the overridden method is called.    
> This check also has to happen when walking the enclosedInstance injections of any class in BijectionInterceptor.injectEnclosingInstances(), because if the above overriddenMethod() were to create an instance of an anonymous inner class, the enclosing instance's handler field will be null.
> Three more bugs related to inheritance in this patch :
> (1) I made WicketComponent.scan() check superclasses, so that it injects for the superclasses as well .    This would be needed, for example, if an overridden method referred to a visible injected field in a superclass.)  
> (2) I've taken out the check that made the instrumentor not instrument abstract classes.  I can't think of a good reason for that check, and it kept me from having abstract superclasses with injections.
> (3) If you override a method, you get an infinite loop, because the synthetic method where the actual code lives will be generated with the same name in both super and subclass, and one will override the other, so that when sub.fooUNIQUE() calls base.foo(), it will call base.fooUNIQUE(), which will be a virtual call to sub.fooUNIQUE().  So I made the synthetic method private, which means it gets an invokespecial instead of an invokevirtual.
> (4) A similar problem with constructors...the preamble was calling getClass().getDeclaredConstructor(), but it now refers directly to the class in question, so that if a subclass has a constructor with the same signature, you don't get an infinite loop when the parent class tries to find its own constructor.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the seam-issues mailing list