tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stephen Connolly <stephen.alan.conno...@gmail.com>
Subject Re: Singleton + Timer service
Date Tue, 09 Feb 2010 16:30:41 GMT
On 9 February 2010 16:23, Jason Russo <jrusso@genscape.com> wrote:

> These are some excerpts taken from the JavaEE 5.0 spec document:
>
> "The specifications for the various application component types describe
> which classes may be annotated for injection, as summarized in Table
> EE.5-1.
> They also describe when injection occurs in the lifecycle of the
> component.
> Typically injection will occur after an instance of the class is
> constructed, but
> before any business methods are called. If the container fails to find a
>

I take this to mean that you are not allowed to call any business methods of
the injectables.... as it reads like a "cuts both ways" statement.


> resource
> needed for injection, initialization of the class must fail, and the
> class must not be
> put into service."
>
> ...
>
> "In some cases a class may need to perform initialization of its own
> after all
> resources have been injected.


This one does not specify what operations are allowed in your classes
initialization after the resources have been injected.


> To support this case, one method of the
> class may be
> annotated with the PostConstruct annotation. This method will be called
> after all
> injections have occured and before the class is put into service. This
> method will
> be called even if the class doesn’t request any resources to be
> injected. Similarly,
> for classes whose lifecycle is managed by the container, the PreDestroy
> annotation may be applied to one method that will be called when the
> class is
> taken out of service and will no longer be used by the container. Each
> class in a
> class hierarchy may have PostConstruct and PreDestroy methods. The order
> in
> which the methods are called matches the order of the class hierarchy
> with
> methods on a superclass being called before methods on a subclass."
>
> --------------------------------------------
> So, am I wrong to take these statements as meaning that injected
> resources
> should already be initialized (I'm taking the use of the term
> 'constructed' above
> to mean the same)?


They will have been initialized, but they may not have been put into
service.

Initialized = Constructed and Injectables injected
Put into Service = Sometime after @PostConstruct returns successfully.

And the spec does not seem to specify whether components can be put into
service as their @PostConstruct completes, or whether the container can wait
until all classes are ready to be put into service....


