AppEngine Jersey Junit tests not working (api not registered for this thread)
===

I'm having a really hard time getting Jersey, AppEngine and JUnit to work. Current error is following:

**No API environment is registered for this thread.**

I'm doing following:

* Loading the helper.setUp() (LocalDataStoreService) over JUnit @Before annotation

* Creating an instance of the Grizzly Webserver over the JUnit @Before annotation

* Executing the testCreateCard test

* Stopping the Grizzly Webserver

* Running the helper.tearDown() method over JUnit @After annotation

I launch (Run as) Junit Test with Eclipse Indigo (I include the jars over the Java BuildPath).

It seems like Jersey or the Grizzly Webcontainer is opening new threads which doesn't work with the local datastore methods helper.setUp() and helper.tearDown().

I have found a few questions/answers but not related to using AppEngine with Jersey.

Is there anyone that can help? Is a setup with Jersey and AppEngine and JUnit actually possible? I tried several possibilities with rest-assured and jersey-test-framework but all tries ended up in errors and debugging and also a post in to the AppEngine Mailinglist without any results.

My last hope is my current setup with:

* Grizzly 2.1 (provided by Jersey)

* Jersey 1.12

* JUnit 4.10

Stacktrace is following:

    java.lang.NullPointerException: No API environment is registered for this thread.
    	at  com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppId(DatastoreApiHelper.java:86)
	at     com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppIdNamespace(DatastoreApiHelper.java:96)
	at com.google.appengine.api.datastore.Key.<init>(Key.java:106)
	at com.google.appengine.api.datastore.Key.<init>(Key.java:90)
	at com.google.appengine.api.datastore.Key.<init>(Key.java:86)
	at com.google.appengine.api.datastore.Entity.<init>(Entity.java:125)
	at com.google.appengine.api.datastore.Entity.<init>(Entity.java:106)
	at org.datanucleus.store.appengine.DatastoreFieldManager.<init>(DatastoreFieldManager.java:189)
	at  org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPreProcess(DatastorePersistenceHandler.java:354)
	at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(DatastorePersistenceHandler.java:267)
	at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:256)
	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.acolsolutions.loyaltycard.dataobjects.CardDAO.create(CardDAO.java:23)
	at com.acolsolutions.loyaltycard.resources.CardResource.create(CardResource.java:32)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
	at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205)
	at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
	at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
	at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
	at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
	at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1483)
	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1414)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1363)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1353)
	at com.sun.jersey.server.impl.container.grizzly2.GrizzlyContainer._service(GrizzlyContainer.java:215)
	at com.sun.jersey.server.impl.container.grizzly2.GrizzlyContainer.service(GrizzlyContainer.java:185)
	at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:163)
	at org.glassfish.grizzly.http.server.HttpHandlerChain.service(HttpHandlerChain.java:207)
	at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:163)
	at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:164)
	at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:265)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:134)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
	at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:78)
	at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:816)
	at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:111)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:566)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:546)
	at java.lang.Thread.run(Unknown Source)


My Jersey Test class looks following:

    import java.io.IOException;
    import java.net.URI;
    import java.util.HashMap;
    import java.util.Map;

    import javax.ws.rs.core.UriBuilder;

    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;

    import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
    import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

    import org.glassfish.grizzly.http.server.HttpServer;

    import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory;
    import com.sun.jersey.api.core.PackagesResourceConfig;
    import com.sun.jersey.api.core.ResourceConfig;
    import com.sun.jersey.api.client.WebResource;
    import com.sun.jersey.api.client.Client;

    import org.codehaus.jettison.json.JSONObject;

    public class CardResourceTests {
	private final LocalServiceTestHelper helper = new LocalServiceTestHelper(
			new LocalDatastoreServiceTestConfig());	
	
	private HttpServer httpServer;
	private URI uri;

	@Before
	public void setUp() throws Exception {
		helper.setUp();
		
		uri = UriBuilder.fromUri("http://localhost/").port(9998).build();
		ResourceConfig rc = new PackagesResourceConfig("com.acolsolutions.loyaltycard.resources");
		httpServer = GrizzlyServerFactory.createHttpServer(uri, rc);
	}
	
	@After
	public void tearDown() throws Exception {
		helper.tearDown();
		
		httpServer.stop();
	}
	
	@Test
	public void testCreate() {
		boolean thrown = false;
		Client client = Client.create();
		WebResource webResource = client.resource(uri);
        JSONObject card = new JSONObject();

		try {
        	card.put("id", "1")
    		.put("name", "Name of Card")
    		.put("code", "123456")
    		.put("codeTypeId", "1")
    		.put("cardProviderName", "The Card Provider")
    		.put("picturePath", "provider.jpg")
    		.put("cardProviderUrl", "http://www.provider.com")
    		.put("creationDate", "Sun Jun 10 08:55:14 UTC 2012")
    		.put("modificationDate","Sun Jun 10 08:55:14 UTC 2012");
    	webResource.path("cards").type("application/json").post(card);
		} catch(Exception e) {
        	e.printStackTrace();
        	thrown = true;			
		}
		
		assertEquals("Result", false, thrown);
	}
    }