[cdi-dev] Proxy implementation leaks

Pete Muir pmuir at redhat.com
Mon May 9 11:36:37 EDT 2011


Yes, that is the proposal.

On 9 May 2011, at 16:34, Mark Struberg wrote:

> imo once for *every* instance you create.
> 
> And each proxy == instance imo.
> 
> Marius, Stuuu, think we need you guys to clarify this.
> 
> txs and LieGrue,
> strub
> 
> --- On Mon, 5/9/11, Pete Muir <pmuir at redhat.com> wrote:
> 
>> From: Pete Muir <pmuir at redhat.com>
>> Subject: Re: AW: [cdi-dev] Proxy implementation leaks
>> To: "Mark Struberg" <struberg at yahoo.de>
>> Cc: "Arne Limburg" <arne.limburg at openknowledge.de>, "cdi-dev at lists.jboss.org" <cdi-dev at lists.jboss.org>
>> Date: Monday, May 9, 2011, 3:32 PM
>> You can't enhance the class without
>> either a javaagent or bytecode instr.
>> 
>> If you use subclassing you only need to call the ctor of
>> the superclass once, not twice as it stands today.
>> 
>> On 9 May 2011, at 16:30, Mark Struberg wrote:
>> 
>>> was about to ask the same ;)
>>> 
>>> If there is some subclassing involved, then you will
>> need to call the constructor of the superclass. You cannot
>> solve this another way without changing the original class.
>>> 
>>> There is only one magic trick, but this is a pretty
>> heavyweight one:
>>> 1.) dynamically create an interface with all the
>> methods from the class hierarchy from the proxied class
>>> 2.) create a java.lang.reflect.proxy for the
>> interface
>>> 3.) dynamically _change_ the original proxied class to
>> additionally implement the freshly generated interface
>>> 
>>> This is pretty much work, but imo the only way which
>> works.
>>> The downsides are that you need to 'enhance' the
>> original class, which might cause ClassCastExceptions and
>> lots of other nasty problems...
>>> 
>>> LieGrue,
>>> strub
>>> 
>>> --- On Mon, 5/9/11, Arne Limburg <arne.limburg at openknowledge.de>
>> wrote:
>>> 
>>>> From: Arne Limburg <arne.limburg at openknowledge.de>
>>>> Subject: AW: [cdi-dev] Proxy implementation leaks
>>>> To: "Pete Muir" <pmuir at redhat.com>,
>> "Mark Struberg" <struberg at yahoo.de>
>>>> Cc: "cdi-dev at lists.jboss.org"
>> <cdi-dev at lists.jboss.org>
>>>> Date: Monday, May 9, 2011, 3:26 PM
>>>> 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