openejb-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jason Russo <jru...@genscape.com>
Subject Re: Singleton + Timer service
Date Tue, 09 Feb 2010 16:23:35 GMT
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
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. 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)?  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