Objectify和TimerTask:此线程未注册API环境
我正在尝试进行TimerTask
设置,以定期从Google App
Engine的dataStore中删除条目。所以我设置了ServletContextListener
一个Timer
。
在中contextInitialized
,我注册了我的Objectify类:
ObjectifyService.register(Person.class);
但是,当任务实际运行时,它抱怨没有设置API环境:
Exception in thread "Timer-0" java.lang.NullPointerException: No API environment is registered for this thread. at com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppId(DatastoreApiHelper.java:80)
at com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppIdNamespace(DatastoreApiHelper.java:90)
at com.google.appengine.api.datastore.Query.<init>(Query.java:214)
at com.google.appengine.api.datastore.Query.<init>(Query.java:143)
at com.googlecode.objectify.impl.cmd.QueryImpl.<init>(QueryImpl.java:72)
at com.googlecode.objectify.impl.cmd.LoadTypeImpl.createQuery(LoadTypeImpl.java:50)
at com.googlecode.objectify.impl.cmd.LoadTypeImpl.filter(LoadTypeImpl.java:58)
at myApp.MyServletContextListener$MyTask.run(MyServletContextListener.java:58)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
有任何想法吗?我尝试将注册该类的行更改为,ObjectifyService.factory().register(Person.class);
但似乎没有帮助。
回答:
从类的文档中java.util.Timer
:
与每个Timer对象相对应的是一个后台线程。
而偷看到的内码java.util.Timer
类,我们可以看到,它基本上是通过调用实例的线程new
Thread()。
同时,从App
Engine的文档中了解有关在其Java沙箱中使用线程的信息:
您必须使用ThreadManager上的方法之一来创建线程。
或使用默认的线程工厂。
因此,这里发生的是Timer
对象实例化了自己的线程,然后该线程执行Objectify查询,但是由于在ThreadManager外部实例化的线程没有为它们设置适当的App
Engine API环境,因此它将引发异常。
您需要重构代码以避免使用Timer和TimerTask类,而应使用基本线程。例如,代替使用:
import java.util.Timer;import java.util.TimerTask;
...
Timer timer = new Timer();
timer.schedule( new TimerTask()
{
@Override
public void run()
{
// Objectify query here.
}
}, 5000 );
您可以改用:
import com.google.appengine.api.ThreadManager;...
final long tScheduleDelay = 5000;
ThreadManager.createThreadForCurrentRequest( new Runnable()
{
@Override
public void run()
{
try
{
Thread.sleep( tScheduleDelay );
}
catch ( InterruptedException ex )
{
// log possible exception
}
// Objectify query here.
}
} ).start();
以上是 Objectify和TimerTask:此线程未注册API环境 的全部内容, 来源链接: utcz.com/qa/411864.html