You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@pivot.apache.org by Michael Bushe <mi...@bushe.com> on 2010/06/22 05:53:06 UTC

Re: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation and an annotation processor for application context message listener

In my experience in supporting users of the EventBus, in both the open
source world and in professional teams, weak references are not something to
be feared.  This is because:
1) Weak references fail fast.
2) Weak reference semantics can be documented.  Make the API's clear, make
the doc clear, make the examples clear.  Document the anti-pattern, put it
in the FAQ.
3) Assume your users are smarter than you might think.  WeakReferences are
pretty easy to understand.  Even if a rookie doesn't understand them, you
can make it a teachable moment.
4) WeakReferences are clean and simple.  Managaging listener lifecycle is
like managing memory in C- it a buggy job that sucks productivity and bloats
code.
5) In the 6 years of the EventBus' life, only one user posted a "this
doesn't work" question because they didn't RTFM.

Greg, you didn't detail many of the "number of issues" with WeakReferences,
so I'm not sure what the perception is, but in my experience WeakReferences
are better since the lifecycle of the listener is generally (90%+)
equivalent to the lifecycle of the component that defines the listener.

One issue mentioned is the use of an anonymous inner class (a questionable
pattern anyway), but when annotations are available users generally use that
more terse route rather than using an anonymous class.  When developers use
the anonymous class anti-pattern, it fails quickly and they change it -
often forcing them to think about garbage collection in their apps, which is
a great thing.  The corollary of using .subscribe(new XXXSubscriber()) is
even worse when using strong references - without a reference it's
impossible to clean up.

I think the encapsulation argument  is extremely weak.  Firstly, most UI
developers don't care too much about building extensible classes, but even
when they do, I prefer the opposite effect: Each method that is annotated as
a subscriber becomes part of the contract of the component.  This is a form
of programming by contract that is very powerful.  It says, "whenever this
event is fired, I'm going to call this method."  Derived classes can
manipulate the behavior as needed.  Hiding it is equivalent to the static
final listeners that are all over the Swing framework - it stops extension
and customization in it's tracks. I went into this pub/sub
programming-by-contract method quite a bit in the
article<http://eventbus.org/confluence/pages/viewpage.action?pageId=819222#EventBus%26ApachePivotorRefactoringUIstoUsePub-Sub-Contracts>I
wrote on the EventBus+Pivot.  Lastly, if you don't like that idea, you
can
easily create private fields that are listeners.

The best argument for weak references is that strong references generally
suck.   Strong references have the opposite effects listed above:
1) Strong references cause memory "leaks" that don't fail fast.  They fail
very slowly and insiduously.  They are often not caught until production.
2) Strong reference issues are hard to document.
3) Even smart, experienced developers wind up wasting hours or days tracking
down memory leaks before they find the culprit.
4) Lifecycle management of listeners is not always easy.  It is error prone
and bloats code.  Even in the easy cases, it's easily forgotten and
difficult to test for.

Note: The Spring ActionScript EventBus shifted (is shifting?) from
defaulting to strong to defaulting to weak.

I look forward to seeing how the MessageBus API develops.

Michael Bushe
Principal
Bushe Enterprises, Inc.
michael@bushe.com
www.bushe.com
www.mindfulsoftware.com
www.eventbus.org

On Mon, Jun 21, 2010 at 4:33 PM, aappddeevv <aa...@verizon.net> wrote:

> I think that's fair to do.
>
> -----Original Message-----
> From: Greg Brown [mailto:gkbrown@mac.com]
> Sent: Monday, June 21, 2010 2:11 PM
> To: dev@pivot.apache.org
> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
> annotation
> and an annotation processor for application context message listener
>
> It doesn't necessarily need to be used by other parts of the framework to
> go
> in pivot-core. It just needs to be generally useful and not have any
> dependencies on the other libraries.
>
> I'm not sure what else, if anything, I would want it to do - it is really
> only meant to provide simple intra-application messaging services without a
> lot of overhead or the need for an external library.
>
> One advantage to moving it to org.apache.pivot.util is that listener
> implementations would not require so much typing (MessageBusListener is
> shorter than ApplicationContextMessageListener). Also, since (like
> WTKXSerializer) it isn't strictly dependent on WTK, it probably does not
> belong there.
>
> G
>
> On Jun 21, 2010, at 11:53 AM, aappddeevv wrote:
>
> > Yes. But I would leave it there for now. For simple messaging it is
> > sufficient. More thought is needed. My current thinking is that unless it
> > used by pivot internally, and hence drives need & evolution, it could be
> > better to use something else.
> >
> >
> > -----Original Message-----
> > From: Greg Brown [mailto:gkbrown@mac.com]
> > Sent: Monday, June 21, 2010 9:52 AM
> > To: dev@pivot.apache.org
> > Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
> annotation
> > and an annotation processor for application context message listener
> >
> >> One thing I am finding is for annotations and auto-registering, that the
> >> machinery dominates the actual messaging code in ApplicationContext.
> >
> > ApplicationContext is large, but the message handling code itself is
> pretty
> > small - it is just a few methods:
> >
> > subscribe()
> > unsubscribe()
> > sendMessage()
> > queueMessage()
> >
> > I have actually been wondering if it might make sense to move it to a
> core
> > class, such as org.apache.pivot.util.MessageBus so that non-UI
> applications
> > can also use it. The only thing specific to WTK is queueMessage(), but
> that
> > could either remain in ApplicationContext and be implemented in terms of
> > MessageBus, or it could potentially be eliminated - the code in that
> method
> > could easily be implemented at the application level.
> >
>
>

RE: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation and an annotation processor for application context message listener

Posted by aappddeevv <aa...@verizon.net>.
Folks, while interesting, I suggest we delay this conversation until later
when something is submitted. Then we can rally the conversation around some
concrete items.



-----Original Message-----
From: Greg Brown [mailto:gkbrown@mac.com] 
Sent: Tuesday, June 22, 2010 10:30 AM
To: dev@pivot.apache.org
Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation
and an annotation processor for application context message listener

AFAIK, EventBus doesn't have any dependencies on Pivot, nor vice versa.
There is also nothing in Pivot that would preclude a developer from using
EventBus in a Pivot app.

