mrszj / google-guice

Automatically exported from code.google.com/p/google-guice
Apache License 2.0
0 stars 0 forks source link

Lifecycle support #62

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Support for JSR-250 (javax.annotation) would also be very useful for all those 
people using init() 
methods and the list.

The mapping I think is:

@PostConstruct -> Called right after construction
@Resource -> Analogous to @Inject
@PreDestroy -> No concept of destruction, is there?
@Generated -> Doesn't apply

Original issue reported on code.google.com by h...@formicary.net on 14 Mar 2007 at 1:22

GoogleCodeExporter commented 9 years ago
Couldnt @Inject be made available on zero-arg methods (and invoked after all 
other
@Injects)? That would solve @PostConstruct

That being said, I feel that lifecycle methods are a legacy of setter-injection 
and
are superfluous in guice, especially as constructor injection is now on par with
spring-style setter injection (auto-wire with annotations).

It's also significant (different from guice) that @Resource (with no name=..)
connotes field names being used as ids. Should that be considered an implicit 
@Named?

Original comment by dha...@gmail.com on 14 Mar 2007 at 11:36

GoogleCodeExporter commented 9 years ago
lifecycle (which is what this is) will certainly be needed. +1 to hani's 
JSR-250 suggestion.

(and its bogus to say that cxtor injection is now "on par" with setting 
injection. picocontainer has been doing 
cxtor injection just as long as spring has been doing setter (trivial to tweak 
pico to use annotations). guice just 
does it in a super-elegant and java5-friendly way)

Original comment by peter.royal@pobox.com on 14 Mar 2007 at 11:43

GoogleCodeExporter commented 9 years ago
Nooo!

@Inject on no-arg methods is a hack. Nothing is being injected, it'd be an 
abuse of the annotation.

I do think that @Resource should work the way it's supposed to too (via field 
name). Guice should be flexible 
enough to be able to plug in different resolution mechanisms, and this is just 
one of them.

Original comment by h...@formicary.net on 15 Mar 2007 at 12:39

GoogleCodeExporter commented 9 years ago
proper lifecycle is much more of an app-server/container issue. IMO I think 
lifecycle
is overkill (you can currently do it just fine with ctors and @Inject-ed 
methods).
just imho of course. =)

yes I am well aware pico did ctor injection long before anyone else, that's not 
what
I was referring to.

Original comment by dha...@gmail.com on 15 Mar 2007 at 1:27

GoogleCodeExporter commented 9 years ago
yea come to think @Inject on no arg was a terrible idea

Original comment by dha...@gmail.com on 15 Mar 2007 at 1:29

GoogleCodeExporter commented 9 years ago
I am also deeply suspicious of the entire idea of "initialization" as separate 
from
object construction. I think I'm lacking that great example that shows me why
construction is sometimes not enough.

That said, I can imagine some real value in an object being notified when its 
Scope
has let it go.  (Or, sometime after its Scope has let it go; and perhaps 
individual
Scopes themselves need the flexibility to govern how strong their guarantee is 
in
this regard.)  Some objects, while 'alive', consume resources. You might for 
example
need to close yourself some closeables.

I wonder if this could be accomplished by having Guice or the Scope detect that 
your
object implements Closeable.

Original comment by kevin...@gmail.com on 15 Mar 2007 at 2:55

GoogleCodeExporter commented 9 years ago
Here's a very simple example.

You have field injection, and would like to do some init work.

You can't do it in the ctor since the fields can't be injected until after the 
ctor has run.

If you want concrete 'init' work, imagine I want to cache some data from an 
injected DataSource, if it's a field, 
how would I do this caching?

Original comment by h...@formicary.net on 15 Mar 2007 at 2:58

GoogleCodeExporter commented 9 years ago
Stock answer: then don't use field injection?  Now I need more meat to the 
example to
tell me why it has to be field injection. :)

Original comment by kevin...@gmail.com on 15 Mar 2007 at 6:04

GoogleCodeExporter commented 9 years ago
I'm inclined to lean on garbage collection for finalization logic. Or to 
delegate
responsibility to something like OSGi.

We really need an external post-injection/pre-scoping hook. Then you could do
whatever you want in a generic fashion:

1) Call an init() method or some annotated method.
2) Create a phantom reference to an object so you can close its resources before
garbage collection when the scope goes away.
3) Peform ad hoc injections. For example, Struts calls setters on interceptors 
with
parameters from the config file. 

Maybe something like this:

interface ProviderInterceptor<T> {
  T intercept(Key<T> key, Provider<T> next);  
}

