Re: [weld-dev] Fwd: Re[2]: How to make method injection when bean subclass is required in Weld?
by Alex Sviridov
Hi Martin
Thank you very much for your comment and suggestion about improving.
Best regards, Alex
>Четверг, 31 августа 2017, 12:50 +03:00 от Martin Kouba <mkouba(a)redhat.com>:
>
>Hi Alex,
>
>1) should work but looks a little bit cumbersome. WRT 2) you should
>avoid using BeanManager to create a bean instance whenever possible. And
>in this particular case, if SimpleFoo is @Dependent it wouldn't be
>destroyed correctly (@PreDestroy) when Parent or Child is destroyed.
>
>The following should also work (no need to have two Instance IPs):
>
>public class Parent {
>
> @Inject
> private Instance<SimpleFoo> fooInstance;
>
> private SimpleFoo foo;
>
> protected SimpleFoo newFoo() {
> return fooInstance.get();
> }
>
> @PostConstruct
> private void doPostConstruct() {
> foo = newFoo();
> }
> }
>
> public class Child extends Parent {
>
> @Override
> protected AdvancedFoo newFoo() {
> return fooInstance.select(AdvancedFoo.class).get();
> }
> }
>
>
>Martin
>
>Dne 31.8.2017 v 11:07 Alex Sviridov napsal(a):
>> Hi Martin,
>>
>>
>> Could you comment the following solutions?
>>
>> 1)
>> public class Parent {
>>
>> @Inject
>> private Instance<SimpleFoo> fooInstance;
>>
>> private SimpleFoo foo;
>>
>> protected SimpleFoo newFoo() {
>> return fooInstance.get();
>> }
>>
>> @PostConstruct
>> private void doPostConstruct() {
>> foo = newFoo();
>> }
>> }
>>
>> public class Child extends Parent {
>>
>> @Inject
>> private Instance<AdvancedFoo> fooInstance;
>>
>> @Override
>> protected AdvancedFoo newFoo() {
>> return fooInstance.get();
>> }
>> }
>>
>>
>> 2)
>>
>> public class Parent {
>>
>> @Inject
>> protected BeanManager beanManager;
>>
>> private SimpleFoo foo;
>>
>> protected SimpleFoo newFoo() {
>> SimpleFoo foo = constructing bean with BM;
>> return foo;
>> }
>>
>> @PostConstruct
>> private void doPostConstruct() {
>> foo = newFoo();
>> }
>> }
>>
>> public class Child extends Parent {
>>
>> @Override
>> protected AdvancedFoo newFoo() {
>> AdvancedFoo foo = constructing bean with BM;
>> return foo;
>> }
>> }
>>
>>
>> Best regards, Alex
>>
>> Среда, 30 августа 2017, 10:51 +03:00 от Matej Novotny
>> < manovotn(a)redhat.com <mailto: manovotn(a)redhat.com >>:
>>
>> 1) If you inject Instance<T>, you still have the ambiguous
>> dependency issue for any class which does have a subclass.
>> E.g. from your sample:
>>
>> @Inject
>> Instance<SimpleFoo> instance;
>>
>> //within some method
>> instance.get(); -> this will blow up because you have two beans
>> which have SimpleFoo type (SimpleFoo and AdvancedFoo)
>>
>> 2) I don't understand what you mean by this. How does BM help here?
>>
>>
>> Sidenote:
>> You might want to try and use what Martin said - limiting the types
>> of a bean with @Typed(MyClass.Foo).
>> That way you have control over the bean types and can further
>> manupulate the injection.
>> Limit all your children to only the actual subclass type they have:
>>
>> @Dependent
>> @Typed(AdvancedFoo.class)
>> public class AdvancedFoo extends SimpleFoo {
>> // this ben now only has a bean of AdvancedFoo, e.g. it does not
>> fit into injection point for SimpleFoo
>> }
>>
>> And then override the initializer methods like this:
>>
>> @Dependent
>> public class Parent extends Child {
>>
>> @Inject
>> @Override
>> protected void setFoo(AdvancedFoo foo) {
>> this.foo = foo; // assuming foo is a protected field
>> }
>> }
>>
>> Matej
>>
>>
>> ----- Original Message -----
>> > From: "Alex Sviridov" < ooo_saturn7(a)mail.ru
>> <mailto: ooo_saturn7(a)mail.ru >>
>> > To: "weld-dev" < weld-dev(a)lists.jboss.org
>> <mailto: weld-dev(a)lists.jboss.org >>
>> > Sent: Tuesday, August 29, 2017 8:54:47 PM
>> > Subject: Re: [weld-dev] How to make method injection when bean
>> subclass is required in Weld?
>> >
>> > I thought here, and would like to share my ideas hoping to get
>> comments from
>> > more experienced people.
>> >
>> > First of all I came to conclusion that CDI works badly with cases
>> when we
>> > need
>> > to change field values in super classes. If there is a lot of
>> inheritance as
>> > in my case:
>> > ParentA, ChildA0, ChildA1.., ParentB, ChildB0, ChildB1..,... then
>> situation
>> > is
>> > becoming very bad. Maybe in future there will be other solutions
>> in CDI
>> > specs.
>> >
>> > I found two additional ways that can be used. 1) Inject not beans but
>> > instances,
>> > + method SimpleFoo newFoo {return Instance<SimpleFoo>.get} +
>> overriding.
>> > 2) Inject BeanManager + method SimpleFoo newFoo() {beanManager...} +
>> > overriding.
>> >
>> > Maybe such ways can be named lazy/postponed initialization with
>> overriding
>> > support....
>> >
>> > Best regards, Alex
>> >
>> >
>> >
>> >
>> > Вторник, 29 августа 2017, 18:22 +03:00 от Martin Kouba
>> < mkouba(a)redhat.com <mailto: mkouba(a)redhat.com >>:
>> >
>> > Hi Alex,
>> >
>> > that's an interesting question. Indeed, qualifiers are the way to
>> go if
>> > you need to keep the method signature.
>> >
>> > Another way could be to override the setFoo() method so that the
>> Child
>> > initializer is ignored and add a new method to inject AdvancedFoo:
>> >
>> > @Override
>> > protected void setFoo(SimpleFoo foo) { // Do nothing }
>> >
>> > @Inject
>> > void setAdvancedFoo(AdvancedFoo foo) {
>> > super.setFoo(foo);
>> > }
>> >
>> > However, note that right now there are the following beans:
>> >
>> > SimpleFoo with bean types Object, SimpleFoo
>> > AdvancedFoo -> Object, SimpleFoo, AdvancedFoo
>> >
>> > So if you do @Inject SimpleFoo you get ambiguous dependency exception
>> > because both SimpleFoo and AdvancedFoo are eligible for injection.
>> >
>> > To resolve this you need to use qualifiers or restrict the bean
>> types of
>> > AdvancedFoo:
>> >
>> > @Typed(AdvancedFoo.class)
>> > class AdvancedFoo extends SimpleFoo {}
>> >
>> > HTH
>> >
>> > Martin
>> >
>> >
>> > Dne 29.8.2017 v 15:09 Matej Novotny napsal(a):
>> > > Hi Alex,
>> > >
>> > > no need to be sorry, you have come to the right place :)
>> > > As for your question, the simplest thing is probably to use
>> qualifiers.
>> > >
>> > > Create your own like this:
>> > >
>> > > @Qualifier
>> > > @Retention(RetentionPolicy.RUNTIME)
>> > > @Target({ ElementType.TYPE, ElementType.PARAMETER,
>> ElementType.FIELD,
>> > > ElementType.METHOD })
>> > > public @interface MyQualifier {}
>> > >
>> > >
>> > > And then change your AdvancedFoo class to use the qualifier:
>> > >
>> > > @Dependent
>> > > @MyQualifier
>> > > public class AdvancedFoo extends SimpleFoo {
>> > > }
>> > >
>> > > And accordingly, the init method which uses injection should
>> then look like
>> > > this:
>> > >
>> > > @Dependent
>> > > public class Parent extends Child {
>> > >
>> > > @Inject
>> > > @Override
>> > > protected void setFoo(@MyQualifier SimpleFoo foo) {
>> > > super.setFoo(foo);
>> > > }
>> > > }
>> > >
>> > > Does this answer your question?
>> > >
>> > > Matej
>> > >
>> > > ----- Original Message -----
>> > >> From: "Alex Sviridov" < ooo_saturn7(a)mail.ru
>> <mailto: ooo_saturn7(a)mail.ru > >
>> > >> To: "weld-dev" < weld-dev(a)lists.jboss.org
>> <mailto: weld-dev(a)lists.jboss.org > >
>> > >> Sent: Tuesday, August 29, 2017 1:46:23 PM
>> > >> Subject: [weld-dev] How to make method injection when bean
>> subclass is
>> > >> required in Weld?
>> > >>
>> > >> Hi all,
>> > >>
>> > >> I am really sorry for writing to this mailing list, but I
>> checked all user
>> > >> forums and chats and saw that they are very old.
>> > >>
>> > >> I would be very thankful if someone gives suggestion for
>> solving the
>> > >> following problem.
>> > >> I have a child and parent class. Child has SimpleFoo, Parent
>> needs Advaced
>> > >> foo. So,
>> > >>
>> > >> @Dependent
>> > >> public class SimpleFoo {
>> > >> }
>> > >>
>> > >> @Dependent
>> > >> public class AdvancedFoo extends SimpleFoo {
>> > >> }
>> > >>
>> > >> @Dependent
>> > >> public class Child {
>> > >>
>> > >> private SimpleFoo foo;
>> > >>
>> > >> @Inject
>> > >> protected void setFoo(SimpleFoo foo) {
>> > >> this.foo = foo;
>> > >> }
>> > >> }
>> > >>
>> > >> @Dependent
>> > >> public class Parent extends Child {
>> > >>
>> > >> @Inject
>> > >> @Override
>> > >> protected void setFoo(SimpleFoo foo) { //How to inject here
>> AdvancedFoo?
>> > >> super.setFoo(foo);
>> > >> }
>> > >> }
>> > >>
>> > >> How to inject in Parent AdvancedFoo? I know that I can do it via
>> > >> constructor
>> > >> injection
>> > >> but I need method injection. How to do it? Can it be done
>> without using
>> > >> names
>> > >> (like MyBean1)
>> > >> but only using classes (AdvancedFoo)?
>> > >>
>> > >> Best regards, Alex
>> > >>
>> > >>
>> > >>
>> > >>
>> > >>
>> > >> --
>> > >> Alex Sviridov
>> > >>
>> > >> _______________________________________________
>> > >> weld-dev mailing list
>> > >> weld-dev(a)lists.jboss.org <mailto: weld-dev(a)lists.jboss.org >
>> > >> https://lists.jboss.org/mailman/listinfo/weld-dev
>> > > _______________________________________________
>> > > weld-dev mailing list
>> > > weld-dev(a)lists.jboss.org <mailto: weld-dev(a)lists.jboss.org >
>> > > https://lists.jboss.org/mailman/listinfo/weld-dev
>> > >
>> >
>> > --
>> > Martin Kouba
>> > Senior Software Engineer
>> > Red Hat, Czech Republic
>> >
>> >
>> > _______________________________________________
>> > weld-dev mailing list
>> > weld-dev(a)lists.jboss.org <mailto: weld-dev(a)lists.jboss.org >
>> > https://lists.jboss.org/mailman/listinfo/weld-dev
>>
>>
>>
>> ------------------------------------------------------------------------
>>
>> --
>> Alex Sviridov
>
>--
>Martin Kouba
>Senior Software Engineer
>Red Hat, Czech Republic
--
Alex Sviridov
7 years, 3 months
How to make method injection when bean subclass is required in Weld?
by Alex Sviridov
Hi all,
I am really sorry for writing to this mailing list, but I checked all user forums and chats and saw that they are very old.
I would be very thankful if someone gives suggestion for solving the following problem.
I have a child and parent class. Child has SimpleFoo, Parent needs Advaced foo. So,
@Dependent
public class SimpleFoo {
}
@Dependent
public class AdvancedFoo extends SimpleFoo {
}
@Dependent
public class Child {
private SimpleFoo foo;
@Inject
protected void setFoo(SimpleFoo foo) {
this.foo = foo;
}
}
@Dependent
public class Parent extends Child {
@Inject
@Override
protected void setFoo(SimpleFoo foo) { //How to inject here AdvancedFoo?
super.setFoo(foo);
}
}
How to inject in Parent AdvancedFoo? I know that I can do it via constructor injection
but I need method injection. How to do it? Can it be done without using names (like MyBean1)
but only using classes (AdvancedFoo)?
Best regards, Alex
--
Alex Sviridov
7 years, 3 months
Dependent Scoped bean aquired by CDI.current() is not destroyed
by Benjamin Confino
Hello
I have a servlet that acquires two instances of a dependent scoped bean.
The first is aquired by @Inject Instance<CdiBean> the second is acquired
via CDI.current().select(CdiBean.class).get().
I can see that the first instance's @PreDestroy is called when I shut down
the application. However @PreDestroy is not called on the instance
acquired CDI.current. Here is the source:
My question is, is this behaviour intentional? And if it is, can you
please link me to the appropriate part of the spec that says when we
should expect a @Dependent bean created by CDI.current to be destroyed? I
have a customer concerned about this causing a potential memory leak.
Regards
Benjamin
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
7 years, 4 months
Do Custom implementations of Bean need to provide injection points?
by John D. Ament
Hi
As the subject says. I have a library that registers a custom
implementation of Bean, which has a method
@Override
public Set<InjectionPoint> getInjectionPoints() {
return Collections.emptySet();
}
When testing this on Weld3, I have code that looks up the injection point,
to find the annotations present. However, the following injection point
lookup fails:
private static InjectionPoint findInjectionPoint(final BeanManager bm,
final CreationalContext<?> ctx) {
return InjectionPoint.class.cast(
bm.getReference(bm.resolve(bm.getBeans(InjectionPoint.class)),
InjectionPoint.class, ctx));
}
so based on a CreationalContext I'm looking for InjectionPoint. Maybe
there's a different way that this is supposed to work? If you're
interested in giving it a shot, take a look at
https://github.com/apache/geronimo-config and run the Weld3 profile to
replicate the issue.
John
7 years, 4 months