On Jun 22, 2010, at 10:09 AM, Noel Grandin wrote:

> Hi
> 
> This argument seems to be running in circles a little.
> 
> I personally don't particularly like the EventBus style of doing things,
> but I'm perfectly happy for people to pick their own style of development.
> 
> I don't see that sufficient of the Pivot developers are sufficiently
> keen to make this part of the Pivot library itself (I could be wrong),
> but I don't anything that prevents people from using the EventBus
> library together with Pivot.
> 
> (Am I correct? Does EventBus require any additional support from Pivot
> itself? It doesn't seem like it from what I read.)
> 
> In which case I suggest that we mark this feature request as "Thanks,
> feel free to keep developing your idea, but we're not keen on
> incorporating it right now".
> 
> -- Noel Grandin
> 
> 


Re: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation and an annotation processor for application context message listener

Posted by Greg Brown <gk...@mac.com>.
AFAIK, EventBus doesn't have any dependencies on Pivot, nor vice versa. There is also nothing in Pivot that would preclude a developer from using EventBus in a Pivot app.

On Jun 22, 2010, at 10:09 AM, Noel Grandin wrote:

> Hi
> 
> This argument seems to be running in circles a little.
> 
> I personally don't particularly like the EventBus style of doing things,
> but I'm perfectly happy for people to pick their own style of development.
> 
> I don't see that sufficient of the Pivot developers are sufficiently
> keen to make this part of the Pivot library itself (I could be wrong),
> but I don't anything that prevents people from using the EventBus
> library together with Pivot.
> 
> (Am I correct? Does EventBus require any additional support from Pivot
> itself? It doesn't seem like it from what I read.)
> 
> In which case I suggest that we mark this feature request as "Thanks,
> feel free to keep developing your idea, but we're not keen on
> incorporating it right now".
> 
> -- Noel Grandin
> 
> 


Re: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation and an annotation processor for application context message listener

Posted by Noel Grandin <no...@gmail.com>.
Hi

This argument seems to be running in circles a little.

I personally don't particularly like the EventBus style of doing things,
but I'm perfectly happy for people to pick their own style of development.

I don't see that sufficient of the Pivot developers are sufficiently
keen to make this part of the Pivot library itself (I could be wrong),
but I don't anything that prevents people from using the EventBus
library together with Pivot.

(Am I correct? Does EventBus require any additional support from Pivot
itself? It doesn't seem like it from what I read.)

In which case I suggest that we mark this feature request as "Thanks,
feel free to keep developing your idea, but we're not keen on
incorporating it right now".

-- Noel Grandin



Re: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation and an annotation processor for application context message listener

Posted by Greg Brown <gk...@mac.com>.
> This is dead wrong.  If component A adds a subscriber and component A goes
> away, the subscriber must be removed.

That's only true if something else maintains a reference to the listener, which is generally not the case when using anonymous inner classes as listeners.

>> Anonymous inner classes are not a questionable design pattern...To me,
>> they are somewhat akin to closures, which
>> also seemed strange at first but are the cornerstone of many currently
>> popular languages.
> 
> They aren't closures and a main motivation
> for getting Closures in Java is because anonymous inner classes are a
> suboptimal at best.

I didn't say they were closures - I said they were akin to closures. Also, at least one of the proposals for implementing closures in Java is effectively syntactic sugar around anonymous inner classes (though I'm not sure if that is the one that is actually being implemented for Java 7).

>> I am not familiar with techniques for using annotations to replace
>> anonymous inner classes. Can you provide some examples?
> 
> There are a number of detailed examples in the article and demo I wrote on
> Pivot and the EventBus and sent to you a few months ago.  Did you read it
> yet?

I read it. I did not memorize it.

>>> I think the encapsulation argument  is extremely weak.  Firstly, most UI
>>> developers don't care too much about building extensible classes
>> 
>> It's not a question of extensibility - it is about method visibility. When
>> your class implements an interface, all listener methods by necessity become
>> public.
> 
> This is a good design since it allows the component to be tested in
> isolation.  

It is not good design. It breaks encapsulation, and thus violates a basic OO principle. You should not be making a list selection change listener part of your public API, for example. It allows an arbitrary caller to simulate a change event, which may leave your class in an inconsistent state.

If you want to test something in isolation, you can make the methods package private and create a JUnit test that lives in the same package.

> Besides, if you use annotations, you don't need to implement an interface.

And thus lose the compile-time benefits of using an interface.


Re: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation and an annotation processor for application context message listener

Posted by Michael Bushe <mi...@bushe.com>.
On Tue, Jun 22, 2010 at 8:57 AM, Greg Brown <gk...@mac.com> wrote

> > in my experience WeakReferences
> > are better since the lifecycle of the listener is generally (90%+)
> > equivalent to the lifecycle of the component that defines the listener.
>
> I mentioned this in my previous email, and I think it is actually a much
> stronger argument for strong references: In this case, you don't need to
> worry about unregistering the listener anyways, so weak references add
> almost no value.
>
>
This is dead wrong.  If component A adds a subscriber and component A goes
away, the subscriber must be removed.

Take out pub/sub and it's still wrong: If component A adds a listener to
component B and component A goes away, the listener must be removed.

THE SUBSCRIBER HAS THE SAME LIFECYCLE AS THE COMPONENT.


> Anonymous inner classes are not a questionable design pattern. They have a
> valid use case in event handling, also described in my previous email. Once
> you get used to the syntax (which I'll admit seemed a bit strange at first),
> they become quite useful. To me, they are somewhat akin to closures, which
> also seemed strange at first but are the cornerstone of many currently
> popular languages.


Huh?  Just because you don't question them doesn't mean they are not
questionable.  Lots of other people question them.  Google it if you are
interested in what other people think.  Personally, I've written hundreds of
them so I'm "used to the syntax." They aren't closures and a main motivation
for getting Closures in Java is because anonymous inner classes are a
suboptimal at best.


> > when annotations are available users generally use that
> > more terse route rather than using an anonymous class.
>
> I am not familiar with techniques for using annotations to replace
> anonymous inner classes. Can you provide some examples?
>


There are a number of detailed examples in the article and demo I wrote on
Pivot and the EventBus and sent to you a few months ago.  Did you read it
yet?



>
> > I think the encapsulation argument  is extremely weak.  Firstly, most UI
> > developers don't care too much about building extensible classes
>
> It's not a question of extensibility - it is about method visibility. When
> your class implements an interface, all listener methods by necessity become
> public. Any other class can now invoke the listener method, effectively
> spoofing the event. This is a poor design that inner classes allow you to
> avoid.
>

This is a good design since it allows the component to be tested in
isolation.  Spoofing events is sometimes a nice way to get things done in
normal (non-test) development too. Encapsulation in UI development is way
overrated.  There's already so much exposed just by extending a base class.


Besides, if you use annotations, you don't need to implement an interface.



>
> Also, if your class needs to respond to multiple events, it must now
> implement multiple interfaces. This further bloats its public API and
> exposes it to additional misuse.
>

Most components already implement a ton of interfaces and adding more to
describe all the responsibilities of a class is better than trying to hide a
bloated class with a lot of hidden features.  Besides, if you use
annotations, you don't need to implement an interface.


>
> > Lastly, if you don't like that idea, you can easily create private fields
> that are listeners.
>
> I'm not sure how you could do this without inner classes.
>
> They would be inner classes, but since they are fields, they are not
anonymous and thus are lifecycle'd with the component.

Re: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation and an annotation processor for application context message listener

Posted by Greg Brown <gk...@mac.com>.
> Greg, you didn't detail many of the "number of issues" with WeakReferences,

Most of them are related to different approaches we might take to support weak references - I left them out because there are other stronger arguments against weak references and didn't want to muddy the rest of the email.

> in my experience WeakReferences
> are better since the lifecycle of the listener is generally (90%+)
> equivalent to the lifecycle of the component that defines the listener.

I mentioned this in my previous email, and I think it is actually a much stronger argument for strong references: In this case, you don't need to worry about unregistering the listener anyways, so weak references add almost no value.

> One issue mentioned is the use of an anonymous inner class (a questionable
> pattern anyway)

Anonymous inner classes are not a questionable design pattern. They have a valid use case in event handling, also described in my previous email. Once you get used to the syntax (which I'll admit seemed a bit strange at first), they become quite useful. To me, they are somewhat akin to closures, which also seemed strange at first but are the cornerstone of many currently popular languages.

> when annotations are available users generally use that
> more terse route rather than using an anonymous class.

I am not familiar with techniques for using annotations to replace anonymous inner classes. Can you provide some examples?

> I think the encapsulation argument  is extremely weak.  Firstly, most UI
> developers don't care too much about building extensible classes

It's not a question of extensibility - it is about method visibility. When your class implements an interface, all listener methods by necessity become public. Any other class can now invoke the listener method, effectively spoofing the event. This is a poor design that inner classes allow you to avoid.

Also, if your class needs to respond to multiple events, it must now implement multiple interfaces. This further bloats its public API and exposes it to additional misuse.

> Lastly, if you don't like that idea, you can easily create private fields that are listeners.

I'm not sure how you could do this without inner classes.



Re: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation and an annotation processor for application context message listener

Posted by Greg Brown <gk...@mac.com>.
And so the argument is to base your design on a garbage collection scheme that may or may not be employed by the currently installed JVM, simply to avoid calling removeListener() in the few cases that the lifetime of the listener isn't itself tied to the lifetime of the component? That's doesn't seem like sound development advice to me. Might as well time some for loops to see how many iterations your animation should run for while you're at it.  ;-)

I can potentially see an argument for weak references in a message bus framework where there is no component that will be garbage collected and thus reclaim the listener as well. So maybe it is worth considering there. But I certainly don't see that as a valid argument against using strong listeners elsewhere.

On Jun 22, 2010, at 8:59 AM, Noel Grandin wrote:

> 
> It was quite a while ago that I tried, probably around JDK 1.2.2.
> 
> I've only ever run across a couple of memory leaks related to strong
> listeners, and they were dead-easy to find and kill - just follow the
> this$0 reference.
> 
> Weak listeners on the other hand, manifested as UI controls that would
> work for a while, and then stop listening. Which was a major pain to
> find and fix.
> 
> You're right - this is much less of a problem with modern VM's because
> the GC strategy so aggressively collects short-lived objects.
> 
> -- Noel Grandin
> 
> Michael Bushe wrote:
>> How long ago was that experience with weak listeners?  VMs since 1.5
>> (maybe 1.4) would collect a weak listener before the next statement
>> after subscribe() executes.  Try to get a test to pass with a weak
>> listener, it's been a long time since I've seen it.
>> 
>> Even if that were not true, failing after a few minutes is a lot
>> better than a memory leak as slow to close as the BP's Gulf Gusher.
>> 
>> Michael Bushe
>> Principal
>> Bushe Enterprises, Inc.
>> michael@bushe.com <ma...@bushe.com>
>> www.bushe.com <http://www.bushe.com>
>> www.mindfulsoftware.com <http://www.mindfulsoftware.com>
>> www.eventbus.org <http://www.eventbus.org>
>> 
>> 
>> On Tue, Jun 22, 2010 at 2:59 AM, Noel Grandin <noelgrandin@gmail.com
>> <ma...@gmail.com>> wrote:
>> 
>>    Hi
>> 
>>    Unfortunately, weak listeners don't "fail fast". In my experience,
>>    with
>>    large applications, weak listeners generally take a couple of
>>    minutes to
>>    fail, which makes them quite painful to track down.
>> 
>>    I think the reason you don't see this issue is because your primary
>>    pattern doesn't use anonymous inner classes.
>> 
>>    But yes, I can see how weak listeners will make life-cycle management
>>    easier when your listeners are methods on a normal class.
>> 
>>    -- Noel Grandin
>> 
>>    Michael Bushe wrote:
>>> In my experience in supporting users of the EventBus, in both
>>    the open
>>> source world and in professional teams, weak references are not
>>    something to
>>> be feared.  This is because:
>>> 1) Weak references fail fast.
>>> 2) Weak reference semantics can be documented.  Make the API's
>>    clear, make
>>> the doc clear, make the examples clear.  Document the
>>    anti-pattern, put it
>>> in the FAQ.
>>> 3) Assume your users are smarter than you might think.
>>     WeakReferences are
>>> pretty easy to understand.  Even if a rookie doesn't understand
>>    them, you
>>> can make it a teachable moment.
>>> 4) WeakReferences are clean and simple.  Managaging listener
>>    lifecycle is
>>> like managing memory in C- it a buggy job that sucks
>>    productivity and bloats
>>> code.
>>> 5) In the 6 years of the EventBus' life, only one user posted a
>>    "this
>>> doesn't work" question because they didn't RTFM.
>>> 
>>> Greg, you didn't detail many of the "number of issues" with
>>    WeakReferences,
>>> so I'm not sure what the perception is, but in my experience
>>    WeakReferences
>>> are better since the lifecycle of the listener is generally (90%+)
>>> equivalent to the lifecycle of the component that defines the
>>    listener.
>>> 
>>> One issue mentioned is the use of an anonymous inner class (a
>>    questionable
>>> pattern anyway), but when annotations are available users
>>    generally use that
>>> more terse route rather than using an anonymous class.  When
>>    developers use
>>> the anonymous class anti-pattern, it fails quickly and they
>>    change it -
>>> often forcing them to think about garbage collection in their
>>    apps, which is
>>> a great thing.  The corollary of using .subscribe(new
>>    XXXSubscriber()) is
>>> even worse when using strong references - without a reference it's
>>> impossible to clean up.
>>> 
>>> I think the encapsulation argument  is extremely weak.  Firstly,
>>    most UI
>>> developers don't care too much about building extensible
>>    classes, but even
>>> when they do, I prefer the opposite effect: Each method that is
>>    annotated as
>>> a subscriber becomes part of the contract of the component.
>>     This is a form
>>> of programming by contract that is very powerful.  It says,
>>    "whenever this
>>> event is fired, I'm going to call this method."  Derived classes can
>>> manipulate the behavior as needed.  Hiding it is equivalent to
>>    the static
>>> final listeners that are all over the Swing framework - it stops
>>    extension
>>> and customization in it's tracks. I went into this pub/sub
>>> programming-by-contract method quite a bit in the
>>> 
>>    article<http://eventbus.org/confluence/pages/viewpage.action?pageId=819222#EventBus%26ApachePivotorRefactoringUIstoUsePub-Sub-Contracts>I
>>> wrote on the EventBus+Pivot.  Lastly, if you don't like that
>>    idea, you
>>> can
>>> easily create private fields that are listeners.
>>> 
>>> The best argument for weak references is that strong references
>>    generally
>>> suck.   Strong references have the opposite effects listed above:
>>> 1) Strong references cause memory "leaks" that don't fail fast.
>>     They fail
>>> very slowly and insiduously.  They are often not caught until
>>    production.
>>> 2) Strong reference issues are hard to document.
>>> 3) Even smart, experienced developers wind up wasting hours or
>>    days tracking
>>> down memory leaks before they find the culprit.
>>> 4) Lifecycle management of listeners is not always easy.  It is
>>    error prone
>>> and bloats code.  Even in the easy cases, it's easily forgotten and
>>> difficult to test for.
>>> 
>>> Note: The Spring ActionScript EventBus shifted (is shifting?) from
>>> defaulting to strong to defaulting to weak.
>>> 
>>> I look forward to seeing how the MessageBus API develops.
>>> 
>>> Michael Bushe
>>> Principal
>>> Bushe Enterprises, Inc.
>>> michael@bushe.com <ma...@bushe.com>
>>> www.bushe.com <http://www.bushe.com>
>>> www.mindfulsoftware.com <http://www.mindfulsoftware.com>
>>> www.eventbus.org <http://www.eventbus.org>
>>> 
>>> On Mon, Jun 21, 2010 at 4:33 PM, aappddeevv
>>    <aappddeevv@verizon.net <ma...@verizon.net>> wrote:
>>> 
>>> 
>>>> I think that's fair to do.
>>>> 
>>>> -----Original Message-----
>>>> From: Greg Brown [mailto:gkbrown@mac.com <ma...@mac.com>]
>>>> Sent: Monday, June 21, 2010 2:11 PM
>>>> To: dev@pivot.apache.org <ma...@pivot.apache.org>
>>>> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
>>>> annotation
>>>> and an annotation processor for application context message
>>    listener
>>>> 
>>>> It doesn't necessarily need to be used by other parts of the
>>    framework to
>>>> go
>>>> in pivot-core. It just needs to be generally useful and not
>>    have any
>>>> dependencies on the other libraries.
>>>> 
>>>> I'm not sure what else, if anything, I would want it to do - it
>>    is really
>>>> only meant to provide simple intra-application messaging
>>    services without a
>>>> lot of overhead or the need for an external library.
>>>> 
>>>> One advantage to moving it to org.apache.pivot.util is that
>>    listener
>>>> implementations would not require so much typing
>>    (MessageBusListener is
>>>> shorter than ApplicationContextMessageListener). Also, since (like
>>>> WTKXSerializer) it isn't strictly dependent on WTK, it probably
>>    does not
>>>> belong there.
>>>> 
>>>> G
>>>> 
>>>> On Jun 21, 2010, at 11:53 AM, aappddeevv wrote:
>>>> 
>>>> 
>>>>> Yes. But I would leave it there for now. For simple messaging
>>    it is
>>>>> sufficient. More thought is needed. My current thinking is
>>    that unless it
>>>>> used by pivot internally, and hence drives need & evolution,
>>    it could be
>>>>> better to use something else.
>>>>> 
>>>>> 
>>>>> -----Original Message-----
>>>>> From: Greg Brown [mailto:gkbrown@mac.com <ma...@mac.com>]
>>>>> Sent: Monday, June 21, 2010 9:52 AM
>>>>> To: dev@pivot.apache.org <ma...@pivot.apache.org>
>>>>> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
>>>>> 
>>>> annotation
>>>> 
>>>>> and an annotation processor for application context message
>>    listener
>>>>> 
>>>>> 
>>>>>> One thing I am finding is for annotations and
>>    auto-registering, that the
>>>>>> machinery dominates the actual messaging code in
>>    ApplicationContext.
>>>>>> 
>>>>> ApplicationContext is large, but the message handling code
>>    itself is
>>>>> 
>>>> pretty
>>>> 
>>>>> small - it is just a few methods:
>>>>> 
>>>>> subscribe()
>>>>> unsubscribe()
>>>>> sendMessage()
>>>>> queueMessage()
>>>>> 
>>>>> I have actually been wondering if it might make sense to move
>>    it to a
>>>>> 
>>>> core
>>>> 
>>>>> class, such as org.apache.pivot.util.MessageBus so that non-UI
>>>>> 
>>>> applications
>>>> 
>>>>> can also use it. The only thing specific to WTK is
>>    queueMessage(), but
>>>>> 
>>>> that
>>>> 
>>>>> could either remain in ApplicationContext and be implemented
>>    in terms of
>>>>> MessageBus, or it could potentially be eliminated - the code
>>    in that
>>>>> 
>>>> method
>>>> 
>>>>> could easily be implemented at the application level.
>>>>> 
>>>>> 
>>>> 
>>>> 
>>> 
>> 
>> 
> 


