[cdi-dev] Proxy implementation leaks

Mark Struberg struberg at yahoo.de
Mon May 9 11:44:37 EDT 2011


add: but it was clear what I meant with the serialization part at least?

Since we try to shield all the serialization from our users, and each recontruction of a bean on the other side also causes a ct call (no magic involved, just plain java basics!), means you should not do any logic in the ct anyway.

LieGrue,
strub

--- On Mon, 5/9/11, Mark Struberg <struberg at yahoo.de> wrote:

> From: Mark Struberg <struberg at yahoo.de>
> Subject: Re: [cdi-dev] Proxy implementation leaks
> To: "Pete Muir" <pmuir at redhat.com>
> Cc: "cdi-dev at lists.jboss.org" <cdi-dev at lists.jboss.org>
> Date: Monday, May 9, 2011, 3:34 PM
> 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
> > >> 
> > 
> > 
> 
> _______________________________________________
> 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