Then you could apply them like this:

void bindInterceptor(Matcher<Key<...>> keyMatcher, ProviderInterceptor<...> 
interceptor);

Original comment by crazybob...@gmail.com on 15 Mar 2007 at 9:03

GoogleCodeExporter commented 9 years ago
Im with kevin--use ctor injection its safer (final publication), better 
(obvious to
non-guice factories) and has a tight contract (cannot partially inject a ctor 
like u
can with fields).

the only reason I use field inj is convenience/laziness. 

gc is probably a different stage of the lifecycle than closing/shutting 
down--we have
no control over gc, but my canonical example is: a servlet container may 
conceivably
want to signal a close hook to its beans (perhaps to cleanup the session), i.e.
injector.close(), which would be totally different to when those beans actually 
get
finalize()-d.

That having been said I still think proper lifecycle should be managed by an
appserver. Pico does both but clearly states them as disparate features in the 
doc.

Original comment by dha...@gmail.com on 16 Mar 2007 at 12:45

GoogleCodeExporter commented 9 years ago
I think we need more use cases. I've never actually needed to run code when the
session ends. If I really need to do this, I can always use the servlet API 
directly.
Sometimes I wonder if other frameworks support lifecycle methods just because 
it's so
easy to do.

Original comment by crazybob...@gmail.com on 16 Mar 2007 at 12:54

GoogleCodeExporter commented 9 years ago
I suppose ctor injection would be out if you were "reinjecting" an object (with
injectMembers) and wanted to rerun the init--in that case you could still fall 
back
on a setter/psuedo-ctor without needing an independent "init" method.

Original comment by dha...@gmail.com on 16 Mar 2007 at 1:00

GoogleCodeExporter commented 9 years ago
You may want to release resources on hotdeploys (like datasources)--which REALLY
shouldnt count on the gc but yea I cant think of many use-cases outside of
appserver-style ones. 

I dont really like the idea of lifecycle in DI anyway.

Original comment by dha...@gmail.com on 16 Mar 2007 at 1:05

GoogleCodeExporter commented 9 years ago
Here's a use case.

Being able to DI any POJO developed for use in Spring or EJB3. There's a ton of 
code
out there which relies on the Spring IoC model (injecting optional properties 
then
having a validation step after injection to double check things are OK). Most
libraries I'm aware of (Jetty, ActiveMQ et al) all tend to have their own
initialisation hooks. Indeed I'm not aware of any IoC container apart from Guice
which does not support at the very least an initialisation callback mechanism.

If you're writing really simple POJOs which only have a set of mandatory
dependencies, then sure constructor injection avoids the need for an init step 
(as
the Pico folks promoted years ago).

However as soon as you have complex objects with multiple optional properties 
which
may or may not be set, some of which may be mutually exclusive and need some 
kind of
on-start validation, its much much cleaner to have a single well defined init 
method
called (where you can check all the various optional parameters are fine and do 
any
on-start-up caching & calculation etc).

The great thing about the init method is its called by the IoC container in 
context
immediately after injection; so if there are any configuration issues (mostly 
the
init callback is used to double check configuration when optional injections 
are used
after-all) then the IoC container is capable of giving a better error message 
as its
aware of the module/binder/injector being used. This avoids a runtime barf 
later on
when the injection context & information is lost.

Original comment by james.st...@gmail.com on 16 Mar 2007 at 7:04

GoogleCodeExporter commented 9 years ago
Sorry, I meant use cases for the "tear down"/"stop" side of things.

The general ProviderInterceptor mechanism I suggested above should be able to 
support
any type of "init" design--calling a method on an interface, calling an 
annotated
method, running external logic, etc.

Original comment by crazybob...@gmail.com on 16 Mar 2007 at 3:23

GoogleCodeExporter commented 9 years ago
OK the common use case in EJB3 or Spring POJOs is to close down expensive 
resources
like JDBC connections and the like when a scope is closed; e.g. using a 
request-scope
for processing web requests or more commonly, singleton POJOs created within an
application scope.

e.g. its fairly common in web applications to have some singleton POJOs which 
need
closing down in the correct order (as there is often a dependency order so you 
wanna
close things down in the reverse order to which they were started). For things 
like
JDBC connections, background threads, sockets and the like you typically don't 
wanna
just pray and hope on GC kicking in and finalizers sorting it out for you. e.g. 
folks
usually want their web applications to close down nice and promptly.

