[ 
https://issues.apache.org/jira/browse/MYFACES-4138?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16145473#comment-16145473
 ] 

Paul Nicolucci commented on MYFACES-4138:
-----------------------------------------

The following spec issue was opened for this: 
https://github.com/javaee/javaserverfaces-spec/issues/1449

> Issue with some JSF Artifacts eligible for injection
> ----------------------------------------------------
>
>                 Key: MYFACES-4138
>                 URL: https://issues.apache.org/jira/browse/MYFACES-4138
>             Project: MyFaces Core
>          Issue Type: Bug
>    Affects Versions: 2.2.12, 2.3.0-beta
>            Reporter: Eduardo Breijo
>
> When we register an ActionListener or PhaseListener globally via 
> faces-config.xml, the instance that is created per listener is injectable, 
> that is, we can do @Inject in the instance. These listeners are added to the 
> injected bean storage list in the application map and as a result, we can 
> call @PreDestroy and @PostConstruct on this scenario. 
> On the other hand, when facelet elements <f:actionListener/> and 
> <f:phaseListener/> are used, the instances that are created (per click for 
> action listener or per view for phase listener) are not injectable. That is, 
> we cannot do @Inject inside of these objects. And @PreDestroy and 
> @PostConstruct are not invoked on them.
> I supposes we want to have the same behavior in both cases.
> To solve this issue, we can probably do a similar logic as what was done in 
> FacesConfigurator that we call inject on the instance, and then store that in 
> the injected bean storage list. We can add that logic in the 
> ActionListenerHandler and PhaseListenerHandler classes after the instance is 
> created.
> // Code snippet
> instance = (ActionListener) ReflectionUtil.forName(this.type).newInstance();
> ExternalContext externalContext = faces.getExternalContext();
> // Note that we have to make INJECTED_BEAN_STORAGE_KEY public
> List<BeanEntry> injectedBeanStorage = 
> (List<BeanEntry>)externalContext.getApplicationMap().get(FacesConfigurator.INJECTED_BEAN_STORAGE_KEY);
>  
> InjectionProvider injectionProvider = 
> InjectionProviderFactory.getInjectionProviderFactory(
>                                                             
> externalContext).getInjectionProvider(externalContext);
> Object creationMetaData = injectionProvider.inject(instance);
> injectedBeanStorage.add(new BeanEntry(instance, creationMetaData));
> injectionProvider.postConstruct(instance, creationMetaData);
> But there is an issue when adding that. Every time we use <f:actionListener/> 
> with type defined but no binding, a new instance is created on every button 
> click, the same will happen with <f:phaseListener/>. These instances are 
> added to the list of injected bean storage, and that reference will exist 
> until app shuts down, creating a memory leak. So we need a way to remove 
> those references from the list once we are out of scope. We might need a 
> different list for this case.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to