Objectify and TimerTask: API is not registered for this stream

I am trying to configure TimerTaskto periodically delete records from the Google App Engine data store. So I installed ServletContextListenerwith Timer.

Inside, contextInitializedI registered Objectify classes:

ObjectifyService.register(Person.class);

However, when the task is actually running, it complains that the API is not configured:

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)

Any ideas? I tried changing the line that the class registers to ObjectifyService.factory().register(Person.class);, but didn't seem to help.

+5
source share
1 answer

From the class documentationjava.util.Timer :

Matching each Timer object represents one background thread.

java.util.Timer, , , new Thread().

, App Engine Java:

ThreadManager. Thread() factory.

, , Timer , Objectify, , ThreadManager, API App Engine, , .

, 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();
+6

All Articles