This could be implemented using a provider interceptor; calling a stop method 
is just
a reverse of calling a start method etc. Its just the stop interceptor needs to
register the stop method call with a listener to Scopes closing down.

So to nicely support Spring POJOs we'd just look for DisposableBean interface; 
for
EJB3 we look for @PreDestroy then call 'em when the scope closes down (FWIW I'm 
not
sure what Spring does for non-singletons :)

Original comment by james.st...@gmail.com on 17 Mar 2007 at 7:29

GoogleCodeExporter commented 9 years ago
The only action we plan to take on this is to resolve issue 78.  After we do 
that we
should be able to close this one.

Original comment by kevin...@gmail.com on 19 Mar 2007 at 6:31

GoogleCodeExporter commented 9 years ago
Tear down/close hooks can be very useful for session-scoped beans that may hold
resources or need to notify someone else about their destruction.

Original comment by ekules...@gmail.com on 20 Apr 2007 at 9:22

GoogleCodeExporter commented 9 years ago
I have this "Spring-based" swing application that I'd like to convert to Guice, 
as
I'm fed up by the refactor-unfriendlyness of the string identifiers. I've just
started looking into Guice for real, so I might easily be missing lots..

However, right after ditching Spring from the classpath to start my convertion, 
I
quickly ran into the problem of destroy-methods. I'd like to be able to 
"reboot" the
entire application, and that obviously (at least to me, please enlighten me if 
I'm
missing something) requires a rather extensive use of destroying.

Is there a way to get hold of all objects that Guice have instantiated? Is it
possible to inject some kind of listener that lets me know which objects are 
created,
so that I could destroy them myself?

Basically, I'd like a Inject.destroy()/stop() method - but I'd be happy to make 
it
myself it is possible.. Hooks into the "internals" would be great.

Original comment by stolsvik on 5 Jun 2007 at 4:47

GoogleCodeExporter commented 9 years ago
Don't you have some root object you could just throw away and re-create? Is 
there
some reason that garbage collection won't work?

If not, construction listeners (coming in the next release) will do what you 
need.

Original comment by crazybob...@gmail.com on 5 Jun 2007 at 4:55

GoogleCodeExporter commented 9 years ago
.. okay, listeners sounds good!

When it comes to garbage collection, I really don't like to rely on that for
"external resources" - I thought that was "basic java": you might, for example, 
use
up all your database connections if there suddenly are two or more db pools 
hanging
around, and System.gc() is just a _hint_ to the runtime that you'd like GC to 
happen.
Threads won't die either w/o some explicit "we're going down" message.

Googling "finalization java" gives several articles pointing out this fact, e.g.
"Don't rely on finalizers to release non-memory resources. ...But the same 
program
may fail on a different JVM whose garbage collector doesn't finalize often 
enough to
keep the program from running out of file handles."

(Really a mailinglist question, but..) Is there a timeframe for next version? Is
there a place where I can find such info myself?

Original comment by stolsvik on 5 Jun 2007 at 7:06

GoogleCodeExporter commented 9 years ago
You should release a critical resource in a finally block in close proximity to 
where
you acquired the resource. Waiting for a framework to call you back means you're
holding onto the resource longer than necessary and taking the risk that it 
won't get
cleaned up.

We don't have a concrete date for the next release yet, but it won't be long.

Original comment by crazybob...@gmail.com on 5 Jun 2007 at 8:07

GoogleCodeExporter commented 9 years ago
In other words, no object should ever hold a resource "occupied" between method
invocations?  Only within the confines of a single method call?

Original comment by kevin...@gmail.com on 5 Jun 2007 at 8:59

GoogleCodeExporter commented 9 years ago
I wouldn't say that. More detailed use cases would help.

Original comment by crazybob...@gmail.com on 5 Jun 2007 at 9:25

GoogleCodeExporter commented 9 years ago
If objects are created in a scope, it only
makes sense that they can be informed that the scope
is gone. 

The "classic" example is an object grabbing an expensive
non-gcable native in a scope and being informed that the
scope is gone - so it can release the resource in a timely
fashion. It may not be possible to release the resource
in the body of a function - i.t may for example be a handle
to a window.

Original comment by peter.ki...@gmail.com on 5 Jun 2007 at 10:17

GoogleCodeExporter commented 9 years ago
crazyboblee: so I should make my database _pool_ where I need a database 
connection,
and then kill it when I don't need the connection anymore in a finally? Great 
idea.

It is of course possible to handle _all_ external resources ("heavy Closables")
outside of Guice, and take care of destruction myself. That will however lessen 
the
value of Guice slightly, I believe.