>  Even so, it states that injection will be performed
> 'before
> any business methods are called', which I assume includes even the
> @PostConstruct
> method.
>
>
>
> Jason Russo
>
> Application Developer
>
> Genscape– See the Energy
>
> 445 E. Market St, Suite 200
>
> Louisville, KY 40202
>
> Tel: 502-583-2091
>
> www.genscape.com
>
>
>
> On Mon, 2010-02-08 at 20:40 -0500, Stephen Connolly wrote:
>
> > but if you are injecting another ejb from your jar it may not have
> > been postconstructed... if there are some cases where you might have
> > some injected references which are not postconstructed when you are
> > being postconstructed, then the spec way is to define that the
> > postconstructed state of all injectables is undefined while you are
> > being postconstructed...
> >
> > some containers can then choose to put effort into an optimized
> > postconstruct order, while others can go for quick and dirty... and if
> > A depends on B and B depends on A, we will always have to
> > postconstruct one first.
> >
> > check the spec, but my gut is that postconstruct only guarantees that
> > you have all your required references, not that your required
> > references have all been initialized
> >
> > Sent from my [rhymes with tryPod] ;-)
> >
> > On 8 Feb 2010, at 20:28, Jason Russo <jrusso@genscape.com> wrote:
> >
> > > If references are to be injected before PostConstruct is called, as
> > > you
> > > explain (in other words, B happens before C), shouldn't these
> > > references
> > > be initialized already before they are injected?  I should think
> > > this to
> > > be the case when, for example, I want to open a database connection
> > > in a
> > > PostConstruct method using an injected resource.  Even more so in this
> > > case, I would think, since timer service is a component of the ejb
> > > session context, which I would assume should be initialized by the
> > > point
> > > an ejb is constructed.
> > >
> > >
> > >
> > > Jason Russo
> > >
> > > Application Developer
> > >
> > > Genscape– See the Energy
> > >
> > > 445 E. Market St, Suite 200
> > >
> > > Louisville, KY 40202
> > >
> > > Tel: 502-583-2091
> > >
> > > www.genscape.com
> > >
> > >
> > >
> > > On Mon, 2010-02-08 at 14:18 -0500, Stephen Connolly wrote:
> > >
> > >> I have not read the spec, but here is my €0.02 anyway.
> > >>
> > >> when deploying an ejb-jar, there are three states for that jar:
> > >>
> > >> 1. Undeployed
> > >> 2. Transitional
> > >> 3. Deployed
> > >>
> > >> The EJB lifecycle for each EJB starts of as follows:
> > >>
> > >> A. Constructed
> > >> B. Inject references to all @EJB & @Resource objects
> > >> C. Call PostConstruct
> > >>
> > >> Due to circular references, it may not be possible to guarantee
> > >> that when
> > >> your @PostConstruct method is invoked, all your references have
> > >> finished
> > >> initialization.
> > >>
> > >> In otherwords, all the C calls take place in state #2 before the
> > >> container
> > >> has finished initialization.  The container contract is only to call
> > >> postconstruct after the injectables have been injected and before
> > >> your
> > >> ejb-jar has entered the deployed state.
> > >>
> > >> So therefore IF I was designing the specification I would mandate
> > >> that the
> > >> @PostConstruct method be used just to finish the bean's internal
> > >> initialization... I would say that calls to any of the injected
> > >> EJBs or
> > >> Resources be either banned, or of an undefined result because we
> > >> cannot
> > >> guarnatee that those injected components have had their
> > >> @PostConstruct
> > >> method called yet... (or else I'd ban circular references between EJB
> > >> components)
> > >>
> > >> So as such I would expect that the TimerService for my ejb-jar
> > >> might not be
> > >> available until after the @PostConstruct has been called...
> > >>
> > >> Others [and possibly even the spec] might disagree with me
> > >>
> > >> -Stephen
> > >>
> > >> On 8 February 2010 17:51, Jason Russo <jrusso@genscape.com> wrote:
> > >>
> > >>> Good afternoon everyone,
> > >>>
> > >>> I have a question about the ejb timer services with the new
> > >>> singleton
> > >>> beans.  What I want to do is create a timer service that starts on
> > >>> openejb startup, so I thought it would be perfect to use the
> > >>> singleton
> > >>> bean for this purpose.  However, when I try to create the timer in
> > >>> the
> > >>> singleton post-construct method, I get this error:
> > >>>
> > >>> java.lang.IllegalStateException: TimerService method not permitted
> > >>> for
> > >>> current operation POST_CONSTRUCT
> > >>>
> > >>> Is this a bug, an incomplete implementation, or by design?  I
> > >>> suppose I
> > >>> can work around by using a servlet context listener, but I figured
> > >>> singleton beans would be cleaner.
> > >>>
> > >>>
> > >>> ---
> > >>> ---
> > >>> ---
> > >>> ---
> > >>> ---
> > >>> ---
> > >>> ---
> > >>> ---
> > >>> ---
> > >>> ---
> > >>> ---
> > >>> --------------------------------------------------------------------
> > >>> Here is my singleton class:
> > >>>
> > >>> @Singleton(name="TimerServiceTest")
> > >>> @Startup
> > >>> public class TimerServiceTestBean implements TimerServiceTestLocal
{
> > >>>   private static Logger _log =
> > >>> Logger.getLogger(TimerServiceTestBean.class);
> > >>>   private volatile static Timer _timer;
> > >>>
> > >>>   @Resource
> > >>>   private TimerService _timerService;
> > >>>
> > >>>   @PostConstruct
> > >>>   public void onStartup() {
> > >>>       _timer = _timerService.createTimer(60000, 60000, null);
> > >>>       _log.info("Starting TimerServiceTestBean timer.");
> > >>>   }
> > >>>
> > >>>   @PreDestroy
> > >>>   public void onShutdown() {
> > >>>       _timer.cancel();
> > >>>       _log.info("Shutting down TimerServiceTestBean timer.");
> > >>>   }
> > >>>
> > >>>   @Timeout
> > >>>   public void onTimeout(Timer timer) {
> > >>>       _log.info("TimeServiceTestBean has just received a timeout
> > >>> notice at "
> > >>>               + (new Date()).toString());
> > >>>   }
> > >>> }
> > >>>
> > >>>
> > >>>
> > >>>
> > >>> Jason Russo
> > >>>
> > >>> Application Developer
> > >>>
> > >>> Genscape– See the Energy
> > >>>
> > >>> 445 E. Market St, Suite 200
> > >>>
> > >>> Louisville, KY 40202
> > >>>
> > >>> Tel: 502-583-2091
> > >>>
> > >>> www.genscape.com
> > >>>
> > >>>
> > >>>
> > >>>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message