Duplicated Resources Loaded With Virgo Server

MyFaces Logo

Yesterday I ran into a problem with resource loading when using MyFaces. As filed on MyFaces JIRA here, the problem is the result of duplicated resources loaded.

As documented in the ticket, my workaround involves the use of a custom factory to provide a custom resource provider. The provider then calls the default implementation, and filters out duplicate results. The custom factory is then hooked into MyFaces using a custom StartupListener, which is registered in web.xml.

Below is highlighted and better formatted version of the fix:

web.xml:

  1. <context-param> 
  2.     <param-name>org.apache.myfaces.FACES_INIT_PLUGINS</param-name> 
  3.     <param-value>my.package.MyFacesStartupListener</param-value> 
  4. </context-param>

MyFacesStartupListener:

  1. public class MyFacesStartupListener implements StartupListener { 
  2.  
  3.     private static final String FACTORY_KEY = FacesConfigResourceProviderFactory.class.getName(); 
  4.  
  5.     public void postDestroy(ServletContextEvent event) { 
  6.     } 
  7.  
  8.     public void postInit(ServletContextEvent event) { 
  9.     } 
  10.  
  11.     public void preDestroy(ServletContextEvent event) { 
  12.     } 
  13.  
  14.     public void preInit(ServletContextEvent event) { 
  15.         ServletContext context = event.getServletContext(); 
  16.         context.setAttribute(FACTORY_KEY, new MyFacesConfigResourceProviderFactory()); 
  17.     } 
  18.  
  19. }

MyFacesConfigResourceProviderFactory:

  1. public class MyFacesConfigResourceProviderFactory 
  2.     extends FacesConfigResourceProviderFactory { 
  3.  
  4.     public FacesConfigResourceProvider createFacesConfigResourceProvider( 
  5.         ExternalContext ectx) { 
  6.         return new MyFacesConfigResourceProvider(); 
  7.     } 
  8.  
  9. } 

MyFacesConfigResourceProvider:

  1. public class MyFacesConfigResourceProvider 
  2.     extends DefaultFacesConfigResourceProvider { 
  3.  
  4.     public Collection<URL> getMetaInfConfigurationResources(ExternalContext ectx)
  5.         throws IOException { 
  6.         Collection<URL> resources = super.getMetaInfConfigurationResources(ectx); 
  7.         Collection<URL> filtered = new HashSet<URL>(); 
  8.         for (URL resource : resources) { 
  9.             if (!filtered.contains(resource)) { 
  10.                 filtered.add(resource); 
  11.             } 
  12.         } 
  13.         return filtered; 
  14.     } 
  15.  
  16. } 

When I have the chance, I will try to produce a reduced testcase and file it against Virgo.