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(a)openknowledge.de> wrote:
From: Arne Limburg <arne.limburg(a)openknowledge.de>
Subject: AW: [cdi-dev] Proxy implementation leaks
To: "Pete Muir" <pmuir(a)redhat.com>, "Mark Struberg"
<struberg(a)yahoo.de>
Cc: "cdi-dev(a)lists.jboss.org" <cdi-dev(a)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(a)lists.jboss.org
[mailto:cdi-dev-bounces@lists.jboss.org]
Im Auftrag von Pete Muir
Gesendet: Montag, 9. Mai 2011 17:20
An: Mark Struberg
Cc: cdi-dev(a)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(a)gmail.com>
wrote:
>
>> From: Christian Bauer <christian.bauer(a)gmail.com>
>> Subject: [cdi-dev] Proxy implementation leaks
>> To: cdi-dev(a)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(a)lists.jboss.org
>>
https://lists.jboss.org/mailman/listinfo/cdi-dev
>>
_______________________________________________
cdi-dev mailing list
cdi-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/cdi-dev