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

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

例外:

 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 class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService { 

 public String greetServer(String input) throws IllegalArgumentException { return ""; } @Override public void saveContact(Contacts contacts) { PersistenceManager pm = PMF.get().getPersistenceManager(); pm.makePersistent(contacts); //line:20 pm.close(); } 

}

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

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

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

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

这应该可以解决问题。

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

 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