ChuckW
ChuckW

Reputation: 11

Transitioning from Objectify v5 to v6 ObjectifyService.init() throws NoClassDefFoundError

I'm transitioning a working google-appengine project from objectify v5 to v6, which uses the new Google Cloud datastore endpoints. In my listener-class EntityRegistrar class I call ObjectifyService.init() which throws a NoClassDefFoudError. Maven dependencies for objectify v6.0.4 and guava v18 look OK and the project compiles OK in Eclipse using Java8, but I must be missing something.

I get the same error when trying to run on the local google cloud beta datastore emulator.

Any hints would be appreciated.

package org.chemvantage;

import java.util.Date;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import com.googlecode.objectify.ObjectifyService;

public class EntityRegistrar implements ServletContextListener {

     public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("Starting up: " + new Date());

        ObjectifyService.init();   // line 15

        ObjectifyService.register(Assignment.class);
        ObjectifyService.register(BLTIConsumer.class);
    }
}

Uncaught exception from servlet

java.lang.NoClassDefFoundError: com/googlecode/objectify/ObjectifyService at org.chemvantage.EntityRegistrar.contextInitialized(EntityRegistrar.java:15) at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:843) at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:533) at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:816) at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:345) at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1406) at com.google.apphosting.runtime.jetty9.AppEngineWebAppContext.startWebapp(AppEngineWebAppContext.java:175) at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1368) at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:778) at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262) at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:522) at com.google.apphosting.runtime.jetty9.AppEngineWebAppContext.doStart(AppEngineWebAppContext.java:120) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at com.google.apphosting.runtime.jetty9.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:240) at com.google.apphosting.runtime.jetty9.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:178) at com.google.apphosting.runtime.jetty9.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:120) at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchServletRequest(JavaRuntime.java:722) at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchRequest(JavaRuntime.java:685) at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:655) at com.google.apphosting.runtime.JavaRuntime$NullSandboxRequestRunnable.run(JavaRuntime.java:847) at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:270) at java.lang.Thread.run(Thread.java:748)

Upvotes: 0

Views: 450

Answers (1)

ChuckW
ChuckW

Reputation: 11

OK, thanks to anyone who was scratching their head over this on my behalf. I think I found the answer:

In order to deal with asynchronous datastore operations (especially ofy().sa ve() operations that are left in the background), one must include the following Java class, which extends ObjectifyFilter.

package org.chemvantage;

import javax.servlet.annotation.WebFilter;

import com.googlecode.objectify.ObjectifyFilter;

/**
 * Filter required by Objectify to clean up any thread-local transaction contexts and pending
 * asynchronous operations that remain at the end of a request.
 */
@WebFilter(urlPatterns = {"/*"})
public class ObjectifyWebFilter extends ObjectifyFilter {}

This is addition to the required definition of the ObjectifyFilter in your web.xml file.

<web-app>
  <filter>
    <filter-name>ObjectifyFilter</filter-name>
    <filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>ObjectifyFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

You need both, although it seems counterintuitive. I checked it by deleting one and then replacing it and deleting the other. It would be helpful to put this into the Objectify instructions for upgrading from v5 to v6.

Upvotes: 1

Related Questions