(.. but so far I like it real good! XML-hell be gone!)

Original comment by stolsvik on 7 Jun 2007 at 12:40

GoogleCodeExporter commented 9 years ago
Ha ha. I was talking about releasing connections for example, but why does 
Guice need
to tear down my connection pool? When should this happen?

We're trying to find a solution to a problem we haven't really defined.

Original comment by crazybob...@gmail.com on 7 Jun 2007 at 1:09

GoogleCodeExporter commented 9 years ago
bob: i think the thing here is "in and out of scopes", like kevin refers to 
comment 6.

If I'm instantiated within some scope, I'd possibly like to know when that 
scope is
no more, so that I can release any non-memory resources.

However, there is a difference between singleton and instance "beans" (objects) 
here.
Spring solves this by explicitly stating that the destroy methods won't be run 
on
"prototype" beans (which are "instance"), while singleton beans (which are 
default in
Spring), and the other scopes (request and (global) session) will have their 
destroy
run.
http://www.springframework.org/docs/reference/beans.html#beans-factory-scopes-pr
ototype

This is pretty much OK, I think, since those "expensive" objects most likely 
will be
of a "singleton" character (a db pool, or some other ERP connection used 
throughout
some scoped call), while instance objects are of a "use and ditch"-character,
probably just holding onto memory, and should be able to cope with only their
finalizer being run, OR the method they're injected into should handle the 
closing.

This goes hand in hand with the logic that states that "don't clean anything 
other
than RAM in finalizers".

Thus basically, if only Guice somehow would let me known which objects it's 
currently
"caching" (since I guess it'll have to do just that to handle the "singleton 
scope"),
I could really manage destroy myself.

Original comment by stolsvik on 8 Jun 2007 at 1:27

GoogleCodeExporter commented 9 years ago
As a further point towards init() methods.

I just got myself Brian Goetz's "Java Concurrency in Practice". In chapter 3.2.1
"Sharing Objects -> Publication and escape -> Safe construction practices" 
(p.41),
one may read "Do not allow the this reference to escape during construction". 
This
was actually something I hadn't thought about: if you in a constructor do some
EventListener registration, you let the *not yet fully constructed* object 
"escape",
and the eventlistener registration may invoke methods further down the line, or 
back
on the object. Another interesting issue is to start Threads in the constructor,
again exposing the not-yet initialized object to a new running stack context. 
This
obviously also goes for staring timers and threadpools. Both of these errors 
may lead
to a whole bunch of interesting fuck-ups.

Brian suggest as a solution "expose a start() or initialize() method...", or 
make the
constructor private, and expose a static factory method instead (that does the
"init()"). I guess this could be realized by using Providers, but wouldn't it be
easier with a @Initialize annotation possible on no-args methods?

Original comment by stolsvik on 11 Jul 2007 at 1:00

GoogleCodeExporter commented 9 years ago
PS: I just realized that this bug concerns two entirely different concepts: the 
JSR
250 annotations, and object lifecycle handling.

I HIGHLY vote for the JSR 250 annotations being honored, natively, by Guice. One
should even consider to just drop (at least deprecate) the corresponding Guice
annotations.

(I also vote for the lifecycle methods (obviously, given my comments).)

Original comment by stolsvik on 11 Jul 2007 at 7:47

GoogleCodeExporter commented 9 years ago
I just got this message: "This is a proxy used to support circular references
involving constructors. The object we're proxying is not constructed yet. 
Please wait
until after injection has completed to use this object."

a) Why doesn't it say which object we're talking about - the class?

.. but my point is b) This is what happens when I need to do initialization 
stuff in
the constructor (here obviously trying to use the injected stuff), not having a
dedicated init-method that could be invoked afterwards. How can i wait "until 
after
injection has completed", when I need to do initialization stuff, and Guice 
refuses
to have init-methods?!

.. but also c) Isn't silent proxying like this un-good (performance wise)? 
Spring
handles circular dependencies only if one of the classes in the circle have a 
setter
instead of constructor injection, which breaks the circle (it "eagerly caches 
the
instance for resolving circular dependencies"). (And spring have support for
init-method, did I mention that?! :))

Original comment by stolsvik on 8 Aug 2007 at 1:40

GoogleCodeExporter commented 9 years ago
Following up on point 27, in a web application context, if you want to
redeploy the application many times without running out of memory, you
need to ensure that any resources that reference the web application's
class loader are properly freed or that any objects in the parent
class loader do not have references to objects inside the web
application.  The gc on its own cannot clean this up.

