[jsr-314-open-mirror] [jsr-314-open] Cannot register listener for PostConstructApplicationEvent and PreDestroyApplicationEvent using @ListenerFor annotation

Leonardo Uribe lu4242 at gmail.com
Thu Sep 30 19:38:32 EDT 2010


Hi

This issue is related to

https://issues.apache.org/jira/browse/MYFACES-2509 @ListenerFor not
processed for global system events

On JSF 2.0 the following system events were added:

javax.faces.event.PostConstructApplicationEvent
javax.faces.event.PreDestroyApplicationEvent

javax.faces.event.PostConstructCustomScopeEvent
javax.faces.event.PreDestroyCustomScopeEvent

javax.faces.event.PostConstructViewMapEvent
javax.faces.event.PreDestroyViewMapEvent

And the following component system events were added:

javax.faces.event.PostAddToViewEvent
javax.faces.event.PreRemoveFromViewEvent
javax.faces.event.PostRestoreStateEvent

javax.faces.event.PreValidateEvent
javax.faces.event.PostValidateEvent

javax.faces.event.PreRenderComponentEvent
javax.faces.event.PreRenderViewEvent

The javadoc of @ListenerFor annotation is clear to say which classes could
be a valid target for this annotation:

"....The default implementation must support attaching this annotation to
UIComponent or Renderer classes. In both cases, the
annotation processing described herein must commence during the
implementation of any variant of Application.createComponent()  and
must complete before the UIComponent instance is returned from
createComponent()...."

Long time ago on MYFACES-2509, it was mentioned those classes could not be
the only target:

Jan-Kees van Andel

JK>> Hrm, it looks like the JavaDoc can be interpreted in multiple ways.
JK>>
JK>> What I read, is that it should be possible for classes that implement
JK>> SystemEventListener, to listen to SystemEvents.
JK>>
JK>> For example: PostConstructApplicationEvent
JK>>
JK>> The current implementation cannot deal with this event, because it
occurs
JK>> before the ApplicationImpl code is invoked (there is no component tree
at
JK>> that time). For this reason, we need to check it @startup.
JK>>
JK>> But because its so ambiguous, I suggest to leave it out of the (myfaces
core) beta release.

Thinking about how to enhance some myfaces projects and reading some
documentation I notice this usage on the book The Complete
Reference JavaServer Faces 2.0 Page 509 (just type on google @ListenerFor
PostConstructApplicationEvent and you will find it):

@ListenerFor(systemEventClass =
javax.faces.event.PostConstructApplicationEvent.class)
public class TestSystemEventListener implements SystemEventListener {
   ...
}

The previous example does not work on both myfaces and mojarra, because both
implement what @ListenerFor javadoc says. But note this
syntax should be valid on JSF 2.0, at least for
PostConstructApplicationEvent and PreDestroyApplicationEvent.

I tried something more elaborated like this:

@ManagedBean(name="myCustomListener", eager=true)
@ApplicationScoped
@ListenersFor({
@ListenerFor(systemEventClass=PostConstructApplicationEvent.class),
@ListenerFor(systemEventClass=PreDestroyApplicationEvent.class)
})
public class SimpleFacesConfigListener implements SystemEventListener
{
   ...
}

Does not work too, but the fact is that syntax should be valid too. Well,
maybe we can use @PostConstruct and @PreDestroy and have the
same effect, but it is worth to mention it.

It could be good to know what do you think about it. I feel inclined to
include it in myfaces, but better to ask first.

Anyway, it could be good if you can consider if it is worth or not adding
@ListenerFor annotation support for JSF application scope objects and
factories (ex: Application, RenderKit, StateManager, ViewHandler .....). I'm
not very sure about it, but better to mention it.

Should I create a spec issue for this one? I think yes.

In another topic, looking for more issues, I notice a side effect testing
this example:

  <system-event-listener>

<system-event-listener-class>org.apache.myfaces.testListenerFor.SimpleFacesConfigListener</system-event-listener-class>

<system-event-class>javax.faces.event.PostConstructApplicationEvent</system-event-class>
  </system-event-listener>
  <system-event-listener>

<system-event-listener-class>org.apache.myfaces.testListenerFor.SimpleFacesConfigListener</system-event-listener-class>

<system-event-class>javax.faces.event.PreDestroyApplicationEvent</system-event-class>
  </system-event-listener>

public class SimpleFacesConfigListener implements SystemEventListener
{
   ...
}

In this case according to both myfaces and mojarra implementation, the
object instance that receive PostConstructApplicationEvent is
not the same that receive PreDestroyApplicationEvent, so the listener should
be "stateless", but the spec does not warn about this
fact (in theory it should be).

regards,

Leonardo Uribe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jsr-314-open-mirror/attachments/20100930/bdee17b2/attachment-0002.html 


More information about the jsr-314-open-mirror mailing list