Hello, Implemented solution 3 in my github repo [1]. I've tested it on JBoss 7.1.0.Final. I need to test it on WAS 8.0.x now.
This solution is fine for my needs : * EAR usage with 0..n webapps * I don't use @JsfPhaseListener in my code * I'm only using CODI JSF Scopes, no other functionnality from CODI. Otherwise, it isn't universal : * if you use @JsfPhaseListener in multiple wars in the same webapp, every phaseListeners will be executed (if PL1 is in webapp1 and PL2 in webapp2, a request to webapp1 will execute PL1 and PL2). * there's a lot of code in CODI relying on classloaders [2] (so it can potentially break on JBoss 7.x when using CODI in a EAR), I've removed classloader usage only for @JsfPhaseListener. I'll use this version and will wait for Deltapike JSF to have a portable solution. Once more thanks Christian and Denis for your help on this issue ! [1] https://github.com/gonzalad/myfaces-extcdi/tree/vas-ear-3 [2] Code relying on classloaders at least : CodiStartupBroadcaster ValidatorFactoryStorage PhaseListenerExtension ApplicationStartupBroadcaster DefaultServiceProvider DefaultServiceProviderContext SimpleServiceProviderContext ClassDeactivatorStorage ConfiguredArtifactUtils PersistenceHelper ViewConfigCache ________________________________ De : Adrian Gonzalez <adr_gonza...@yahoo.fr> À : MyFaces Discussion <users@myfaces.apache.org> Envoyé le : Mercredi 20 mars 2013 16h05 Objet : Re: CODI ViewAccessScoped issue with EAR on JBoss 7.1.x Thanks very much Christian for your help ! So this appears to be a bug/limitation related to CODI usage with an EAR leading to a non portable issue between appservers. I've begun testing some modifications in CODI source which corrects the problem but leads to other limitations. Modification I've made : I'm treating @JsfPhaseListener ad CDI beans and don't use Map<ClassLoader, List<Class<? extends PhaseListener>>> in PhaseListenerExtension anymore. I've changed PhaseListenerExtension#consumePhaseListeners in order to return the list of CDI PhaseListener, i.e. Set<Bean<?>> foundPhaseListenerBeans = beanManager.getBeans(PhaseListener.class, DefaultAnnotation.of(JsfPhaseListener.class)); Now ViewAccessScoped works fine. But If I have @JsfPhaseListener PhaseListener1 in webapp1 and @JsfPhaseListener PhaseListener2 in webapp2, both being in the same EAR, both phaseListeners are registered in the 2 webapps. I'm using a modified version of myfaces-extcdi-bundle-jsf20.jar and package it in the ear. Perhaps I should do a test with the non bundle version (putting JSF jar in the webapp and the remaining ones in the ear) - but I'm pessimistic. So option '3 use CDI to communicate phaseListener class in CODI consumeJsfPhaseListener' doesn't work. Option 1 or 2 remain, but frankly I'm not sure which one is the best (option 2 will work for sure, but I'm not sure CODI team would be interested in incorporating it in the code baseline ;( ). 1. modify ClassUtils.getClassloader add a configurationparameter to return ClassUtils.class.getClassloader(). cons : we're still relying on classloader and potentially will have a pb with another appserver. 2. remove @JsfPhaseListener and rely on classic phaseListeners configured with faces-config.xml Best regards, Adrian N.B. CODI 1.0.5 behaviour : @JsfPhaseListener are not handled as CDI beans (PhaseListenerExtension vetos them). Instead JsfPhaseListener classes are stored in a Map<ClassLoader, List<Class<? extends PhaseListener>>> to communicate info between app startup and request execution (Classloader usage is the root of the problem). ________________________________ De : Christian Beikov <christian.bei...@gmail.com> À : users@myfaces.apache.org Envoyé le : Mercredi 20 mars 2013 14h44 Objet : Re: CODI ViewAccessScoped issue with EAR on JBoss 7.1.x Also tested it, I can confirm that the described behavior occurs. By the way, after the second postback it seems to work. I get an exception in JBoss log about the usage of a TCCL. Sorry but here ends my knowledge, I was thinking that it worked. Hopefully someone one the list can help on this? Mit freundlichen Grüßen, ------------------------------------------------------------------------ *Christian Beikov* Am 20.03.2013 10:04, schrieb Adrian Gonzalez: > Hi Christian, > > Thanks for the update. > I'm also testing on JBoss 7.1.0.Final. > I've modified [1] with your remarks (except dependentWarExcludes which is > deprecated - I don't use overlays for now). > > > Still no luck, I've got the following sysout when clicking on first link of > page http://localhost:8080/viewaccessscoped-web/test.faces. > 09:47:35,644 INFO [stdout] (http--0.0.0.0-8080-1) @PreDestroy > 09:47:35,644 INFO [stdout] (http--0.0.0.0-8080-1) @PostConstruct > > > So ViewAccessScoped bean is reinstantiated. > > I've tested it with both m2e-wtp, and packaging/deploying by hand (mvn clean > package). > > Thanks very much for your help on this topic ! > > [1] https://github.com/gonzalad/codi-ear-viewaccessscoped/tree/ear > > > ----- Mail original ----- > De : Christian Beikov <christian.bei...@gmail.com> > À : users@myfaces.apache.org > Cc : > Envoyé le : Mercredi 20 mars 2013 3h07 > Objet : Re: CODI ViewAccessScoped issue with EAR on JBoss 7.1.x > > I just tested your example application. > First of all you need to add Faces Servlet to web.xml, otherwise JSF > won't be loaded. > Next you should also put the myfaces extcdi jar into EAR/lib as > suggested by using the following maven config for the EAR Plugin: > > > <configuration> > <defaultLibBundleDir>lib</defaultLibBundleDir> > <defaultJavaBundleDir>lib</defaultJavaBundleDir> > <skinnyWars>true</skinnyWars> > <version>6</version> > </configuration> > > The addClasspath option in the war plugin is not necessary then. You > should also consider using dependentWarExcludes in the war plugin config > so you can also exclude the jar from overlay projects. > > Tested with JBoss AS 7.1.0 Final > > Mit freundlichen Grüßen, > ------------------------------------------------------------------------ > *Christian Beikov* > Am 19.03.2013 22:51, schrieb Adrian Gonzalez: >> Hi Denis, >> >> I've already checked your post (very instructive, thanks). >> I'm sure SINGLE_CLASSLOADER for ear will resolve this issue. >> Problem is I don't know how to specify it in JBoss AS 7 (I don't think it's >> supported - JBoss always creates an isolated classloader for each war) >> >> Going to use your instructions for WAS in the future (I'm using both JBoss >> AS 7 and WAS 8). >> For the moment, no problem with WAS 8 and ear packaging, everything is under >> WEB-INF/lib (no EJB Timer for the moment). >> >> BTW, updated sample app (moved codi to ear) : it's in ear branch >> https://github.com/gonzalad/codi-ear-viewaccessscoped/tree/ear >> >> If I don't find a packaging solution, perhaps I'll give a try modifying >> locally CODI code, but not sure which approach is best (the 3rd one perhaps >> but not sure it will work ;( ) : >> Sorry those are rough notes, and I don't master CDI : >> 1. modify ClassUtils.getClassloader >> add a configurationparameter to return >>ClassUtils.class.getClassloader(). >> cons : we're still relying on classloader and potentially will have a >>pb with another appserver. >> 2. remove @JsfPhaseListener and rely on classic phaseListeners >>configured with faces-config.xml >> cons : non CDI >> 3. use CDI to communicate phaseListener class in CODI >>consumeJsfPhaseListener >> i.e. we could perhaps add dynamically a bean or producer of type Class >>with a custom annotation, i.e. @JsfPhaseListener Class. >> then in consumer, we @Inject @JsfPhaseListener Instance<Class> >>jsfPhaseListenerClasses >> Afterwards, we instanciate phaseListener iterating on >>jsfPhaseListenerClasses.iterator(). >> cons : make a test with a JsfPhaseListener1 in webapp1 and >>JSFPhaseListener2 in webapp2, both being in the same EAR. >> Check that webapp1 has only listener JsfPhaseListener1 and not both of >>them. >> >> >> ________________________________ >> De : titou10 titou10 <titou10.tito...@gmail.com> >> À : MyFaces Discussion <users@myfaces.apache.org>; Adrian Gonzalez >> <adr_gonza...@yahoo.fr> >> Envoyé le : Mardi 19 mars 2013 22h37 >> Objet : Re: CODI ViewAccessScoped issue with EAR on JBoss 7.1.x >> >> Maybe you should check my previous post named "CODI jar in ear/lib >> with a WAR = fail in WebSphere v8.5" and then "Does CODI supports to >> be deployed in a app server that uses multi-classloader..." started >> January 17 because it seems that you have the same problem we have >> with WebSphere v8.5 >> >> If I try to deploy the CODI jar into ear/lib, some PhaseListener >> magical initialisation was not working at startup (=first page >> accessed)... >> And I also have the same feeling as you that this is the way CODI use >> the classloaders that causes the problem >> ... >> The only solutions we found: configure WAS to use only 1 classloader >> for all the modules in the ear, (but this is not supported by the OWB >> implementation packaged with WAS), or deploy everything in war >> WEB-INF/lib, including the ejb jars. In fact we put "any module that >> uses CDI (inject/producers)" in web-inf/lib and the other in ear/lib >> (slf4j, hibernate, jpa module etc) >> >> This is what we are doing even if I don't like it... >> >> Mark Struberg answered that he was using CODI with a multi level CL >> without problem... >> >> 2013/3/19 Adrian Gonzalez <adr_gonza...@yahoo.fr>: >>> I've just put myfaces-extcdi-bundle-jsf20-1.0.5.jar into ear (and removed >>> it from WEB-INF/lib), no more luck. >>> >>> I'll try to update my sample tomorrow with ear packaging and debug it. >>> >>> Thanks once more for the help Christian ! >>> >>> P.S. I'm wondering if the root cause of this bug isn't in CODI (classloader >>> usage in Java EE & CDI appears to be under-specified, so I'm not sure a CDI >>> extension should rely on TCCL for its internals) >>> >>> >>> ________________________________ >>> De : Christian Beikov <c.bei...@curecomp.com> >>> À : users@myfaces.apache.org >>> Envoyé le : Mardi 19 mars 2013 21h20 >>> Objet : Re: CODI ViewAccessScoped issue with EAR on JBoss 7.1.x >>> >>> I used the xml file to be able to put the CODI bundle into EAR/lib. >>> The problem was that JSF is not on the classpath which the deployment >>> xml should fix. >>> My CODI bundle is currently in EAR/lib and it deploys successfully with >>> this configuration. >>> >>> Am 19.03.2013 20:43, schrieb Adrian Gonzalez: >>>> Hi Christian, >>>> >>>> Thanks for the tip ! >>>> >>>> Just made a quick test using your file with my sample, but no luck, it >>>> doesn't work. >>>> I'm using JBoss jsf impl (so no jsf jars in my app). >>>> I've also putting myfaces-extcdi-bundle-jsf20-1.0.5.jar in the war, >>>> WEB-INF/lib. >>>> >>>> Do you have the same setup ? >>>> >>>> >>>> ________________________________ >>>> De : Christian Beikov <c.bei...@curecomp.com> >>>> À : users@myfaces.apache.org >>>> Envoyé le : Mardi 19 mars 2013 17h18 >>>> Objet : Re: CODI ViewAccessScoped issue with EAR on JBoss 7.1.x >>>> >>>> Hey, >>>> >>>> I had the same problem a time ago. Just add following >>>> jboss-deployment-structure.xml into META-INF of the EAR: >>>> >>>> <?xml version="1.0" encoding="UTF-8"?> >>>> <jboss-deployment-structure> >>>> <!-- Make sub deployments isolated by default, so they cannot see >>>>each others >>>> classes without a Class-Path entry --> >>>> <ear-subdeployments-isolated>true</ear-subdeployments-isolated> >>>> <!-- This corresponds to the top level deployment. For a war this >>>>is the >>>> war's module, for an ear --> >>>> <!-- This is the top level ear module, which contains all the >>>>classes in >>>> the EAR's lib folder --> >>>> <deployment> >>>> <!-- This allows you to define additional dependencies, it is >>>>the same >>>> as using the Dependencies: manifest attribute --> >>>> <dependencies> >>>> <module name="org.w3c.css.sac" /> >>>> <module name="net.sourceforge.cssparser" /> >>>> <module name="com.sun.jsf-impl" /> >>>> <module name="javax.api" /> >>>> <module name="javax.faces.api" /> >>>> <module name="javax.xml.bind.api" /> >>>> <module name="javax.xml.jaxp-provider" /> >>>> <module name="com.google.guava" /> >>>> </dependencies> >>>> </deployment> >>>> </jboss-deployment-structure> >>>> >>>> Am 19.03.2013 16:34, schrieb Adrian Gonzalez: >>>>> Hello, >>>>> >>>>> This is a follow up on >>>>> http://mail-archives.apache.org/mod_mbox/myfaces-users/201212.mbox/%3c1354617133.46780.yahoomail...@web172404.mail.ir2.yahoo.com%3E. >>>>> >>>>> @ViewAccessScoped is not working when deploying an EAR on JBoss 7.1.0 >>>>> (tested it with 7.1.3 same result). >>>>> If I deploy only a war, it works. >>>>> Sample project is here [1]. >>>>> >>>>> I used the debugguer and found that when using and EAR : >>>>> * the classloader obtained in >>>>>PhaseListenerExtension#addPhaseListener is the EAR classloader >>>>> ModuleClassLoader for Module >>>>>"deployment.viewaccessscoped-ear.ear:main" from Service Module Loader >>>>> * the classloader obtained in >>>>>consumePhaseListeners#consumePhaseListeners() is the WAR classloader >>>>> ModuleClassLoader for Module >>>>>"deployment.viewaccessscoped-ear.ear.viewaccessscoped-web.war:main" from >>>>>Service Module Loader >>>>> >>>>> This means that phaselisteners annotated with @JsfPhaseListener are not >>>>> executed. >>>>> >>>>> The following phaselisteners are not registered with the war classloader >>>>> when using an EAR : >>>>> * class >>>>>org.apache.myfaces.extensions.cdi.jsf.impl.config.view.PhasesLifecycleCallbackPhaseListener >>>>> * class >>>>>org.apache.myfaces.extensions.cdi.jsf.impl.listener.phase.JsfRequestLifecyclePhaseListener >>>>> >>>>> Thanks for the help ! >>>>> >>>>> [1] Sample project here : >>>>> https://github.com/gonzalad/codi-ear-viewaccessscoped >>>>> To reproduce it, >>>>> 1. Testing the war >>>>> a. add the war on JBoss >>>>> b. http://localhost:8080/viewaccessscoped-web/test.faces >>>>> you'll see on sysout that CODI ViewAccessScoped bean has >>>>>been instantiated >>>>> 16:24:52,778 INFO [stdout] (http--0.0.0.0-8080-1) >>>>>@PostConstruct >>>>> c. click on first link. >>>>> you should see nothing on sysout (this means the previous >>>>>bean instance is reused) >>>>> 1. Testing the ear - incorrect behaviour >>>>> a. add the ear on JBoss (remove the previous war) >>>>> b. http://localhost:8080/viewaccessscoped-web/test.faces >>>>> you'll see on sysout that CODI ViewAccessScoped bean has >>>>>been instantiated >>>>> 16:22:49,186 INFO [stdout] (http--0.0.0.0-8080-1) >>>>>@PostConstruct >>>>> c. click on first link. >>>>> you'll see on sysout that previous CODI ViewAccessScoped >>>>>instance has been destroyed and a new one is created. >>>>> 16:23:24,389 INFO [stdout] (http--0.0.0.0-8080-1) >>>>>@PreDestroy >>>>> 16:23:24,389 INFO [stdout] (http--0.0.0.0-8080-1) >>>>>@PostConstruct >>>>>