Cha*_*Tan 5 java google-app-engine scheduled-tasks objectify servletcontextlistener
我正在尝试TimerTask定期从Google App Engine的dataStore中删除条目.所以我建立了ServletContextListener一个Timer.
在里面contextInitialized,我已经注册了我的Objectify课程:
ObjectifyService.register(Person.class);
Run Code Online (Sandbox Code Playgroud)
但是,当任务实际运行时,它会抱怨没有设置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)
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?我已经尝试更改注册该类的行,ObjectifyService.factory().register(Person.class);但它似乎没有帮助.
对应于每个Timer对象的是一个后台线程.
并且窥视java.util.Timer类的内部代码,我们可以看到它基本上通过调用实例化线程new Thread().
同时,从App Engine关于在Java沙箱中使用线程的文档:
您必须使用ThreadManager上的某个方法来创建线程.您不能自己调用新的Thread()或使用默认的线程工厂.
所以这里发生的事情是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 );
Run Code Online (Sandbox Code Playgroud)
你可以改用:
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();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2111 次 |
| 最近记录: |