[cdi-dev] Proxy implementation leaks

Pete Muir pmuir at redhat.com
Mon May 9 11:29:08 EDT 2011


I'm not an expert on this, but AIUI subclass based proxying avoid the need for this.

On 9 May 2011, at 16:26, Arne Limburg wrote:

> Hi Pete,
> 
> how would you instantiate a client proxy, if not via a constructor? You need one call for the proxy and one call for the 'contextual instance'.
> Or am I missing some available java-magic?
> 
> Regards,
> Arne
> 
> -----Ursprüngliche Nachricht-----
> Von: cdi-dev-bounces at lists.jboss.org [mailto:cdi-dev-bounces at lists.jboss.org] Im Auftrag von Pete Muir
> Gesendet: Montag, 9. Mai 2011 17:20
> An: Mark Struberg
> Cc: cdi-dev at lists.jboss.org
> Betreff: Re: [cdi-dev] Proxy implementation leaks
> 
> 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 at gmail.com> wrote:
>> 
>>> From: Christian Bauer <christian.bauer at gmail.com>
>>> Subject: [cdi-dev] Proxy implementation leaks
>>> To: cdi-dev at 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.
>>> 
>>> 
>>> _______________________________________________
>>> cdi-dev mailing list
>>> cdi-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/cdi-dev
>>> 
> 
> 
> _______________________________________________
> cdi-dev mailing list
> cdi-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/cdi-dev




More information about the cdi-dev mailing list