-
1. Re: A basic query on CDI Extension
rhanus Jun 27, 2013 7:21 AM (in response to job75)not sure if I understood well but I guess you need to use right scope(s)
for instance you may define the producer along with a session scope annotation to ensure that in a http session you always use the same instance:
public @Produces @SessionScoped @MyService SomeServiceI createSomeService(InjectionPoint injectionPoint){...}
-
2. Re: A basic query on CDI Extension
job75 Jun 27, 2013 8:28 PM (in response to rhanus)thanks Radim for the answer. The above stuff works. But the issue is(or my question was), if I use producer method for creating SomeServiceImpl(impl returned by my producer method 'createSomeService'), the depency injections specifed within SomeServiceImpl class is not getting evaluated, they get evaluated if I dont have any producer emthod. For e.g
TestI test; is not getting injected in the below code.
public class SomeServiceImpl implements SomeServiceI {
@Inject @TestSvc
TestI test;
}
-
3. Re: A basic query on CDI Extension
mkouba Jun 28, 2013 3:57 AM (in response to job75)Hi job75,
there's one thing I don't understand. SomeServiceImpl is a legacy code but still contains CDI annotations (@Inject, qualifiers, ...)? In any case it's up to the producer to fully initialize the produced object (note that interceptors and decorators are not applied to the return value as well). With regard to your use case (as I understand it) - I think you could use a portable extension and BeforeBeanDiscovery.addAnnotatedType()... see for example https://github.com/mojavelinux/cdi-extension-showcase/blob/master/src/main/java/com/acme/importbeans/RegisterBeanFromNonBeanClassExtension.java (replace SecureRandom.class with SomeServiceImpl.class).
-
4. Re: A basic query on CDI Extension
job75 Jun 28, 2013 7:29 AM (in response to mkouba)Thanks Martin for your response. The above thing didnt really work for me. I can work around this if I call the following things from my producer method - however I wanted to get thing thing done by framework if ther is a way.
AnnotatedType<SomeServiceImpl> type = beanManager.createAnnotatedType(SomeServiceImpl.class);
InjectionTarget<SomeServiceImpl> it = beanManager.createInjectionTarget(type);
CreationalContext ctx = beanManager.createCreationalContext(null);
it.inject( someServiceImpl, ctx); //call initializer methods and perform field injection
it.postConstruct(testI);
-
5. Re: A basic query on CDI Extension
mkouba Jun 28, 2013 8:31 AM (in response to job75)1 of 1 people found this helpfulHm, what exactly "didn't really work" means? I think your workaround will not work correctly - for instance injected dependent instances will not be destroyed properly (@PreDestroy callbacks and disposer methods will not be invoked). See also CDI 1.1: http://docs.jboss.org/cdi/spec/1.1/cdi-spec.html#bm_obtain_unmanaged_instance and javax.enterprise.inject.spi.Unmanaged javadoc...
-
6. Re: A basic query on CDI Extension
job75 Jun 28, 2013 12:42 PM (in response to mkouba)>>Hm, what exactly "didn't really work" means?
It didn't work for me. The SomeServiceImpl didn't get its CDI enabled variables initialized. btw, all works if I remove my custom producer method( as usual ). Not sure if I missing some basics. Any sample is available?
-
7. Re: A basic query on CDI Extension
luksa Jun 28, 2013 1:07 PM (in response to job75)1 of 1 people found this helpfulIf you create the instance yourself (with new SomeServiceImpl()) - even if you do it inside a producer method - CDI will never just magically inject things into your instance. You either have to let CDI create the instance for you or you must create an injection target (as you did in one of your previous comments). One way of having CDI create the instance for you, is through a CDI extension, as Martin mentioned.
-
8. Re: A basic query on CDI Extension
job75 Jun 28, 2013 11:04 PM (in response to luksa)>One way of having CDI create the instance for you, is through a CDI extension, as Martin mentioned.
I've tried that, didn't work for me.
I'm attaching a sample JSF web application(a maven project built using Netbeans 7.3.1) where the issue is replicated. I could be missing some basics(for sure)
https://adf-samples.googlecode.com/files/cdi-testcase.zip
In this sample, the index.xhtml uses IndexPageBean. When you click the button on this page it invokes IndexPageBean::btnClicked(). This method inturn invokes MyServiceImpl::doCheck() MyServiceImpl is injected through my producer class(MyServiceProducer). MyServiceImpl has SomeModularServiceI as memeber variable which fails to get intiailized through CDI if I use my own producer.
Tried the Martin's suggestion of using Extension to add AnnotatedType, doesnot seems working for me(or I missed something here). Can anyone please help
-
9. Re: A basic query on CDI Extension
luksa Jun 30, 2013 3:47 PM (in response to job75)Job, it's really not clear what you are trying to achieve. What do you actually need the producer method for? Do you want it to return a specific implementation of MyService, while you actually have many implementations available at runtime? Is this why you want to create the instance yourself?
In cdi-testcase.zip your producer is creating a new instance of MyServiceImpl. As I said before, CDI will not inject anything into it. You have to let CDI create the instance for you. You do this by either putting MyServiceImpl into a bean archive (add beans.xml to the jar the class is in) or by calling BeforeBeanDiscovery.addAnnotatedType() if you can't put the class into a bean archive.
-
10. Re: A basic query on CDI Extension
job75 Jul 1, 2013 12:53 AM (in response to luksa)>What do you actually need the producer method for?
Thanks Mark for the reply. Yes , It's bid odd case. In fact, I'm trying out a POC. In real life case, MyServiceImpl could be a pooled object managed by the continer(it's custom managed object and its not based on any standard technolgoy such as EJB + CDI doesnot know aout the traget plactform in this case). So I cannot let CDI simply to create a new intance of MyServiceImpl, rather my producer method may have logic to look up from the pool(this logic is missing in the sample to keep it simple). So I'm juts seeing whether MyServiceImpl can also have CDI enabled memeber varibale(i.e introducing CDI for injecting thing in my legacy MyServiceImpl). In a nutshell , I need control on injecting MyServiceImpl instnaces, and at the sametime, would like know whther MyServiceImpl can have 'normal' CDI enebaled memeber variables (whose linjections are normal and straight forward and can be managed by CDI). If this is not acheivable, probably I can change my approach( ie. having CDI annotated variables as members in MyServiceImpl )
-
11. Re: A basic query on CDI Extension
pmuir Jul 8, 2013 9:15 AM (in response to job75)In CDI 1.0
AnnotatedType<SomeServiceImpl> type = beanManager.createAnnotatedType(SomeServiceImpl.class);
InjectionTarget<SomeServiceImpl> it = beanManager.createInjectionTarget(type);
CreationalContext ctx = beanManager.createCreationalContext(null);
it.inject( someServiceImpl, ctx); //call initializer methods and perform field injection
it.postConstruct(testI);
is your best approach.
In CDI 1.1, you can use the more concise version that Martin linked to - http://docs.jboss.org/cdi/spec/1.1/cdi-spec.html#bm_obtain_unmanaged_instance