Ah, I see.
I'll do that,
thanks,
Daniel.
On 8/4/06, Mahesh.Kannan <Mahesh.Kannan_at_sun.com> wrote:
>
> 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>
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: ejb-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: ejb-help_at_glassfish.dev.java.net
>
>