Re: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation and an annotation processor for application context message listener

Posted by Noel Grandin <no...@gmail.com>.
It was quite a while ago that I tried, probably around JDK 1.2.2.

I've only ever run across a couple of memory leaks related to strong
listeners, and they were dead-easy to find and kill - just follow the
this$0 reference.

Weak listeners on the other hand, manifested as UI controls that would
work for a while, and then stop listening. Which was a major pain to
find and fix.

You're right - this is much less of a problem with modern VM's because
the GC strategy so aggressively collects short-lived objects.

-- Noel Grandin

Michael Bushe wrote:
> How long ago was that experience with weak listeners?  VMs since 1.5
> (maybe 1.4) would collect a weak listener before the next statement
> after subscribe() executes.  Try to get a test to pass with a weak
> listener, it's been a long time since I've seen it.
>
> Even if that were not true, failing after a few minutes is a lot
> better than a memory leak as slow to close as the BP's Gulf Gusher.
>
> Michael Bushe
> Principal
> Bushe Enterprises, Inc.
> michael@bushe.com <ma...@bushe.com>
> www.bushe.com <http://www.bushe.com>
> www.mindfulsoftware.com <http://www.mindfulsoftware.com>
> www.eventbus.org <http://www.eventbus.org>
>
>
> On Tue, Jun 22, 2010 at 2:59 AM, Noel Grandin <noelgrandin@gmail.com
> <ma...@gmail.com>> wrote:
>
>     Hi
>
>     Unfortunately, weak listeners don't "fail fast". In my experience,
>     with
>     large applications, weak listeners generally take a couple of
>     minutes to
>     fail, which makes them quite painful to track down.
>
>     I think the reason you don't see this issue is because your primary
>     pattern doesn't use anonymous inner classes.
>
>     But yes, I can see how weak listeners will make life-cycle management
>     easier when your listeners are methods on a normal class.
>
>     -- Noel Grandin
>
>     Michael Bushe wrote:
>     > In my experience in supporting users of the EventBus, in both
>     the open
>     > source world and in professional teams, weak references are not
>     something to
>     > be feared.  This is because:
>     > 1) Weak references fail fast.
>     > 2) Weak reference semantics can be documented.  Make the API's
>     clear, make
>     > the doc clear, make the examples clear.  Document the
>     anti-pattern, put it
>     > in the FAQ.
>     > 3) Assume your users are smarter than you might think.
>      WeakReferences are
>     > pretty easy to understand.  Even if a rookie doesn't understand
>     them, you
>     > can make it a teachable moment.
>     > 4) WeakReferences are clean and simple.  Managaging listener
>     lifecycle is
>     > like managing memory in C- it a buggy job that sucks
>     productivity and bloats
>     > code.
>     > 5) In the 6 years of the EventBus' life, only one user posted a
>     "this
>     > doesn't work" question because they didn't RTFM.
>     >
>     > Greg, you didn't detail many of the "number of issues" with
>     WeakReferences,
>     > so I'm not sure what the perception is, but in my experience
>     WeakReferences
>     > are better since the lifecycle of the listener is generally (90%+)
>     > equivalent to the lifecycle of the component that defines the
>     listener.
>     >
>     > One issue mentioned is the use of an anonymous inner class (a
>     questionable
>     > pattern anyway), but when annotations are available users
>     generally use that
>     > more terse route rather than using an anonymous class.  When
>     developers use
>     > the anonymous class anti-pattern, it fails quickly and they
>     change it -
>     > often forcing them to think about garbage collection in their
>     apps, which is
>     > a great thing.  The corollary of using .subscribe(new
>     XXXSubscriber()) is
>     > even worse when using strong references - without a reference it's
>     > impossible to clean up.
>     >
>     > I think the encapsulation argument  is extremely weak.  Firstly,
>     most UI
>     > developers don't care too much about building extensible
>     classes, but even
>     > when they do, I prefer the opposite effect: Each method that is
>     annotated as
>     > a subscriber becomes part of the contract of the component.
>      This is a form
>     > of programming by contract that is very powerful.  It says,
>     "whenever this
>     > event is fired, I'm going to call this method."  Derived classes can
>     > manipulate the behavior as needed.  Hiding it is equivalent to
>     the static
>     > final listeners that are all over the Swing framework - it stops
>     extension
>     > and customization in it's tracks. I went into this pub/sub
>     > programming-by-contract method quite a bit in the
>     >
>     article<http://eventbus.org/confluence/pages/viewpage.action?pageId=819222#EventBus%26ApachePivotorRefactoringUIstoUsePub-Sub-Contracts>I
>     > wrote on the EventBus+Pivot.  Lastly, if you don't like that
>     idea, you
>     > can
>     > easily create private fields that are listeners.
>     >
>     > The best argument for weak references is that strong references
>     generally
>     > suck.   Strong references have the opposite effects listed above:
>     > 1) Strong references cause memory "leaks" that don't fail fast.
>      They fail
>     > very slowly and insiduously.  They are often not caught until
>     production.
>     > 2) Strong reference issues are hard to document.
>     > 3) Even smart, experienced developers wind up wasting hours or
>     days tracking
>     > down memory leaks before they find the culprit.
>     > 4) Lifecycle management of listeners is not always easy.  It is
>     error prone
>     > and bloats code.  Even in the easy cases, it's easily forgotten and
>     > difficult to test for.
>     >
>     > Note: The Spring ActionScript EventBus shifted (is shifting?) from
>     > defaulting to strong to defaulting to weak.
>     >
>     > I look forward to seeing how the MessageBus API develops.
>     >
>     > Michael Bushe
>     > Principal
>     > Bushe Enterprises, Inc.
>     > michael@bushe.com <ma...@bushe.com>
>     > www.bushe.com <http://www.bushe.com>
>     > www.mindfulsoftware.com <http://www.mindfulsoftware.com>
>     > www.eventbus.org <http://www.eventbus.org>
>     >
>     > On Mon, Jun 21, 2010 at 4:33 PM, aappddeevv
>     <aappddeevv@verizon.net <ma...@verizon.net>> wrote:
>     >
>     >
>     >> I think that's fair to do.
>     >>
>     >> -----Original Message-----
>     >> From: Greg Brown [mailto:gkbrown@mac.com <ma...@mac.com>]
>     >> Sent: Monday, June 21, 2010 2:11 PM
>     >> To: dev@pivot.apache.org <ma...@pivot.apache.org>
>     >> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
>     >> annotation
>     >> and an annotation processor for application context message
>     listener
>     >>
>     >> It doesn't necessarily need to be used by other parts of the
>     framework to
>     >> go
>     >> in pivot-core. It just needs to be generally useful and not
>     have any
>     >> dependencies on the other libraries.
>     >>
>     >> I'm not sure what else, if anything, I would want it to do - it
>     is really
>     >> only meant to provide simple intra-application messaging
>     services without a
>     >> lot of overhead or the need for an external library.
>     >>
>     >> One advantage to moving it to org.apache.pivot.util is that
>     listener
>     >> implementations would not require so much typing
>     (MessageBusListener is
>     >> shorter than ApplicationContextMessageListener). Also, since (like
>     >> WTKXSerializer) it isn't strictly dependent on WTK, it probably
>     does not
>     >> belong there.
>     >>
>     >> G
>     >>
>     >> On Jun 21, 2010, at 11:53 AM, aappddeevv wrote:
>     >>
>     >>
>     >>> Yes. But I would leave it there for now. For simple messaging
>     it is
>     >>> sufficient. More thought is needed. My current thinking is
>     that unless it
>     >>> used by pivot internally, and hence drives need & evolution,
>     it could be
>     >>> better to use something else.
>     >>>
>     >>>
>     >>> -----Original Message-----
>     >>> From: Greg Brown [mailto:gkbrown@mac.com <ma...@mac.com>]
>     >>> Sent: Monday, June 21, 2010 9:52 AM
>     >>> To: dev@pivot.apache.org <ma...@pivot.apache.org>
>     >>> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
>     >>>
>     >> annotation
>     >>
>     >>> and an annotation processor for application context message
>     listener
>     >>>
>     >>>
>     >>>> One thing I am finding is for annotations and
>     auto-registering, that the
>     >>>> machinery dominates the actual messaging code in
>     ApplicationContext.
>     >>>>
>     >>> ApplicationContext is large, but the message handling code
>     itself is
>     >>>
>     >> pretty
>     >>
>     >>> small - it is just a few methods:
>     >>>
>     >>> subscribe()
>     >>> unsubscribe()
>     >>> sendMessage()
>     >>> queueMessage()
>     >>>
>     >>> I have actually been wondering if it might make sense to move
>     it to a
>     >>>
>     >> core
>     >>
>     >>> class, such as org.apache.pivot.util.MessageBus so that non-UI
>     >>>
>     >> applications
>     >>
>     >>> can also use it. The only thing specific to WTK is
>     queueMessage(), but
>     >>>
>     >> that
>     >>
>     >>> could either remain in ApplicationContext and be implemented
>     in terms of
>     >>> MessageBus, or it could potentially be eliminated - the code
>     in that
>     >>>
>     >> method
>     >>
>     >>> could easily be implemented at the application level.
>     >>>
>     >>>
>     >>
>     >>
>     >
>
>