If you don't programmatically close the resources, then references
from them to the web application class loader will prevent the class
loader, any classes loaded by it and all static variables from being
gc'ed.  After a number of redeployments, the JVM runs out of permanent
generation space, throws a OutOfMemoryError and you have to bounce the
process.

One common resource that needs to be shutdown are any threads started
in the web application since they contain a reference to the class
loader.

So you need an explicit shutdown method.

See this page for a discussion of the different libraries that can
keep a class loader from being gc'ed.

http://opensource.atlassian.com/confluence/spring/pages/viewpage.action?pageId=2
669

In our case, we start an Ice server with 30 threads and a Java
memcached client which has its own pool management thread, both are
singletons.  As stolsvik stated, it looks like I would need to ask the
Injector for the singleton's that it constructed and then run a
shutdown method on them.

The one problem with this is that then I manually have to make sure I
shut them down in the correct order, when Guice already knows the
correct order from the dependencies when it constructed them.

Original comment by blair-ol...@orcaware.com on 13 Feb 2008 at 6:14

GoogleCodeExporter commented 9 years ago
I believe this could be implemented as a custom scope that remembers everything 
it's scoped. The scope 
would know whenever it provides a given object, and it could track which object 
need to be disposed when 
the scope ends.

Usually we have a hook when a scope is exited, and we could dispose the 
appropriate objects at that time. 

The tricks:
 - finding dispose() methods. This could be a marker interface on the returned instance, on the Key's type, or 
even just an annotated method somewhere.
 - not leaking memory

The nice thing about implementing this as a custom scope is that it doesn't 
make Guice's internals more 
complex than they already are. The bad thing about implementing it as a custom 
scope is that it competes 
with Guice's built-in scopes for request, session, etc.. It would be reasonable 
for a first-pass at this to fork 
Guice's servlet extension. And we might even fold-in the implementation if it 
seems to work okay.

Original comment by limpbizkit on 30 May 2008 at 8:21

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
I'm with limpbizkit; handling the @PreDestroy or close type of lifecycles is a 
responsibility of the Scope instances; as they are the objects capable of 
knowing when the scope is closed - so it can register objects in the scope and 
then close them when it is being shut down. 

Already the servlet REQUEST and SESSION scopes already maintain a registry of 
objects within that scope - and they are easily capable of knowing when 
those objects go out of scope. So there really should be an easy way to 
register some kind of hook to process all objects about to be closed via a 
Scope 
closing; we can then let folks register SPI hooks to invoke different shut down 
mechanisms (e.g. auto-detecting Spring's DisposableBean interface - or 
using @PreDestroy or some other user annotation driven mechanism etc).

i.e. rather than the end user having to replace the standard guice scopes for 
REQUEST/SESSION to get the @PreDestroy / DisposableBean behaviour this 
should be a standard feature IMHO. It may be that Guice out of the box comes 
with no registered destroy handlers, but we should allow folks to use 
additional Guice libraries to support @PreDestroy / DisposableBean without 
having to move away from standard Guice scopes.

I'd also like to see a standard guice ApplicationScope that was easy to use; so 
folks could create one or more application scopes, let Guice do the 
injection; then at some point later on, close the application scope and have 
all the singletons in that scope shut down cleanly (like folks do in Spring / 
Pico / HiveMind / Plexus).

For the initialisation hooks, the guice framework knows when an object has been 
created; so the Scopes don't really need to be involved; but some 
kinda post-construction handler mechanism would be cool - so folks could use 
the SPI to invoke methods annotated with @PostConstruct or invoke 
objects with some kind of custom lifecycle interface like Spring's 
InitialisingBean.

So in summary, I'd love Guice to have some kinda lifecycle hook in the SPI 
which the default APPLICATION/REQUEST/SESSION scopes invoked on the 
close of a scope and invoked on the post-construction of an object. Hopefully 
folks can register multiple implementations of this handler; so folks can 
add an implementation for JSR 250, one for Spring, one for registering objects 
into the OSGi registry if annotated with something and for other 
frameworks and custom lifecycle interfaces etc. 

Original comment by james.st...@gmail.com on 30 Sep 2008 at 10:45

GoogleCodeExporter commented 9 years ago
I've taken a stab at adding support for @PreDestroy and Spring's DisposableBean 
lifecycles; building above my 
patch for issue 78: http://code.google.com/p/google-guice/issues/detail?id=78.

