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