初始化本地数据存储异常:没有为此线程注册API环境

时间:2011-03-23 12:25:22

标签: java google-app-engine gwt google-cloud-datastore

我想用一些数据初始化我的本地数据存储 常规Java程序(我不想启动开发服务器 并调用服务/ servlet),我得到以下异常

异常:

Exception in thread "main" java.lang.NullPointerException: No API environment is registered for this thread.
    at com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppId(DatastoreApiHelper.java:108)
    at com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppIdNamespace(DatastoreApiHelper.java:118)
    at com.google.appengine.api.datastore.Key.(Key.java:104)
    at com.google.appengine.api.datastore.Key.(Key.java:88)
    at com.google.appengine.api.datastore.Key.(Key.java:84)
    at com.google.appengine.api.datastore.Entity.(Entity.java:122)
    at com.google.appengine.api.datastore.Entity.(Entity.java:103)
    at org.datanucleus.store.appengine.DatastoreFieldManager.(DatastoreFieldManager.java:187)
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPreProcess(DatastorePersistenceHandler.java:338)
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(DatastorePersistenceHandler.java:251)
    at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:240)
    at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManagerImpl.java:3185)
    at org.datanucleus.state.JDOStateManagerImpl.makePersistent(JDOStateManagerImpl.java:3161)
    at org.datanucleus.ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.java:1298)
    at org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java:1175)
    at org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:669)
    at org.datanucleus.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:694)
    at com.stuff.server.GreetingServiceImpl.saveContact(GreetingServiceImpl.java:25)
    at com.stuff.server.TestCase.testServerCallBack(TestCase.java:18)
    at com.stuff.server.TestCase.main(TestCase.java:13)

TestCase.java

public class TestCase {
    static GreetingServiceImpl greetingServiceImpl = new GreetingServiceImpl();

public static void main(String[] args) {
    testServerCallBack();//line9
}

private static void testServerCallBack() {
    Contacts contacts = new Contacts("this is", "awesome");
    greetingServiceImpl.saveContact(contacts);//line:14
}

}

问候..... impl.java

public static void main(String[] args) { testServerCallBack();//line9 } private static void testServerCallBack() { Contacts contacts = new Contacts("this is", "awesome"); greetingServiceImpl.saveContact(contacts);//line:14 }

有办法做到这一点吗?怎么样?

3 个答案:

答案 0 :(得分:7)

Google提供的帮助程序类可以完全按照您的需要运行 - 运行足够的代码来处理数据库,而无需启动整个开发服务器。请参阅http://code.google.com/appengine/docs/java/tools/localunittesting.html

上的setUptearDown方法

答案 1 :(得分:2)

只需将这3个库(除测试版之外)添加到类路径中:

${SDK_ROOT}/lib/impl/appengine-api.jar
${SDK_ROOT}/lib/impl/appengine-api-labs.jar
${SDK_ROOT}/lib/impl/appengine-api-stubs.jar

这应解决问题。

答案 2 :(得分:2)

您必须为当前线程设置测试数据存储区服务。基本上你可以这样做:

private static void testServerCallBack() {
    LocalServiceTestHelper helper =
        new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
    helper.setUp();
    Contacts contacts = new Contacts("this is", "awesome");
    greetingServiceImpl.saveContact(contacts);//line:14
}

这将初始化此方法的数据库服务(仅供测试)。

更好你可以做到:

private final LocalServiceTestHelper helper =
  new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

@Before
public void setUp() {
   helper.setUp();
}

@After
public void tearDown() {
   helper.tearDown();
}

因此,数据库服务将适用于所有测试方法。

请注意,如果您使用不同的线程来访问db,那么您将为每个线程获得一个单独的数据库。这不是你最想要的。我的意思是helper.setUp()为当前线程设置一个新的单独的数据库服务,并且只能从当前线程访问存储在该数据库中的所有数据。

详情请见:http://code.google.com/appengine/docs/java/tools/localunittesting.html