Calls to TransformField.getAccess() or TransformMethod.addAdvice()
(and many others) will often create one or more new classes behinds
the scenes.  ComponentClassTransformWorkers make use of such methods.



On Thu, Apr 29, 2010 at 10:33 AM, Christophe Cordenier
<[email protected]> wrote:
> After going into Tapestry core and ioc code i have seen this comment. I
> thought a fresh view on the problem should help, but it's clear that the
> Tapestry community knows its subject deeply.
>
> It keeps on impressing me !!

It's not like its a-priori knowlege; people hit obscure bugs, often do
the research and provide a patch.  I think most of the detective work
on this one was provided by a user. The code base gains experience.

I've found that web apps are easy up to a point, then you cross a line
and things become much more complicated.  Tapestry exists to push that
"line" way, way out ... but it means there's a lot of code and
machinery employed on simple things so that everything continues to
work once you pass the complexity threshold.

Often that complexity represents various cross-cutting concerns.

For example, I was just working on a logout link. The trick is, some
pages allow anonymous access, and some don't. Once logged out, the
code has to determine whether to stay on the current page or go to a
new page.

In an action/view framework, you would have to probably provide a new
parameter to the "component" that renders the logout link, and
manually configure it with where to go after logging out. That's
because a view does not have insight into the action that triggered it
(partially because a view can potentially have a one-to-many
relationship with actions). Thus, the developer has to take on this
bit of complexity ... made more complex in the case where the URL must
incorporate additional data. In Tapestry, that would be a page
activation context, but in a traditional app it could be anything
(extra path or query parameters).

The point is, my code ends up looking like:

        Object onActionFromLogout() {
                authenticationService.logout();

                Component page = resources.getPage();

                boolean canAccessCurrentPageAnonymously = page.getClass()
                                .isAnnotationPresent(AnonymousAccess.class);

                return canAccessCurrentPageAnonymously ? page : Landing.class;
        }

And Tapestry handles the rest; it has already handled the logic about
encoding into the URL that triggers this method that identity of the
page and the activation context for that page.

>
>    /**
>     * This is, of course, a bit of a problem. We don't have an avenue for
> ensuring that this ThreadLocal is destroyed
>     * at the end of the request, and that means a thread can hold a
> reference to the class and the class loader which
>     * loaded it. This may cause redeployment problems (leaked classes and
> class loaders). Apparently JDK 1.6 provides
>     * the APIs to check to see if the current thread has a read lock. So,
> we tend to remove the TL, rather than set its
>     * value to false.
>     */
>    private static class ThreadBoolean extends ThreadLocal<Boolean>
>    {
>       �...@override
>        protected Boolean initialValue()
>        {
>            return false;
>        }
>    }
>
> 2010/4/29 Christophe Cordenier <[email protected]>
>
>> Thanks for clarification.
>>
>> But If i have well understood, a permgen out of memory indicates that we
>> have too many classes loaded by the classloader.
>>
>> After going through the different Workers, I don't see where Tapestry
>> creates more classes than before. At most there is two/three advisors per
>> Worker.
>>
>> I must miss something ?
>>
>> 2010/4/29 Howard Lewis Ship <[email protected]>
>>
>>> When coding (not meta-coding) Java, using static inner classes rather
>>>
>>> than instance inner classes (including anonymous inner classes) is
>>> more efficient, as the inner class instance does not need to hold a
>>> reference to the enclosing object. That's probably what PMD was
>>> getting on about; an inner class can be a memory leak of the enclosing
>>> object if the enclosing object is not needed anymore.
>>>
>>> On Thu, Apr 29, 2010 at 8:07 AM, Christophe Cordenier
>>> <[email protected]> wrote:
>>> > Hi
>>> >
>>> > 2010/4/29 Thiago H. de Paula Figueiredo <[email protected]>
>>> >
>>> >> On Thu, 29 Apr 2010 11:18:55 -0300, Christophe Cordenier <
>>> >> [email protected]> wrote:
>>> >>
>>> >>  Is it not possible to use static inner class with constructors instead
>>> of
>>> >>> using anonymous inner classes ?
>>> >>> Won't this solve a part of the problem ?
>>> >>>
>>> >>
>>> >> I don't think so, as the problem is not how the classes are created,
>>> but
>>> >> the number of them.
>>> >>
>>> >>
>>> > Yes i have well understood this, it's just that i was remembering a rule
>>> > (PMD or Findbug) that told me to turn some of my inner classes to static
>>> for
>>> > the one who do not access to the enclosing class, maybe it's just to
>>> have a
>>> > clean coding style.
>>> >
>>> > Also i don't know exactly how the JVM handles anonymous classes, every
>>> new
>>> > ComponentMethodAdvice() { ... }  ?
>>>
>>> This is Tapestry; to add advice to component method it splits the
>>> method into two and creates a new implementation of the
>>> ComponentMethodInvocation interface that is used to track parameter
>>> values, return values, and thrown exceptions, along with the stack of
>>> method advice.
>>>
>>> >
>>> >
>>> >> --
>>> >> Thiago H. de Paula Figueiredo
>>> >> Independent Java, Apache Tapestry 5 and Hibernate consultant,
>>> developer,
>>> >> and instructor
>>> >> Owner, Ars Machina Tecnologia da Informação Ltda.
>>> >> http://www.arsmachina.com.br
>>> >>
>>> >>
>>> >> ---------------------------------------------------------------------
>>> >> To unsubscribe, e-mail: [email protected]
>>> >> For additional commands, e-mail: [email protected]
>>> >>
>>> >>
>>> >
>>> >
>>> > --
>>> > Regards,
>>> > Christophe Cordenier.
>>> >
>>> > Developer of wooki @wookicentral.com
>>> >
>>>
>>>
>>>
>>> --
>>> Howard M. Lewis Ship
>>>
>>> Creator of Apache Tapestry
>>>
>>> The source for Tapestry training, mentoring and support. Contact me to
>>> learn how I can get you up and productive in Tapestry fast!
>>>
>>> (971) 678-5210
>>> http://howardlewisship.com
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [email protected]
>>> For additional commands, e-mail: [email protected]
>>>
>>>
>>
>>
>> --
>> Regards,
>> Christophe Cordenier.
>>
>> Developer of wooki @wookicentral.com
>>
>
>
>
> --
> Regards,
> Christophe Cordenier.
>
> Developer of wooki @wookicentral.com
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to