So far they only work with Singleton scoped objects; but I've also added the 
functionality into the REQUEST and 
SESSION scoped Scopes too - though I've not yet added any code to the Servlet 
package to invoke the close() 
methods yet.

I've introduced a Closeable interface which a Scope or Provider can implement; 
so if a Scope implements 
Closeable you can then close it down cleanly; ensuring that all objects are 
closed and each exception thrown 
is collected (rather like we do with the Errors class when binding objects). 

Also I've added a close() method to Injector so you can close down any 
singleton objects.

e.g. 

  Injector injector = Guice.createInjector(...);

  // do stuff

  // now lets cleanly close down the singletons in this injector
  injector.close();

There are many possible strategies we can use to actually close down an object 
held within a 
Singleton/REQUEST/SESSION scope . e.g. respecting java.io.Closeable; or using 
@PreDestroy on a method or 
Spring's DisposableBean or some developer-defined lifecycle API/annotation 
mechanism etc.

So I've introduced a strategy interface, Closer which is a strategy to close 
objects down. So you can bind as 
many Closer implementations into your binder and this patch will invoke them 
all on each object in the scope 
being closed. e.g. so you could install the JavaIO, JSR250 and Spring closers 
to respect those lifecycles. If you 
look at some of the Closer implementations in this patch it will become a bit 
more clear.

Note this patch has no effect to objects created outside of a singleton (and is 
currently not invoked for 
REQUEST/SESSION scopes).

The code InjectorImpl.close() and REQUEST/SESSION scopes is fairly 
straightforward. The more complex 
change was dealing with the Singleton scope; as the singleton SINGLETON object 
creates Providers for each 
key which internally stores the singleton object. So to be able to close all 
the singletons on an injector you 
need to iterate through all the Providers in the bindings looking for providers 
which are Closeable. Since 
there's a lot of wrapping of Providers along with InternalFactory; I made a 
number of internal wrappers and 
adapters also implement Closeable. This should have no runtime effect when 
folks don't invoke the 
Injector.close() method.

Original comment by james.st...@gmail.com on 6 Oct 2008 at 1:39

Attachments:

GoogleCodeExporter commented 9 years ago
Is there any chance to get these functionality as an _extension_ of guice? These
solution seems to add two (?) more dependencies (javax.annotation.* is part of 
JRE6)
to the framework. The majority of developers will use at most one of the 
lifecycle
mechanisms.

Solving this like limpbizkit had it in mind (using custom scopes) would allow 
us to
use different lifecycle demarcation mechanisms (javax.annotation, 
DisposableBean,
etc.) depending on the actual needs.

Additionally I would like to see a solution that does not based on a servlet
container. There are lots of people using guice in standalone applications and 
these
people might have a need for lifecycle support too ;) Lifecycle support should 
also
cope with other environments.

Original comment by sven.lin...@gmail.com on 7 Oct 2008 at 3:51

GoogleCodeExporter commented 9 years ago
BTW my patch is modular. The jsr250 module is optional (and is the module that 
depends on JSR250) ditto the 
Spring code is in the spring module.

However the support for ConstructorInterceptor has to kinda go into the core 
guice package as its code is like 
that of MethodInterceptor which is already in the core. The core guice module 
still just depends on the 
aopalliance.jar so no new dependency has been introduced in the core module; 
the spring module is still 
dependent on spring and the new optional jsr250 module is just dependent on the 
JSR 250 API

Original comment by james.st...@gmail.com on 7 Oct 2008 at 3:57

GoogleCodeExporter commented 9 years ago
Hi, i write this because of some frustation reading the block here. For me it 
seems
that some are thinking of guice as a tool for osgi and j2ee ONLY. if guice 
should be
just that - ok - but then guice should be renamed to just another tool to make 
the
j2ee world bigger. Guice is advertized as "next-generation dependency injection
container for Java 5 and later".
Back to the issue - guice outside of a managed container has no livecycle 
management
at all if field or method injections are used. Except for "constructor only
injections" there is no single point of "being initialized". But field and 
method
injection are part of guice - aren't they?
Isn't that missing livecycle a serious issue by itself? I think that's what Sun 
has
forseen with it's javax.annotation package in java6 - smart,because this is an
architecture issue not just a usage case.
Someone asked here for usage cases - beside I think that's the wrong question 
for a
fundamental package like guice - nevertheless here is one for a Swing based 
application:

