On 24 May 2011, at 20:42, Mark Struberg wrote:
Imo it is surprising, since it would break all kinds of 'business
injections' (as opposed to classic 'resource injections' - Jens Schumann can
explain this well ;)
Can you make him explain it for our edification?
I think 5.4.2. Client proxy invocation + 6.5.2. Contextual instance of a bean goes rather
in the direction of _very_ lazy initialization ;)
Well we can leave it explicitly unspecified should we wish (i.e. we make it unportable).
This reserves the right to change our mind later.
Imho, the current behaviour of Weld, OWB and CanDI is correct.
LieGrue,
strub
--- On Tue, 5/24/11, Pete Muir <pmuir(a)redhat.com> wrote:
> From: Pete Muir <pmuir(a)redhat.com>
> Subject: Re: [cdi-dev] Proxy implementation leaks
> To: "Mark Struberg" <struberg(a)yahoo.de>
> Cc: cdi-dev(a)lists.jboss.org
> Date: Tuesday, May 24, 2011, 7:24 PM
>
> On 24 May 2011, at 20:15, Mark Struberg wrote:
>
>>> Don't quite get this, spec requires that contexts
> are
>>> active only at particular points.
>>
>> yes but imagine the following
>>
>> @ApplicationScoped
>> public class MyService {
>> private @Inject User usr; /* User is RequestScoped */
>>
>> ...
>> }
>>
>> and this MyService will first get invoked in an EJB
> which gets initialized at startup. At this time there is NO
> Request Context active!
>> Thus if you would require all contextual instances
> being created immediately, then you would get a
> ContextNotActiveException...
>
> Yes, but this isn't that surprising and the principle of
> least surprise is a good one to follow ;-)
>
>>
>> LieGrue,
>> strub
>>
>> --- On Tue, 5/24/11, Pete Muir <pmuir(a)redhat.com>
> wrote:
>>
>>> From: Pete Muir <pmuir(a)redhat.com>
>>> Subject: Re: [cdi-dev] Proxy implementation leaks
>>> To: "Mark Struberg" <struberg(a)yahoo.de>
>>> Cc: cdi-dev(a)lists.jboss.org
>>> Date: Tuesday, May 24, 2011, 7:10 PM
>>>
>>> On 24 May 2011, at 19:38, Mark Struberg wrote:
>>>
>>>> Doing this in 2 phases is exactly what I mean
> with
>>> lazy initialisation. For the cyclic injection
> prevention it
>>> doesn't matter _how_ lazy.
>>>>
>>>> As you said: without splitting the proxy
> creation from
>>> the contextual instance creation, we would not be
> able to do
>>> proper cyclic injection. For this to work this
> must be a 2
>>> staged process. Like with forward references in
> compilers.
>>>
>>> Yes, however we can require that this is all done
> by a
>>> certain point.
>>>
>>>> Of course the current _very_ lazy behaviour
> might lead
>>> to curious situations sometimes (as in my
> example). But the
>>> 'eager' mechanism might lead to 'Context not
> active'
>>> Exceptions if you e.g. have a @RequestScoped field
> which
>>> isn't even touched when an @ApllicationScoped
> reference gets
>>> created in an asynchronous EJB. So you can decide
> between
>>> bad and evil ;)
>>>
>>> Don't quite get this, spec requires that contexts
> are
>>> active only at particular points.
>>>
>>>>
>>>> LieGrue,
>>>> strub
>>>>
>>>> --- On Tue, 5/24/11, Pete Muir <pmuir(a)redhat.com>
>>> wrote:
>>>>
>>>>> From: Pete Muir <pmuir(a)redhat.com>
>>>>> Subject: Re: [cdi-dev] Proxy
> implementation leaks
>>>>> To: "Pete Muir" <pmuir(a)redhat.com>
>>>>> Cc: "Mark Struberg" <struberg(a)yahoo.de>,
>>> cdi-dev(a)lists.jboss.org
>>>>> Date: Tuesday, May 24, 2011, 5:47 PM
>>>>> On reflection, I don't believe this
>>>>> is correct. The lazy init doesn't help
> with
>>> cyclic
>>>>> injection, it is simply the presence of
> proxies
>>> that does
>>>>> this.
>>>>>
>>>>> Consider that the DI graph is created
> using
>>> proxies, and
>>>>> call this phase 1. Weld currently does
> phase 1 on
>>>>> injection.
>>>>>
>>>>> Phase 2 is the actual instantiation of the
> objects
>>> backing
>>>>> this graph. Weld currently does phase 2
> lazily,
>>> when the
>>>>> first method on a proxy is called and
> needs to be
>>> passed to
>>>>> the bean (and this repeats through the
> graph).
>>>>>
>>>>> We need to split this into two phases, but
> there
>>> is no
>>>>> reason that we can't require
> implementations to do
>>> phase 2
>>>>> immediately that phase 1 has completed,
> before we
>>> give
>>>>> control to client code.
>>>>>
>>>>> On 9 May 2011, at 16:19, Pete Muir wrote:
>>>>>
>>>>>> Thanks Mark, I knew there was a reason
> for the
>>> lazy
>>>>> init.
>>>>>>
>>>>>> The two-ctor call is not necessary
> though.
>>>>>>
>>>>>> On 9 May 2011, at 16:15, Mark Struberg
> wrote:
>>>>>>
>>>>>>> actually this behaviour is pretty
> clear in
>>> EE.
>>>>> It's the same thing as we have with EJBs
> since
>>> almost ever.
>>>>> That's why @PostConstruct exists.
>>>>>>>
>>>>>>> Whenever object proxies or
>>> hidden/transparent
>>>>> serialisation happens, then we need to
> create the
>>>>> object/proxy on the other side/new
> invocation. And
>>> everytime
>>>>> this happens, the constructer will
> obviously get
>>> called.
>>>>>>>
>>>>>>> So this is not a bug and surely
> not a
>>> leak!
>>>>>>>
>>>>>>> This was on our list when I did a
> talk
>>> about CDI
>>>>> pitfalls at the JSFdays last year together
> with
>>> Dan.
>>>>>>>
>>>>>>> Maybe we should doument this
> better, but
>>> it's
>>>>> nothing for the spec, but the user
> documentation
>>> imo.
>>>>>>>
>>>>>>> Also the lazy init is imo a well
> specified
>>> and
>>>>> welcome behaviour. Look at the discussions
> way
>>> back about
>>>>> how to prevent cyclic injection problems.
>>>>>>>
>>>>>>> LieGrue,
>>>>>>> strub
>>>>>>>
>>>>>>> --- On Mon, 5/9/11, Christian
> Bauer <christian.bauer(a)gmail.com>
>>>>> wrote:
>>>>>>>
>>>>>>>> From: Christian Bauer <christian.bauer(a)gmail.com>
>>>>>>>> Subject: [cdi-dev] Proxy
>>> implementation leaks
>>>>>>>> To: cdi-dev(a)lists.jboss.org
>>>>>>>> Date: Monday, May 9, 2011,
> 2:46 PM
>>>>>>>> Started working with Weld
> 1.1.1 and
>>>>>>>> found two issues that probably
> should
>>> be
>>>>> addressed (maybe
>>>>>>>> just documented). They both
> look to me
>>> like
>>>>> leaking
>>>>>>>> implementation details because
> proxies
>>> are
>>>>> used for
>>>>>>>> components which are not
> @Singleton
>>> or
>>>>> @Dependent.
>>>>>>>>
>>>>>>>> @ApplicationScoped
>>>>>>>> public class Bug {
>>>>>>>>
>>>>>>>> public
> Bug() {
>>>>>>>>
>>>>>>>>
>>> System.out.println("##########
>>>>>>>> CONSTRUCT");
>>>>>>>> }
>>>>>>>>
>>>>>>>> public
> void foo() {
>>>>>>>>
>>>>>
> System.out.println("#####
>>>>>>>> FOO");
>>>>>>>> }
>>>>>>>>
>>>>>>>> public
> static void
>>>>> main(String[] args) {
>>>>>>>>
> Weld weld =
>>> new
>>>>> Weld();
>>>>>>>>
>>> WeldContainer
>>>>> weldContainer
>>>>>>>> = weld.initialize();
>>>>>>>>
>>>>>>>>
> Bug bug =
>>>>>>>>
>>>>>
> weldContainer.instance().select(Bug.class).get();
>>> //
>>>>> Creates
>>>>>>>> new instance of Bug
>>>>>>>>
> bug.foo();
>>> //
>>>>> Creates new
>>>>>>>> instance of Bug!!!
>>>>>>>>
> bug.foo();
>>> //
>>>>> Uses existing
>>>>>>>> instance
>>>>>>>>
>>>>>>>>
>>>>> weld.shutdown();
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>> The proxy of Bug will call
> its
>>> superclass
>>>>> constructor
>>>>>>>> several times during the
> lifecycle of
>>> the Bug
>>>>> component. I
>>>>>>>> don't know if that is really
>>> necessary, but if
>>>>> it is, you
>>>>>>>> can now no longer use
> constructors to
>>>>> initialize your
>>>>>>>> component. This is an issue
> because
>>>>>>>>
>>>>>>>> - it's not documented that
>>> constructors of
>>>>>>>> @ApplciationScoped (etc.,
> proxied)
>>> components
>>>>> behave
>>>>>>>> differently than
>>> @Singleton/@Dependent
>>>>> constructors
>>>>>>>>
>>>>>>>> - even if it's documented,
> it's
>>> questionable
>>>>> if that really
>>>>>>>> should be the case.
>>>>>>>>
>>>>>>>> Taking away constructors as
> the
>>> primary means
>>>>> of
>>>>>>>> initializing a component -
> e.g.
>>> obtaining
>>>>> resources such as
>>>>>>>> database connections, reading
> config
>>> files,
>>>>> etc. - is a
>>>>>>>> major change in the Java
> programming
>>> model.
>>>>> Users have to be
>>>>>>>> strongly advised to use
> @PostConstruct
>>> then.
>>>>>>>>
>>>>>>>> The other issue I immediately
> found is
>>> also
>>>>> related to
>>>>>>>> behavior of proxies and how
>>> transitive
>>>>>>>> initializing/injection is
> implemented
>>> (not
>>>>> sure if this is
>>>>>>>> actually specified
> somewhere):
>>>>>>>>
>>>>>>>> @ApplicationScoped
>>>>>>>> public class Foo {
>>>>>>>>
>>>>>>>>
> @Inject
>>>>>>>> Bar
> bar;
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>> @ApplicationScoped
>>>>>>>> public class Bar {
>>>>>>>>
>>>>>>>> @Inject
>>>>>>>> Baz baz;
>>>>>>>>
>>>>>>>>
>>> @PostConstruct
>>>>>>>> void
> init() {
>>> ... }
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>> When I obtain a reference to
> Foo, I
>>> get a
>>>>> proxy of Foo with
>>>>>>>> a reference to a proxy of Bar.
> The
>>> init()
>>>>> method of Bar is
>>>>>>>> never called. The Baz
> component is
>>> never
>>>>> activated.
>>>>>>>>
>>>>>>>> This means I can't
> transitively
>>> initialize an
>>>>>>>> application-scoped graph of
>>> components. I was
>>>>> trying to use
>>>>>>>> CDI for wiring in a Swing
> application
>>> and I
>>>>> imagine this
>>>>>>>> would be a common usecase. It
> should
>>> either be
>>>>> documented
>>>>>>>> that there is a difference
> between
>>>>> @Singleton/@Dependent and
>>>>>>>> proxy-implemented scopes, or
>>> unification
>>>>> should be
>>>>>>>> considered.
>>>>>>>>
>>>
>>>
>
>