myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Adrian Gonzalez <adr_gonza...@yahoo.fr>
Subject Re: CODI ViewAccessScoped issue with EAR on JBoss 7.1.x
Date Thu, 21 Mar 2013 16:57:16 GMT
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_gonzalez@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.beikov@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.beikov@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.titou10@gmail.com>
>> À : MyFaces Discussion <users@myfaces.apache.org>; Adrian Gonzalez <adr_gonzalez@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_gonzalez@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.beikov@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.beikov@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.YahooMailNeo@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
>>>>>

Mime
View raw message