I wanted to use guice in a swing based environment to bootstrap a Swing 
application.
Having hundreds of JPanel's needing access to hierachical application wide 
services.
In a single panel there may be 2 to 50 other JComponent's and other classes
constructed. So to use juice I found three choices:
1.) use guice and constructor only injectors for the panels- then I endup with
constructors with up to 50 parameters and initialize the panel inside of this 
huge
constructor - very very ugly  
2.) pass (or inject) a Injector instance into all panels and use
injector.getInstance(...) - then I don't need guice - any singleton pattern 
could do
that same thing better.
3.) don't use guice
I think we end up to go with the option 3.)
Note: the application wide services in our case are hierachical  and would fit 
very
well into guice Scope and Stage concept - many of these services are not just
singletons. Guice would have helped a lot if there would be a point where the 
panels
could be "initialized" after being fully constructed (and injected). In this
environment there is no way around an init() or createComponent() or
postConstructed() pattern. Or you end up with "constructor-only" classes.
Just to strengthen my point for those knowing the Eclipse architecture: Eclipse
implementation solved this by using inheritance - ending up with a almost 
endless -
in my opinion - very ugly class hierachy of 10th of levels of inheritance. Any 
simple
eclipse panel (pane) knows by inheritance any service providers of eclipse!!! A
Service oriented architecture for an ui would have been much cleaner.

Original comment by heinz.in...@googlemail.com on 5 Dec 2008 at 10:06

GoogleCodeExporter commented 9 years ago
Just to keep this thread up to date; using trunk of Guice its now easy to 
implement @Resource injection (this 
works perfectly now in GuiceyFruit using the trunk of Guice) and @PostContruct 
is pretty much there - though 
there's a potential ordering issue of post inject hooks being invoked before 
custom injections have all taken 
place - see 
http://code.google.com/p/google-guice/issues/detail?id=351

The only missing piece now is being able to close resources which are bound to 
some scope (e.g. singleton, 
request, session etc). There's no current way to implement @PreDestroy from JSR 
250 or DisposableBean from 
Spring using trunk of Guice.

I'll try refactor my old patches into a simpler patch just for this issue and 
spin up a new issue to track its 
progress

Original comment by james.st...@gmail.com on 3 Apr 2009 at 10:04

GoogleCodeExporter commented 9 years ago
"he only missing piece now is being able to close resources which are bound to 
some scope (e.g. singleton, 
request, session etc). There's no current way to implement @PreDestroy from JSR 
250 or DisposableBean from 
Spring using trunk of Guice."

Why not? you can register the objects before firing post-construct and provide 
an api or jvm shutdown hook to 
call pre-destroy...

Original comment by dha...@gmail.com on 3 Apr 2009 at 10:12

GoogleCodeExporter commented 9 years ago
@dhanji: actually thats a neat idea :)

I'm gonna take a stab at trying to implement that.

My only reservation is that all the scopes (application, request, session) 
*already* store the objects (they have 
to so that they can be reused within the scope). 

So all we need really need is a way of iterating through all the objects in a 
scope so they can be closed. (e.g. 
iterating through the request/session scopes in the servlet or through the 
injector's bindings for application 
scope). It does feel a bit dirty and inefficient having another Map for each 
application/request/session scope 
and copying all objects into them just because Guice can't expose a hook to 
process all objects within a 
scope.

But in the meantime you're idea is a great workaround :)

Original comment by james.st...@gmail.com on 3 Apr 2009 at 10:36

GoogleCodeExporter commented 9 years ago
@dhanji: it also saves me the dread of trying to merge an old massive & complex 
patch against trunk of Guice 
which has changed alot - many thanks :)

Original comment by james.st...@gmail.com on 3 Apr 2009 at 10:47

GoogleCodeExporter commented 9 years ago
@james.strachan

=)

You can hook into most of the scopes, by rebinding the annotations to your own 
scoping wrapper and fire the 
destroy event appropriately. Note that Guice Servlet already fires destroy() 
properly on the servlet lifecycle event 
and can be hooked into in webapps...

Original comment by dha...@gmail.com on 3 Apr 2009 at 11:20

GoogleCodeExporter commented 9 years ago
Why didn't anyone mention a hibernate Session, which MUST be closed after use?

Original comment by elijah.e...@gmail.com on 13 Apr 2009 at 11:27

GoogleCodeExporter commented 9 years ago
And more provocative question:
- How can you call a Scope scope when it can't terminate?

This is just to highlight that a tool that provides means of creating objects 
must
also provide means to properly destroy them. Or else how could I create an 
expensive
object except of in Scopes.SINGLETON?

Original comment by elijah.e...@gmail.com on 13 Apr 2009 at 11:40

