[cdi-dev] Proxy implementation leaks

Mark Struberg struberg at yahoo.de
Mon May 9 11:30:59 EDT 2011


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