Le 19 oct. 2016 04:14, "Andriy Redko" <[email protected]> a écrit : > > I think this is what is happening: > - Roman defines own CXF bus bean, named "cxf"
This is a workaround to be able to lookup the bus in my workaround extension. Not doing it without my extension leads to the issue. > - our JAX-RS CDI extension finds it and makes it a "default" bus to be used > for JAXRSServerFactoryBean instances > - however, JAXRSServerFactoryBean::setApplication() would create a new bus > nonetheless, because the actual call to JAXRSServerFactoryBean::setBus would > be done later > This is the issue, custom bus or not. > The issue in this case is that application was created using one bus instance, > but JAXRSServerFactoryBean would be initialized using another bus instance. This > is my understading of the problem. Hopefully it makes sense. > The factory uses the cdi bus but the application used a "prototype" bus. Side note: i deploy with tomcat embedded a single app so I am not in "multiple" deployments case. > Best Regards, > Andriy Redko > > JDA> So still something isn't clicking as I don't have Romain's issue. Is it > JDA> specific to when you have multiple deployments in your JVM? > > JDA> On Oct 18, 2016 09:02, "Romain Manni-Bucau" <[email protected]> wrote: > > >> 2016-10-18 14:43 GMT+02:00 Andrey Redko <[email protected]>: > > >> > Hi Romain Manni-Bucau, > >> > > >> > Yes, technically we do have this option, but I would suggest to use > >> > explicit wirings instead of thread local context. It > >> > could have quite a number of side effects. I hope you would agree with > >> > that. > >> > > >> > > >> I agree it is better but side effect should be null since the value is > >> cleaned up after. If not then runtime can have side effects which would be > >> a bigger issue ;) > > > >> > Thanks! > >> > > >> > Best Regards, > >> > Andriy Redko > >> > > >> > > >> > On Tue, Oct 18, 2016 at 7:49 AM, Romain Manni-Bucau < > >> [email protected] > >> > > > >> > wrote: > >> > > >> > > We also have option 3: set the thread bus as in the workaround I used. > >> > > > >> > > > >> > > Romain Manni-Bucau > >> > > @rmannibucau <https://twitter.com/rmannibucau> | Blog > >> > > <https://blog-rmannibucau.rhcloud.com> | Old Wordpress Blog > >> > > <http://rmannibucau.wordpress.com> | Github <https://github.com/ > >> > > rmannibucau> | > >> > > LinkedIn <https://www.linkedin.com/in/rmannibucau> | Tomitriber > >> > > <http://www.tomitribe.com> | JavaEE Factory > >> > > <https://javaeefactory-rmannibucau.rhcloud.com> > >> > > > >> > > 2016-10-18 13:47 GMT+02:00 Sergey Beryozkin <[email protected]>: > >> > > > >> > > > Hi Andriy > >> > > > yes, option 1 is probably the simplest for the CDI integration path, > >> > > > > >> > > > Thanks, Sergey > >> > > > > >> > > > On 18/10/16 12:43, Andrey Redko wrote: > >> > > > > >> > > >> Hey guys, > >> > > >> > >> > > >> Indeed, there is an issue with CDI and usage of custom bus. I think > >> > > there > >> > > >> are couple of the options > >> > > >> we have here: > >> > > >> - pass the bus instance to ResourceUtils::createApplication, in > >> this > >> > > >> case > >> > > >> if bus is not set, the behaviour would be exactly the same > >> > > >> - change the way JAXRSServerFactoryBean is being created so we > >> could > >> > > set > >> > > >> the bus before setting the application > >> > > >> > >> > > >> Romain Manni-Bucau, do we have a ticket for it? If not, could you > >> > please > >> > > >> create one, we'll work on a fix for it. > >> > > >> Thanks. > >> > > >> > >> > > >> > >> > > >> On Tue, Oct 18, 2016 at 7:08 AM, Romain Manni-Bucau < > >> > > >> [email protected]> > >> > > >> wrote: > >> > > >> > >> > > >> Not yet something failling i can share but globally I ended up doing > >> > > that: > >> > > >>> > >> > > >>> @Named("cxf") > >> > > >>> @ApplicationScoped > >> > > >>> public class BusInstance implements Bus { > >> > > >>> @Delegate > >> > > >>> private Bus delegate = new ExtensionManagerBus(); > >> > > >>> } > >> > > >>> public class OWBAutoSetup implements ServletContainerInitializer { > >> > > >>> @Override > >> > > >>> public void onStartup(final Set<Class<?>> c, final ServletContext > >> > ctx) > >> > > >>> throws ServletException { > >> > > >>> > >> > > >>> ctx.addListener(WebBeansConfigurationListener.class); > >> > > >>> ctx.addListener(WebBeansConfigurationHttpSessionListener.class); > >> > > >>> } > >> > > >>> } > >> > > >>> > >> > > >>> > >> > > >>> > >> > > >>> public class CxfCdiAutoSetup implements > >> ServletContainerInitializer { > >> > > >>> @Override > >> > > >>> public void onStartup(final Set<Class<?>> c, final ServletContext > >> > ctx) > >> > > >>> throws ServletException { > >> > > >>> final ServletRegistration.Dynamic jaxrs = ctx.addServlet("cxf-cdi", > >> > > >>> CXFCdiServlet.class); > >> > > >>> > >> > > >>> > >> > > >>> jaxrs.setLoadOnStartup(1); > >> > > >>> jaxrs.setAsyncSupported(true); > >> > > >>> jaxrs.addMapping("/*"); // TODO: config > >> > > >>> } > >> > > >>> } > >> > > >>> > >> > > >>> > >> > > >>> > >> > > >>> With my workaround extension it works fine, without there is this > >> > > >>> mismatch > >> > > >>> of bus. > >> > > >>> > >> > > >>> Have to admit I have no idea how > >> > > >>> org.apache.cxf.jaxrs.utils.ResourceUtils#createApplication( > >> > javax.ws.rs > >> > > . > >> > > >>> core.Application, > >> > > >>> boolean, boolean) could reuse the right bus in current state of the > >> > cdi > >> > > >>> module. If you check > >> > > >>> org.apache.cxf.cdi.JAXRSCdiResourceExtension#createFactoryIn > >> > > >>> stance(javax. > >> > > >>> ws.rs.core.Application, > >> > > >>> java.util.List<?>, java.util.List<?>, java.util.List<? extends > >> > > >>> org.apache.cxf.feature.Feature>) the bus is set but too late > >> (after > >> > > bean > >> > > >>> .setApplication(app);). > >> > > >>> > >> > > >>> Romain Manni-Bucau > >> > > >>> @rmannibucau <https://twitter.com/rmannibucau> | Blog > >> > > >>> <https://blog-rmannibucau.rhcloud.com> | Old Wordpress Blog > >> > > >>> <http://rmannibucau.wordpress.com> | Github < https://github.com/ > >> > > >>> rmannibucau> | > >> > > >>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | Tomitriber > >> > > >>> <http://www.tomitribe.com> | JavaEE Factory > >> > > >>> <https://javaeefactory-rmannibucau.rhcloud.com> > >> > > >>> > >> > > >>> 2016-10-18 12:50 GMT+02:00 John D. Ament <[email protected] >: > >> > > >>> > >> > > >>> Do you have a sample project that demonstrates the issue? > >> > > >>>> > >> > > >>>> Also, do you see setBus method being called on CXFCdiServlet? How > >> > > many > >> > > >>>> times do you see it invoked? Maybe step through loadBus to see > >> > which > >> > > >>>> > >> > > >>> path > >> > > >>> > >> > > >>>> it follows. > >> > > >>>> > >> > > >>>> On Tue, Oct 18, 2016 at 6:24 AM Romain Manni-Bucau < > >> > > >>>> > >> > > >>> [email protected]> > >> > > >>> > >> > > >>>> wrote: > >> > > >>>> > >> > > >>>> Not really, > >> > > >>>>> > >> > > >>>>> I don't have any bus bean, just using the default one of the > >> > > extenson - > >> > > >>>>> behavior is the same however if I impl my own bus bean. > >> > > >>>>> > >> > > >>>>> Issue is in the load() method of the extension. It gets the bus > >> and > >> > > >>>>> > >> > > >>>> then > >> > > >>> > >> > > >>>> calls ResourceUtils.createApplication(application, false, false) > >> > > which > >> > > >>>>> > >> > > >>>> will > >> > > >>>> > >> > > >>>>> call org.apache.cxf.jaxrs.JAXRSServerFactoryBean#setApplication > >> > > which > >> > > >>>>> > >> > > >>>> will > >> > > >>>> > >> > > >>>>> do getBus() wich uses BusFactory.getThreadDefaultBus() which is > >> > > >>>>> > >> > > >>>> obviously > >> > > >>>> > >> > > >>>>> not set so you end up in org.apache.cxf.BusFactory# > >> createThreadBus > >> > > >>>>> > >> > > >>>> which > >> > > >>> > >> > > >>>> does a newInstance().createBus() and here you are, you have 2 > >> > > instances > >> > > >>>>> > >> > > >>>> of > >> > > >>>> > >> > > >>>>> a bus. > >> > > >>>>> > >> > > >>>>> Romain > >> > > >>>>> > >> > > >>>>> 2016-10-18 12:10 GMT+02:00 John D. Ament < [email protected] > >> >: > >> > > >>>>> > >> > > >>>>> Romain, > >> > > >>>>>> > >> > > >>>>>> Depends on how you're trying to instantiate it. There is a > >> > > >>>>>> > >> > > >>>>> CdiBusBean > >> > > >>> > >> > > >>>> provided by CXF which does what you're trying to do - > >> > > >>>>>> https://github.com/apache/cxf/blob/3.1.x-fixes/integration/ > >> > > >>>>>> cdi/src/main/java/org/apache/cxf/cdi/CdiBusBean.java#L40 > >> > > >>>>>> , > >> > > >>>>>> take a look at the create method. > >> > > >>>>>> > >> > > >>>>>> I was actually contemplating removing the @Inject from the > >> > > >>>>>> > >> > > >>>>> CXFCdiServlet's > >> > > >>>>> > >> > > >>>>>> set method, it seems to work inconsistently. However, i suspect > >> > > that > >> > > >>>>>> > >> > > >>>>> your > >> > > >>>>> > >> > > >>>>>> issue is that you're getting a Bus registered as a valid CDI > >> bean > >> > > >>>>>> (bean-discovery-mode=all?). > >> > > >>>>>> > >> > > >>>>>> John > >> > > >>>>>> > >> > > >>>>>> On Tue, Oct 18, 2016 at 5:58 AM Romain Manni-Bucau < > >> > > >>>>>> > >> > > >>>>> [email protected]> > >> > > >>>>> > >> > > >>>>>> wrote: > >> > > >>>>>> > >> > > >>>>>> Hi guys, > >> > > >>>>>>> > >> > > >>>>>>> in cdi-integration I don't get how the deployment can work > >> cause > >> > > >>>>>>> > >> > > >>>>>> the > >> > > >>> > >> > > >>>> thread > >> > > >>>>>> > >> > > >>>>>>> local bus is not set > >> > > >>>>>>> > >> > > >>>>>>> Here what i did to ensure i use a single bus (and prevented the > >> > cxf > >> > > >>>>>>> > >> > > >>>>>> one > >> > > >>>> > >> > > >>>>> to > >> > > >>>>>> > >> > > >>>>>>> run): > >> > > >>>>>>> > >> > > >>>>>>> public class JAXRSCdiResourceExtensionWorkaround extends > >> > > >>>>>>> JAXRSCdiResourceExtension { > >> > > >>>>>>> @Override > >> > > >>>>>>> public void load(@Observes final AfterDeploymentValidation > >> > > >>>>>>> > >> > > >>>>>> event, > >> > > >>> > >> > > >>>> final BeanManager beanManager) { > >> > > >>>>>>> final Bus bus = > >> > > >>>>>>> > >> > > >>>>>>> Bus.class.cast(beanManager.getReference(beanManager. > >> > > >>>>>>> > >> > > >>>>>> resolve(beanManager.getBeans(Bus.class)), > >> > > >>>>>> > >> > > >>>>>>> Bus.class, null)); > >> > > >>>>>>> BusFactory.setThreadDefaultBus(bus); // cause app > >> class > >> > > >>>>>>> > >> > > >>>>>> will > >> > > >>> > >> > > >>>> rely on that and would create multiple bus and then deployment > >> > > >>>>>>> > >> > > >>>>>> would > >> > > >>> > >> > > >>>> be broken > >> > > >>>>>>> try { > >> > > >>>>>>> super.load(event, beanManager); > >> > > >>>>>>> } finally { > >> > > >>>>>>> BusFactory.clearDefaultBusForAnyThread(bus); > >> > > >>>>>>> } > >> > > >>>>>>> } > >> > > >>>>>>> } > >> > > >>>>>>> > >> > > >>>>>>> > >> > > >>>>>>> Issue was caused by JAXRSCdiResourceExtension# > >> > > >>>>>>> > >> > > >>>>>> createFactoryInstance > >> > > >>> > >> > > >>>> which > >> > > >>>>>> > >> > > >>>>>>> calls ResourceUtils.createApplication which uses the thread > >> bus > >> > > >>>>>>> > >> > > >>>>>> which > >> > > >>>> > >> > > >>>>> is > >> > > >>>>> > >> > > >>>>>> not set by the extension leading to 2 buses. > >> > > >>>>>>> > >> > > >>>>>>> Did I miss something? > >> > > >>>>>>> > >> > > >>>>>>> Romain Manni-Bucau > >> > > >>>>>>> @rmannibucau <https://twitter.com/rmannibucau> | Blog > >> > > >>>>>>> <https://blog-rmannibucau.rhcloud.com> | Old Wordpress Blog > >> > > >>>>>>> <http://rmannibucau.wordpress.com> | Github < > >> > > >>>>>>> https://github.com/rmannibucau> | > >> > > >>>>>>> LinkedIn <https://www.linkedin.com/in/rmannibucau> | > >> Tomitriber > >> > > >>>>>>> <http://www.tomitribe.com> | JavaEE Factory > >> > > >>>>>>> <https://javaeefactory-rmannibucau.rhcloud.com> > >> > > >>>>>>> > >> > > >>>>>>> > >> > > >>>>>> > >> > > >>>>> > >> > > >>>> > >> > > >>> > >> > > >> > >> > > > > >> > > > -- > >> > > > Sergey Beryozkin > >> > > > > >> > > > Talend Community Coders > >> > > > http://coders.talend.com/ > >> > > > > >> > > > >> > > >