Re: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation and an annotation processor for application context message listener

Posted by Michael Bushe <mi...@bushe.com>.
How long ago was that experience with weak listeners?  VMs since 1.5 (maybe
1.4) would collect a weak listener before the next statement after
subscribe() executes.  Try to get a test to pass with a weak listener, it's
been a long time since I've seen it.

Even if that were not true, failing after a few minutes is a lot better than
a memory leak as slow to close as the BP's Gulf Gusher.

Michael Bushe
Principal
Bushe Enterprises, Inc.
michael@bushe.com
www.bushe.com
www.mindfulsoftware.com
www.eventbus.org


On Tue, Jun 22, 2010 at 2:59 AM, Noel Grandin <no...@gmail.com> wrote:

> Hi
>
> Unfortunately, weak listeners don't "fail fast". In my experience, with
> large applications, weak listeners generally take a couple of minutes to
> fail, which makes them quite painful to track down.
>
> I think the reason you don't see this issue is because your primary
> pattern doesn't use anonymous inner classes.
>
> But yes, I can see how weak listeners will make life-cycle management
> easier when your listeners are methods on a normal class.
>
> -- Noel Grandin
>
> Michael Bushe wrote:
> > In my experience in supporting users of the EventBus, in both the open
> > source world and in professional teams, weak references are not something
> to
> > be feared.  This is because:
> > 1) Weak references fail fast.
> > 2) Weak reference semantics can be documented.  Make the API's clear,
> make
> > the doc clear, make the examples clear.  Document the anti-pattern, put
> it
> > in the FAQ.
> > 3) Assume your users are smarter than you might think.  WeakReferences
> are
> > pretty easy to understand.  Even if a rookie doesn't understand them, you
> > can make it a teachable moment.
> > 4) WeakReferences are clean and simple.  Managaging listener lifecycle is
> > like managing memory in C- it a buggy job that sucks productivity and
> bloats
> > code.
> > 5) In the 6 years of the EventBus' life, only one user posted a "this
> > doesn't work" question because they didn't RTFM.
> >
> > Greg, you didn't detail many of the "number of issues" with
> WeakReferences,
> > so I'm not sure what the perception is, but in my experience
> WeakReferences
> > are better since the lifecycle of the listener is generally (90%+)
> > equivalent to the lifecycle of the component that defines the listener.
> >
> > One issue mentioned is the use of an anonymous inner class (a
> questionable
> > pattern anyway), but when annotations are available users generally use
> that
> > more terse route rather than using an anonymous class.  When developers
> use
> > the anonymous class anti-pattern, it fails quickly and they change it -
> > often forcing them to think about garbage collection in their apps, which
> is
> > a great thing.  The corollary of using .subscribe(new XXXSubscriber()) is
> > even worse when using strong references - without a reference it's
> > impossible to clean up.
> >
> > I think the encapsulation argument  is extremely weak.  Firstly, most UI
> > developers don't care too much about building extensible classes, but
> even
> > when they do, I prefer the opposite effect: Each method that is annotated
> as
> > a subscriber becomes part of the contract of the component.  This is a
> form
> > of programming by contract that is very powerful.  It says, "whenever
> this
> > event is fired, I'm going to call this method."  Derived classes can
> > manipulate the behavior as needed.  Hiding it is equivalent to the static
> > final listeners that are all over the Swing framework - it stops
> extension
> > and customization in it's tracks. I went into this pub/sub
> > programming-by-contract method quite a bit in the
> > article<
> http://eventbus.org/confluence/pages/viewpage.action?pageId=819222#EventBus%26ApachePivotorRefactoringUIstoUsePub-Sub-Contracts
> >I
> > wrote on the EventBus+Pivot.  Lastly, if you don't like that idea, you
> > can
> > easily create private fields that are listeners.
> >
> > The best argument for weak references is that strong references generally
> > suck.   Strong references have the opposite effects listed above:
> > 1) Strong references cause memory "leaks" that don't fail fast.  They
> fail
> > very slowly and insiduously.  They are often not caught until production.
> > 2) Strong reference issues are hard to document.
> > 3) Even smart, experienced developers wind up wasting hours or days
> tracking
> > down memory leaks before they find the culprit.
> > 4) Lifecycle management of listeners is not always easy.  It is error
> prone
> > and bloats code.  Even in the easy cases, it's easily forgotten and
> > difficult to test for.
> >
> > Note: The Spring ActionScript EventBus shifted (is shifting?) from
> > defaulting to strong to defaulting to weak.
> >
> > I look forward to seeing how the MessageBus API develops.
> >
> > Michael Bushe
> > Principal
> > Bushe Enterprises, Inc.
> > michael@bushe.com
> > www.bushe.com
> > www.mindfulsoftware.com
> > www.eventbus.org
> >
> > On Mon, Jun 21, 2010 at 4:33 PM, aappddeevv <aa...@verizon.net>
> wrote:
> >
> >
> >> I think that's fair to do.
> >>
> >> -----Original Message-----
> >> From: Greg Brown [mailto:gkbrown@mac.com]
> >> Sent: Monday, June 21, 2010 2:11 PM
> >> To: dev@pivot.apache.org
> >> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
> >> annotation
> >> and an annotation processor for application context message listener
> >>
> >> It doesn't necessarily need to be used by other parts of the framework
> to
> >> go
> >> in pivot-core. It just needs to be generally useful and not have any
> >> dependencies on the other libraries.
> >>
> >> I'm not sure what else, if anything, I would want it to do - it is
> really
> >> only meant to provide simple intra-application messaging services
> without a
> >> lot of overhead or the need for an external library.
> >>
> >> One advantage to moving it to org.apache.pivot.util is that listener
> >> implementations would not require so much typing (MessageBusListener is
> >> shorter than ApplicationContextMessageListener). Also, since (like
> >> WTKXSerializer) it isn't strictly dependent on WTK, it probably does not
> >> belong there.
> >>
> >> G
> >>
> >> On Jun 21, 2010, at 11:53 AM, aappddeevv wrote:
> >>
> >>
> >>> Yes. But I would leave it there for now. For simple messaging it is
> >>> sufficient. More thought is needed. My current thinking is that unless
> it
> >>> used by pivot internally, and hence drives need & evolution, it could
> be
> >>> better to use something else.
> >>>
> >>>
> >>> -----Original Message-----
> >>> From: Greg Brown [mailto:gkbrown@mac.com]
> >>> Sent: Monday, June 21, 2010 9:52 AM
> >>> To: dev@pivot.apache.org
> >>> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
> >>>
> >> annotation
> >>
> >>> and an annotation processor for application context message listener
> >>>
> >>>
> >>>> One thing I am finding is for annotations and auto-registering, that
> the
> >>>> machinery dominates the actual messaging code in ApplicationContext.
> >>>>
> >>> ApplicationContext is large, but the message handling code itself is
> >>>
> >> pretty
> >>
> >>> small - it is just a few methods:
> >>>
> >>> subscribe()
> >>> unsubscribe()
> >>> sendMessage()
> >>> queueMessage()
> >>>
> >>> I have actually been wondering if it might make sense to move it to a
> >>>
> >> core
> >>
> >>> class, such as org.apache.pivot.util.MessageBus so that non-UI
> >>>
> >> applications
> >>
> >>> can also use it. The only thing specific to WTK is queueMessage(), but
> >>>
> >> that
> >>
> >>> could either remain in ApplicationContext and be implemented in terms
> of
> >>> MessageBus, or it could potentially be eliminated - the code in that
> >>>
> >> method
> >>
> >>> could easily be implemented at the application level.
> >>>
> >>>
> >>
> >>
> >
>
>

