[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