[cdi-dev] Proxy implementation leaks
Pete Muir
pmuir at redhat.com
Mon May 9 11:19:49 EDT 2011
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
>>
More information about the cdi-dev
mailing list