Re: [jira] Commented: (PIVOT-535) Add a @MessageListener annotation and an annotation processor for application context message listener

Posted by Noel Grandin <no...@gmail.com>.
Hi

Unfortunately, weak listeners don't "fail fast". In my experience, with
large applications, weak listeners generally take a couple of minutes to
fail, which makes them quite painful to track down.

I think the reason you don't see this issue is because your primary
pattern doesn't use anonymous inner classes.

But yes, I can see how weak listeners will make life-cycle management
easier when your listeners are methods on a normal class.

-- Noel Grandin

Michael Bushe wrote:
> In my experience in supporting users of the EventBus, in both the open
> source world and in professional teams, weak references are not something to
> be feared.  This is because:
> 1) Weak references fail fast.
> 2) Weak reference semantics can be documented.  Make the API's clear, make
> the doc clear, make the examples clear.  Document the anti-pattern, put it
> in the FAQ.
> 3) Assume your users are smarter than you might think.  WeakReferences are
> pretty easy to understand.  Even if a rookie doesn't understand them, you
> can make it a teachable moment.
> 4) WeakReferences are clean and simple.  Managaging listener lifecycle is
> like managing memory in C- it a buggy job that sucks productivity and bloats
> code.
> 5) In the 6 years of the EventBus' life, only one user posted a "this
> doesn't work" question because they didn't RTFM.
>
> Greg, you didn't detail many of the "number of issues" with WeakReferences,
> so I'm not sure what the perception is, but in my experience WeakReferences
> are better since the lifecycle of the listener is generally (90%+)
> equivalent to the lifecycle of the component that defines the listener.
>
> One issue mentioned is the use of an anonymous inner class (a questionable
> pattern anyway), but when annotations are available users generally use that
> more terse route rather than using an anonymous class.  When developers use
> the anonymous class anti-pattern, it fails quickly and they change it -
> often forcing them to think about garbage collection in their apps, which is
> a great thing.  The corollary of using .subscribe(new XXXSubscriber()) is
> even worse when using strong references - without a reference it's
> impossible to clean up.
>
> I think the encapsulation argument  is extremely weak.  Firstly, most UI
> developers don't care too much about building extensible classes, but even
> when they do, I prefer the opposite effect: Each method that is annotated as
> a subscriber becomes part of the contract of the component.  This is a form
> of programming by contract that is very powerful.  It says, "whenever this
> event is fired, I'm going to call this method."  Derived classes can
> manipulate the behavior as needed.  Hiding it is equivalent to the static
> final listeners that are all over the Swing framework - it stops extension
> and customization in it's tracks. I went into this pub/sub
> programming-by-contract method quite a bit in the
> article<http://eventbus.org/confluence/pages/viewpage.action?pageId=819222#EventBus%26ApachePivotorRefactoringUIstoUsePub-Sub-Contracts>I
> wrote on the EventBus+Pivot.  Lastly, if you don't like that idea, you
> can
> easily create private fields that are listeners.
>
> The best argument for weak references is that strong references generally
> suck.   Strong references have the opposite effects listed above:
> 1) Strong references cause memory "leaks" that don't fail fast.  They fail
> very slowly and insiduously.  They are often not caught until production.
> 2) Strong reference issues are hard to document.
> 3) Even smart, experienced developers wind up wasting hours or days tracking
> down memory leaks before they find the culprit.
> 4) Lifecycle management of listeners is not always easy.  It is error prone
> and bloats code.  Even in the easy cases, it's easily forgotten and
> difficult to test for.
>
> Note: The Spring ActionScript EventBus shifted (is shifting?) from
> defaulting to strong to defaulting to weak.
>
> I look forward to seeing how the MessageBus API develops.
>
> Michael Bushe
> Principal
> Bushe Enterprises, Inc.
> michael@bushe.com
> www.bushe.com
> www.mindfulsoftware.com
> www.eventbus.org
>
> On Mon, Jun 21, 2010 at 4:33 PM, aappddeevv <aa...@verizon.net> wrote:
>
>   
>> I think that's fair to do.
>>
>> -----Original Message-----
>> From: Greg Brown [mailto:gkbrown@mac.com]
>> Sent: Monday, June 21, 2010 2:11 PM
>> To: dev@pivot.apache.org
>> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
>> annotation
>> and an annotation processor for application context message listener
>>
>> It doesn't necessarily need to be used by other parts of the framework to
>> go
>> in pivot-core. It just needs to be generally useful and not have any
>> dependencies on the other libraries.
>>
>> I'm not sure what else, if anything, I would want it to do - it is really
>> only meant to provide simple intra-application messaging services without a
>> lot of overhead or the need for an external library.
>>
>> One advantage to moving it to org.apache.pivot.util is that listener
>> implementations would not require so much typing (MessageBusListener is
>> shorter than ApplicationContextMessageListener). Also, since (like
>> WTKXSerializer) it isn't strictly dependent on WTK, it probably does not
>> belong there.
>>
>> G
>>
>> On Jun 21, 2010, at 11:53 AM, aappddeevv wrote:
>>
>>     
>>> Yes. But I would leave it there for now. For simple messaging it is
>>> sufficient. More thought is needed. My current thinking is that unless it
>>> used by pivot internally, and hence drives need & evolution, it could be
>>> better to use something else.
>>>
>>>
>>> -----Original Message-----
>>> From: Greg Brown [mailto:gkbrown@mac.com]
>>> Sent: Monday, June 21, 2010 9:52 AM
>>> To: dev@pivot.apache.org
>>> Subject: Re: [jira] Commented: (PIVOT-535) Add a @MessageListener
>>>       
>> annotation
>>     
>>> and an annotation processor for application context message listener
>>>
>>>       
>>>> One thing I am finding is for annotations and auto-registering, that the
>>>> machinery dominates the actual messaging code in ApplicationContext.
>>>>         
>>> ApplicationContext is large, but the message handling code itself is
>>>       
>> pretty
>>     
>>> small - it is just a few methods:
>>>
>>> subscribe()
>>> unsubscribe()
>>> sendMessage()
>>> queueMessage()
>>>
>>> I have actually been wondering if it might make sense to move it to a
>>>       
>> core
>>     
>>> class, such as org.apache.pivot.util.MessageBus so that non-UI
>>>       
>> applications
>>     
>>> can also use it. The only thing specific to WTK is queueMessage(), but
>>>       
>> that
>>     
>>> could either remain in ApplicationContext and be implemented in terms of
>>> MessageBus, or it could potentially be eliminated - the code in that
>>>       
>> method
>>     
>>> could easily be implemented at the application level.
>>>
>>>       
>>
>>     
>