GoogleCodeExporter commented 9 years ago
@45

"Why didn't anyone mention a hibernate Session, which MUST be closed after use?"

If you use warp-persist this is done for you on transactions or Http requests 
(or any granularity of session, 
really). You can even set up a scope around the session or transaction, which 
is consistent with our philosophy to 
keeps scopes simple (by making scoping orthogonal to domain use cases).

Original comment by dha...@google.com on 14 Apr 2009 at 12:09

GoogleCodeExporter commented 9 years ago
BTW the patch on this issue: 
http://code.google.com/p/google-guice/issues/detail?id=354 provides a 
solution to the last remaining issue with lifecycle support - being able to 
iterate through objects within a 
scope so that you can close them (other than using a scope specific work around 
such as the servlet 
request/session scopes that @dhanji mentions). We're using this mechanism right 
now in GuiceyFruit to 
support @PreDestroy and Spring's DisposableBean interface.

I'm not sure which way this will go though; there's more discussion on various 
possible implementations here:
http://groups.google.com/group/google-guice/browse_thread/thread/da6af0961cf4a5d
6

I certainly hope that some mechanism can be added though :)

Original comment by james.st...@gmail.com on 15 Apr 2009 at 3:49

GoogleCodeExporter commented 9 years ago
for the one expecting the feature, here is a "snipper" of mine:
//annotatedMethods is a simple method that return a list of any methods (and 
super ones, that has the given annotation)
public static <T extends Annotation> List<Method> annotatedMethods(Class<?> 
target, Class<T> annotationClass) {
        List<Method> methods = new ArrayList<Method>();
        while (target != null) {
            for (Method m : target.getDeclaredMethods()) {
                T annotated = m.getAnnotation(annotationClass);
                if (annotated != null) {
                    methods.add(m);
                }
            }
            target = target.getSuperclass();
        }
        return methods;
    }

// the type listener itself
public class JFormDesignerTypeListener implements TypeListener {

public <T> void hear(TypeLiteral<T> typeLiteral, TypeEncounter<T> 
typeEncounter) {
        Class<? super T> raw = typeLiteral.getRawType();
        List<Method> methods = annotatedMethods(raw, PostConstruct.class);
        typeEncounter.register(new JFormDesignerInjector<T>(methods));
}
}

//and the JFormDesignerInjector :

class JFormDesignerInjector<T> implements MembersInjector<T> {
    private List<Method> methods;
    public JFormDesignerInjector(List<Method> methods) {
            super();
            this.methods = methods;
        }

        /**
         * @param t
         */
        public void injectMembers(final T t) {

            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    for (Method m : methods) {
                        try {
                            m.setAccessible(true);
                            m.invoke(t, null);
                        } catch (InvocationTargetException ite) {
                                                assert false : "Static Exception Occurred. @PostConstructor Method raises an exception:" + t.getClass() + ":" + m.getName() + " raises :" + 
ite.getTargetException() + " : " + ite.getTargetException().getMessage();
                        } catch (Throwable e) {
                        assert false : "Static Exception Occurred. @See logs for more details in: " + JFormDesignerInjector.this.getClass().getName() + " " + 
e.getMessage();
                        }
                    }
                }
            });
        }

I've tried to simplified my actual code ( in fact I've mixed bean  injections 
from JFormDesigner and @PostConstructor ).

The main idea here is to use the swing invokelater to handle the 
PostConstructor. this is quite nice for "swing" requirements ( as I had ).

Original comment by ericaro on 5 Jan 2010 at 4:48

GoogleCodeExporter commented 9 years ago
Dhanji and I discussed this at length this evening. We're thinking about taking 
a Service interface, inspired by the one in Guava, with these methods. Note 
that start() is renamed to startAsync() and likewise for stop:
  interface Service {
    boolean isRunning();
    State state();
    Future<State> startAsync();
    void startAndWait();
    Future<State> stopAsync();
    void stopAndWait();
  }
http://code.google.com/p/guava-libraries/source/browse/trunk/src/com/google/comm
on/base/Service.java?r=49

In addition, we'd like to support listeners on services, so objects could 
register to be notified when a service changes state. The granularity of 
registration may be by service instance or perhaps by Guice Key.

We were also discussing the interplay between services and scopes. It might be 
useful to create a scope that's keyed off of a Provider<Service> for a 
particular service, and whose objects are in scope only while a service is 
running. This idea isn't fully baked.

Original comment by limpbizkit on 23 Jul 2010 at 6:32