Thanks Howard, great to hear I'm on the right track :)

I haven't given much thought to exposing tapestry services to cdi.
It's not something we currently require for our projects, but if it's
requested by others I could look into that as well!

*Question*
I have one issue related to the CDIObjectProvider though.
While testing the quickstart (which uses the CDIModule) I created and
registered a tapestry service - which accidentally also satisfies as a CDI
managed bean.
*From quickstart appmodule*
*public static void bind(ServiceBinder binder){*
* binder.bind(AnotherService.class).withId("AnotherSrv");    *
*}*

As posted earlier the CDIProvider is contributed to the MasterObjectProvider
as last (after:*)?
*configuration.add("cdiProvider", cdiProvider, "after:*");*

AnotherService is injected into a component/page
*@Inject private AnotherService another;*
*
*
What I would want is the cdiprovider to be asked last - so that if Tapestry
itself cannot provide the service it will eventually get delegated to CDI.
In this case - tapestry should provide the service.
However, the cdiprovider is asked to provide the bean. (This is why I've
specifically test for scope now.)

So the question is. *How can I make sure that the CDIProvider is asked last
in chain?*
Do I have to contribute to InjectionProvider as well?

thanks in advance
Magnus

On Wed, Jun 8, 2011 at 6:47 PM, Howard Lewis Ship <hls...@gmail.com> wrote:

> Nope, it's designed to be easy ... though contributions into
> MasterObjectProvider are always tricky since you can get into
> dependency cycles very easily. You've properly side-stepped this using
> @InjectService (using the special @Local marker annotation is always
> very important).
>
> The hard part, which is still difficult with Spring, is proper
> co-dependence:  allowing Tapestry services to be injected into Spring
> beans as well as the reverse.  It comes down to a turf battle about
> which framework is "in charge".
>
> On Wed, Jun 8, 2011 at 4:56 AM, Magnus Kvalheim <mag...@kvalheim.dk>
> wrote:
> > Hi all,
> >
> > We're looking into moving our apps from a 'traditional' servlet container
> > with spring into a Java EE web profile server like glassfish 3.1.
> > Motivations for doing this is to utilize cdi(jsr 299, 330), ejb3 and
> more.
> > Not just for the tapestry app, but also the other applications in
> > our portfoleo which share common core business logic.
> >
> > For reference on previous discussions:
> >
> http://tapestry.1045711.n5.nabble.com/Java-based-spring-configuration-td3394086.html
> > http://tapestry.1045711.n5.nabble.com/Discussion-td2421783i20.html
> >
> > Now, I've tried running the tapestry quickstart app in glassfish 3.1
> (with
> > the eclipse connector for publishing).
> > This works ok - although I cannot make live class reloading work. :(
> >
> > Glassfish uses Weld, so the CDIModule is basically an objectprovider for
> > injecting Weld managed beans.
> > (As you probably know CDI/Weld can also be used outside jee as
> alternative
> > to tapestry-ioc, spring, etc)
> >
> > *CDIModule class*
> > *public class CDIModule { *
> > * public static void bind(ServiceBinder binder) {*
> > *    binder.bind(ObjectProvider.class,
> > CDIObjectProvider.class).withId("CDIObjectProvider");        *
> > *    } *
> > * public static BeanManager buildBeanManager(Logger log) { *
> > * try {*
> > * BeanManager beanManager = (BeanManager) new
> > InitialContext().lookup("java:comp/BeanManager");*
> > * return beanManager; *
> > * } catch (NamingException e) {*
> > * log.error("Could not lookup jndi resource: java:comp/BeanManager", e);*
> > * }*
> > * return null;*
> > * } *
> > * public static void contributeMasterObjectProvider(*
> > * @InjectService("CDIObjectProvider") ObjectProvider cdiProvider,*
> > * OrderedConfiguration<ObjectProvider> configuration) { *
> > *// configuration.add("cdiProvider", cdiProvider,
> >
> "after:Service,after:AnnotationBasedContributions,after:Alias,after:Autobuild");
> > *
> > * configuration.add("cdiProvider", cdiProvider, "after:*"); *
> > * } *
> > *}*
> > *
> > *
> > The beanmanager is expected to be found in jndi. If the beans.xml is
> present
> > it will be available at this point.
> > The BeanManager is also exposed as a service and injectable for other
> > services or components.
> > I've tested by adding the *@SubModule(CDIModule.class) *to my quickstart
> > appmodule.
> > *
> > *
> > *CDIObjectProvider class*
> > *public class CDIObjectProvider implements ObjectProvider { *
> > * private BeanManager beanManager;*
> > * private Logger log;*
> > * *
> > * @SuppressWarnings({ "unchecked", "rawtypes" })*
> > * private Set allowedScopes = CollectionFactory.newSet(*
> > * ApplicationScoped.class,*
> > * Singleton.class);*
> > *
> > *
> > * public CDIObjectProvider(*
> > * Logger log,*
> > * @InjectService("BeanManager") BeanManager manager) {*
> > * this.beanManager = manager;*
> > * this.log = log;*
> > * }*
> > * @SuppressWarnings("unchecked")*
> > * public <T> T provide(Class<T> objectType,*
> > * AnnotationProvider annotationProvider, ObjectLocator locator) {*
> > * Set<Bean<?>> beans =  beanManager.getBeans(objectType);*
> > * if(beans!=null && beans.size()>0) {*
> > * Bean<T> bean = (Bean<T>) beans.iterator().next(); *
> > * if(hasValidScope(bean)) {*
> > * CreationalContext<T> ctx = beanManager.createCreationalContext(bean);*
> > * T o = (T) beanManager.getReference(bean, objectType, ctx); *
> > * log.info("Found and returning: "+objectType.getCanonicalName());*
> > * return o; *
> > * }*
> > * }*
> > * return null;*
> > * } *
> > * protected <T> boolean hasValidScope(Bean<T> bean) {*
> > * return bean!=null && allowedScopes.contains(bean.getScope());*
> > * }*
> > *}*
> >
> > I've limited the scope to singleton/applicationscoped. Perhaps also
> Default
> > could be accepted though.
> > Until now I've only tested this with pojo's and not ejb's - but for that
> > it's working as expected.
> > I can inject CDI beans into pages and components using*
> >  org.apache.tapestry5.ioc.annotations.Inject*
> >
> > I'm no expert to tapestry internals - so there could be
> > other considerations that needs to be addressed.
> > In fact in seemed just a little to easy to implement - so I must have
> missed
> > something. - Or perhaps it's just that easy to do in Tapestry :)
> >
> > Thoughts, comments?
> >
>
>
>
> --
> Howard M. Lewis Ship
>
> Creator of Apache Tapestry
>
> The source for Tapestry training, mentoring and support. Contact me to
> learn how I can get you up and productive in Tapestry fast!
>
> (971) 678-5210
> http://howardlewisship.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>

Reply via email to