tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Blevins <david.blev...@visi.com>
Subject Re: Singleton + Timer service
Date Thu, 11 Feb 2010 17:35:57 GMT
Thanks, Jason!

There were some changes to the Singleton lifecycle guarantees after we  
had implemented that bean type while the spec was being developed.   
Already on the radar was allowing @PostConstruct execute in a  
transaction.  We'll definitely add this to the road map as well.

-David

On Feb 9, 2010, at 10:38 AM, Jason Russo wrote:

> Looks like the mailling list removed my attachment.  Let me try again.
>
> <ejb3_1_singleton_operations.png>
>
>
>
> 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 Tue, 2010-02-09 at 13:05 -0500, Jason Russo wrote:
>> I found this table in the 3.1 spec document that seems to outline  
>> what is and isn't allowed by a singleton bean.  This is table 3  
>> from section 4.8.6, and it appears to explicitly allow for access  
>> to timer services and several session context methods within the  
>> PostConstruct and PreDestroy methods callbacks.
>>
>> You can download the doc here for further reference:
>>
>> https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_JCP-Site/en_US/-/USD/ViewFilteredProducts-SingleVariationTypeFilter
>>
>>
>>
>>
>>
>>
>> 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 Tue, 2010-02-09 at 11:30 -0500, Stephen Connolly wrote:
>>>
>>> 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
View raw message