gpt4 book ai didi

java - 对象化和 TimerTask : No API environment is registered for this thread

转载 作者:搜寻专家 更新时间:2023-10-31 19:56:19 24 4
gpt4 key购买 nike

我正在尝试设置一个 TimerTask 以定期从 Google App Engine 的数据存储中删除条目。所以我设置了一个带有 TimerServletContextListener

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); 但它似乎没有帮助。

最佳答案

来自documentation of java.util.Timer class :

Corresponding to each Timer object is a single background thread.

peeking to the inner code of the java.util.Timer class ,我们可以看到它基本上是通过调用 new Thread() 来实例化线程。

与此同时,来自 App Engine's documentation关于在他们的 Java 沙箱中使用线程:

You must use one of the methods on ThreadManager to create your threads. You cannot invoke new Thread() yourself or use the default thread factory.

所以这里发生的是 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();

关于java - 对象化和 TimerTask : No API environment is registered for this thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15976406/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com