Hi Daniel,
The EJB specification doesn't allow timer service operations in the
constructor. Try moving this into one of your business methods.
Thanks,
--Mahesh
Daniel Cavalcanti wrote:
> Hi Masesh,
>
> I found out what the problem was, but I still can't figure out how to
> solve.
> I forgot to copy a part of the code into what I had sent. Notice that
> I have a method to execute on a timeout callback.
> I declare a variable like this:
>
> @Resource()
> private TimerService timerService;
>
> which I use to create a timer. Whenever I leave the timer related code
> in, I get these errors. If I take that part out, which I had done to
> post the message and that's why I forgot to copy in again, then all
> works fine. So it seems that I'm doing something wrong with the timer.
>
> Have you used them before?
> Here is the code with the timer parts in:
>
> package com.localmatters.flexitext.ejb;
>
> import com.localmatters.flexitext.support.HistoryTable;
> import com.localmatters.flexitext.support.UserHistory ;
> import java.sql.Date;
> import java.util.Set;
> import javax.annotation.PostConstruct;
> import javax.annotation.Resource;
> import javax.ejb.Stateless;
> import javax.ejb.Timeout;
> import javax.ejb.Timer;
> import javax.ejb.TimerService;
> import javax.jws.WebMethod;
> import javax.jws.WebParam;
> import javax.jws.WebService;
>
> /**
> * The history WS-EJB. The actual history is managed by
> * {_at_link HistoryTable HistoryTable}, so all operations are delegated
> to it.
> *
> * @author Daniel Cavalcanti
> */
> @Stateless()
> @WebService()
> public class HistoryBean implements HistoryRemote, HistoryLocal {
>
> //
> **********************************************************************
> // Instance variables
> //
> **********************************************************************
>
> /**
> * All users' history.
> */
> private HistoryTable historyTable;
>
> /**
> * The timer service.
> */
> @Resource()
> private TimerService timerService;
>
> //
> **********************************************************************
> // Constructors
> //
> **********************************************************************
>
> /**
> * Creates a new instance of HistoryBean.
> */
> public HistoryBean() {
> // create history-table
> historyTable = historyTable.getInstance();
>
> // create timer for clean-up notifications
> timerService.createTimer(new Date(System.currentTimeMillis()),
> 5 * 60 * 1000, null);
> }
>
> //
> **********************************************************************
> // Bean life-cycle methods
> //
> **********************************************************************
>
> /**
> * Gets reference to history table resource.
> */
> @PostConstruct()
> public void postConstruct() {
>
> // create history-table
> historyTable = historyTable.getInstance ();
>
> }
>
> /**
> * Periodic clean up method
> */
> @Timeout()
> public void clean(Timer timer) {
> // TODO clean users temporary history
> System.out.println ("current time: " + new
> Date(System.currentTimeMillis()));
> }
>
> //
> **********************************************************************
> // Bean methods
> //
> **********************************************************************
>
> @WebMethod()
> public Set<String> users() {
> return historyTable.users();
> }
>
> @WebMethod()
> public void clear() {
> historyTable.clear();
> }
>
> @WebMethod()
> public void clearOld(@WebParam() int age) {
> historyTable.clear(age);
> }
>
> @WebMethod()
> public void create(@WebParam() String user)
> throws NullPointerException {
> historyTable.create(user);
> }
>
> @WebMethod()
> public UserHistory get(@WebParam() String user)
> throws NullPointerException {
> return historyTable.get(user);
> }
>
> @WebMethod()
> public UserHistory remove(@WebParam() String user)
> throws NullPointerException {
> return historyTable.remove(user);
> }
>
> }
>
> An part of the exception due to this code:
>
> [#|2006-08-04T14:39:47.350-0400|INFO|sun-appserver-pe9.0|javax.enterprise.system.container.ejb|_ThreadID=16;_ThreadName=httpWorkerThread-8080-1;|EJB5070:
> Exception creating stateless session bean : [{0}]
> java.lang.IllegalStateException : EJB Timer method calls cannot be
> called in this context
> at
> com.sun.ejb.containers.SessionContextImpl.checkTimerServiceMethodAccess(SessionContextImpl.java:324)
> at
> com.sun.ejb.containers.EJBTimerServiceWrapper.checkCallPermission
> (EJBTimerServiceWrapper.java:237)
> at
> com.sun.ejb.containers.EJBTimerServiceWrapper.checkCreateTimerCallPermission(EJBTimerServiceWrapper.java:227)
> at com.sun.ejb.containers.EJBTimerServiceWrapper.createTimer
> (EJBTimerServiceWrapper.java:160)
> at
> com.localmatters.flexitext.ejb.HistoryBean.postConstruct(HistoryBean.java:68)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke
> (NativeMethodAccessorImpl.java:39)
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:585)
> at
> com.sun.ejb.containers.interceptors.BeanCallbackInterceptor$1.run
> (InterceptorManager.java:601)
> at java.security.AccessController.doPrivileged(Native Method)
> at
> com.sun.ejb.containers.interceptors.BeanCallbackInterceptor.intercept(InterceptorManager.java:595)
> at
> com.sun.ejb.containers.interceptors.CallbackChainImpl.invokeNext
> (InterceptorManager.java:448)
> at
> com.sun.ejb.containers.interceptors.InterceptorManager.intercept(InterceptorManager.java:204)
> at
> com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java
> :546)
> at
> com.sun.ejb.containers.StatelessSessionContainer.access$100(StatelessSessionContainer.java:96)
> at
> com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java
> :746)
> at
> com.sun.ejb.containers.util.pool.NonBlockingPool.getObject(NonBlockingPool.java:186)
> at
> com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:469)
> at com.sun.ejb.containers.BaseContainer.getContext
> (BaseContainer.java:1566)
> at
> com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1148)
> at
> com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:182)
>
> at
> com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:71)
> at $Proxy83.get(Unknown Source)
> at com.localmatters.flexitext.servlet.StoreServlet.processRequest
> (StoreServlet.java:44)
> at
> com.localmatters.flexitext.servlet.StoreServlet.doGet(StoreServlet.java:77)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
> at javax.servlet.http.HttpServlet.service (HttpServlet.java:820)
> at
> org.apache.catalina.core.ApplicationFilterChain.servletService(ApplicationFilterChain.java:397)
> at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:278)
>
> at
> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)
> at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)
> at org.apache.catalina.core.StandardContextValve.invokeInternal
> (StandardContextValve.java:240)
> at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:179)
> at
> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)
> at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:73)
> at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:182)
> at
> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java
> :566)
> at
> com.sun.enterprise.web.VirtualServerPipeline.invoke(VirtualServerPipeline.java:120)
> at
> org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:939)
> at org.apache.catalina.core.StandardEngineValve.invoke
> (StandardEngineValve.java:137)
> at
> org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:566)
> at
> org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:536)
> at org.apache.catalina.core.ContainerBase.invoke
> (ContainerBase.java:939)
> at
> org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:231)
> at
> com.sun.enterprise.web.connector.grizzly.ProcessorTask.invokeAdapter(ProcessorTask.java:667)
> at
> com.sun.enterprise.web.connector.grizzly.ProcessorTask.processNonBlocked
> (ProcessorTask.java:574)
> at
> com.sun.enterprise.web.connector.grizzly.ProcessorTask.process(ProcessorTask.java:844)
> at
> com.sun.enterprise.web.connector.grizzly.ReadTask.executeProcessorTask(ReadTask.java:287)
>
> at
> com.sun.enterprise.web.connector.grizzly.ReadTask.doTask(ReadTask.java:212)
> at
> com.sun.enterprise.web.connector.grizzly.TaskBase.run(TaskBase.java:252)
> at com.sun.enterprise.web.connector.grizzly.WorkerThread.run
> (WorkerThread.java:75)
> |#]
>
> [#|2006-08-04T14:39:47.353-0400|INFO|sun-appserver-pe9.0|javax.enterprise.system.container.ejb|_ThreadID=16;_ThreadName=httpWorkerThread-8080-1;HistoryBean;|EJB5018:
> An exception was thrown during an ejb invocation on [HistoryBean]|#]
>
>
>
>
> On 8/4/06, *Mahesh.Kannan* <Mahesh.Kannan_at_sun.com
> <mailto:Mahesh.Kannan_at_sun.com>> wrote:
>
> Well I tried a similar exampe and it worked!! The only (minor)
> difference is that the static Singleton is initialized during class
> loading time in my example. The client created multiple threads and
> called the sleepFor() method in Sless.
>
> I am sure you might have already checked, but Can you print the
> hashcode
> of the singleton and check if you get different instances?
>
>
> --Mahesh
>
> Daniel Cavalcanti wrote:
>
> > Hello,
> >
> > I have a stateless, session bean. All client code uses this bean to
> > place some entries in a history object (just a POJO to store some
> > history information).
> > I know that a statefull, session bean wouldn't solve the problem
> > because users will access this across sessions...
> > I implement this history object as a singleton, but every time a new
> > bean is created, it seems to get a new history object:
> > Does someone know what going on? I can attach the project if
> necessary.
> >
> > thanks,
> > Daniel.
> >
> >
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> >
> > package com.localmatters.flexitext.ejb;
> >
> > import com.localmatters.flexitext.support.HistoryTable;
> > import com.localmatters.flexitext.support.UserHistory;
> > import java.sql.Date;
> > import java.util.Set;
> > import javax.annotation.PostConstruct;
> > import javax.annotation.Resource;
> > import javax.ejb.Stateless;
> > import javax.ejb.Timeout;
> > import javax.ejb.Timer;
> > import javax.jws.WebMethod;
> > import javax.jws.WebParam;
> > import javax.jws.WebService;
> >
> > /**
> > * The history WS-EJB. The actual history is managed by
> > * {_at_link HistoryTable HistoryTable}, so all operations are
> delegated
> > to it.
> > *
> > * @author Daniel Cavalcanti
> > */
> > @Stateless()
> > @WebService()
> > public class HistoryBean implements HistoryRemote, HistoryLocal {
> >
> > //
> >
> **********************************************************************
>
> > // Instance variables
> > //
> >
> **********************************************************************
> >
> > /**
> > * All users' history.
> > */
> > private HistoryTable historyTable;
> >
> > //
> >
> **********************************************************************
> > // Constructors
> > //
> >
> **********************************************************************
>
> >
> > /**
> > * Creates a new instance of HistoryBean.
> > */
> > public HistoryBean() {
> > }
> >
> > //
> >
> **********************************************************************
>
> > // Bean life-cycle methods
> > //
> >
> **********************************************************************
> >
> > /**
> > * Gets reference to history table resource.
> > */
> > @PostConstruct()
> > public void postConstruct() {
> > historyTable = historyTable.getInstance();
> > }
> >
> > /**
> > * Periodic clean up method
> > */
> > @Timeout()
> > public void clean(Timer timer) {
> > // TODO clean users temporary history
> > System.out.println("current time: " + new
> > Date(System.currentTimeMillis ()));
> > }
> >
> > //
> >
> **********************************************************************
> > // Bean methods
> > //
> >
> **********************************************************************
>
> >
> > @WebMethod()
> > public Set<String> users() {
> > return historyTable.users();
> > }
> >
> > @WebMethod()
> > public void clear() {
> > historyTable.clear();
> > }
> >
> > @WebMethod()
> > public void clearOld(@WebParam() int age) {
> > historyTable.clear(age);
> > }
> >
> > @WebMethod()
> > public void create(@WebParam() String user)
> > throws NullPointerException {
> > historyTable.create(user);
> > }
> >
> > @WebMethod()
> > public UserHistory get(@WebParam() String user)
> > throws NullPointerException {
> > return historyTable.get(user);
> > }
> >
> > @WebMethod()
> > public UserHistory remove(@WebParam() String user)
> > throws NullPointerException {
> > return historyTable.remove(user);
> > }
> >
> > }
> >
> >
> -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> >
> >
> > package com.localmatters.flexitext.support;
> >
> > import java.io.Serializable;
> > import java.util.Collections;
> > import java.util.Map;
> > import java.util.Set;
> > import java.util.TreeMap;
> > import java.util.TreeSet ;
> >
> > /**
> > * All users' history. This class is a thread-safe singleton.
> > *
> > * @author Daniel Cavalcanti
> > */
> > public class HistoryTable implements Serializable {
> >
> > //
> >
> **********************************************************************
> > // Singleton variable
> > //
> >
> **********************************************************************
>
> >
> > /**
> > * The users' history singleton instance.
> > */
> > private static HistoryTable singleton;
> >
> > //
> >
> **********************************************************************
>
> > // Instance variables
> > //
> >
> **********************************************************************
> >
> > /**
> > * The users' history.
> > */
> > private Map<String, UserHistory> history;
> >
> > //
> >
> **********************************************************************
> > // Constructor
> > //
> >
> **********************************************************************
>
> >
> > /**
> > * Creates a new instance of HistoryTable.
> > */
> > private HistoryTable() {
> > history = Collections.synchronizedMap(new TreeMap<String,
> > UserHistory>());
> > }
> >
> > /**
> > * Returns the the users' history instance.
> > * HistoryTable factory method.
> > *
> > * @return The the users' history instance.
> > */
> > public static HistoryTable getInstance() {
> > synchronized (HistoryTable.class) {
> > if (singleton == null)
> > singleton = new HistoryTable();
> > return singleton;
> > }
> > }
> >
> > //
> >
> **********************************************************************
> > // History table methods
> > //
> >
> **********************************************************************
>
> >
> > /**
> > * Returns a copy of the users set.
> > *
> > * @return A copy of the users set.
> > */
> > public Set<String> users() {
> > return new TreeSet( history.keySet());
> > }
> >
> > /**
> > * Clears the history table. This methods removes all user to
> > user-history
> > * entries.
> > */
> > public void clear() {
> >
> > synchronized (history) {
> > for (UserHistory userHistory : history.values())
> > userHistory.clear();
> >
> > history.clear();
> > }
> >
> > }
> >
> > /**
> > * Clears the history older than age milliseconds. The user to
> > user-history
> > * entry is maintained. Only the actual history entries that are
> > old are
> > * removed.
> > *
> > * @param age The age threshold in milliseconds.
> > */
> > public void clear(int age) {
> >
> > long threshold = System.currentTimeMillis () - age;
> >
> > synchronized (history) {
> > for (UserHistory userHistory : history.values()) {
> > userHistory.clear(threshold);
> > }
> > }
> >
> > }
> >
> > /**
> > * Create a history entry for a user.
> > *
> > * @param user The user.
> > * @throws java.lang.NullPointerException see {_at_link
> > UserHistory#UserHistory() UserHistory}.
> > * @see UserHistory#UserHistory()
> > */
> > public void create(String user)
> > throws NullPointerException {
> > history.put(user, new UserHistory());
> > }
> >
> > /**
> > * Returns the user's history. If user does not have a history,
> > compulsively
> > * create one.
> > *
> > * @param user The user.
> > * @throws java.lang.NullPointerException If user is null.
> > * @return The user history.
> > */
> > public UserHistory get(String user)
> > throws NullPointerException {
> >
> > // attempt to get user's history
> > UserHistory entry = history.get(user);
> >
> > // user does not have history -- create one
> > if (entry == null)
> > create(user);
> >
> > // return user's history
> > return entry;
> >
> > }
> >
> > /**
> > * Removes a uer's history.
> > *
> > * @param user The user.
> > * @throws java.lang.NullPointerException If user is null.
> > * @return The user's history if it exists, null otherwise.
> > */
> > public UserHistory remove(String user)
> > throws NullPointerException {
> > return history.remove(user);
> > }
> >
> > }
> >
>
>
> /*
> * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
> * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
> */
> package com.sun.s1asdev.ejb.ejb30.hello.session;
>
> import javax.ejb.Remote;
>
> @Remote
> public interface Sless
> {
> public String hello();
>
> public String sleepFor(int sec);
> }
>
>
> /*
> * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
> * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
> */
> package com.sun.s1asdev.ejb.ejb30.hello.session;
>
> import javax.ejb.Stateless;
> import javax.annotation.PostConstruct;
>
> @Stateless
> public class SlessEJB implements Sless
> {
> private Singleton singleton;
>
> @PostConstruct
> public void init() {
> singleton = Singleton.getInstance();
> System.out.println("Singleton: " + singleton);
> }
>
> public String hello() {
> System.out.println("In SlessEJB:hello()");
> return "hello";
> }
>
> public String sleepFor(int sec) {
> try {
> Thread.currentThread().sleep(sec*1000);
> } catch (Exception ex) {
> }
>
> return "sless: " + this + " => " + singleton;
> }
> }
>
>
> package com.sun.s1asdev.ejb.ejb30.hello.session ;
>
> public class Singleton {
> private static Singleton _singleton = new Singleton();
>
> private Singleton() {
> }
>
> public static Singleton getInstance() {
> return _singleton;
> }
> }
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ejb-unsubscribe_at_glassfish.dev.java.net
> <mailto:ejb-unsubscribe_at_glassfish.dev.java.net>
> For additional commands, e-mail: ejb-help_at_glassfish.dev.java.net
> <mailto:ejb-help_at_glassfish.dev.java.net>
>
>