views:

185

answers:

1

I'm trying to deploy my application to a locally running GoogleAppEngine development server, but I'm getting the following stack trace when I start the server

Apr 23, 2010 9:03:33 PM com.google.apphosting.utils.jetty.JettyLogger warn
WARNING: Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientDao' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Cannot resolve reference to bean 'entityManagerFactory' while setting bean property 'entityManagerFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/jdo/metadata/ComponentMetadata:
java.lang.ClassNotFoundException: javax.jdo.metadata.ComponentMetadata
        at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:319)
        at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:151)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:264)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:332)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:264)
        at javax.jdo.JDOHelper$18.run(JDOHelper.java:2009)
        at javax.jdo.JDOHelper$18.run(JDOHelper.java:2007)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.jdo.JDOHelper.forName(JDOHelper.java:2006)
        at javax.jdo.JDOHelper.invokeGetPersistenceManagerFactoryOnImplementation(JDOHelper.java:1155)
        at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:803)
        at javax.jdo.JDOHelper.getPersistenceManagerFactory(JDOHelper.java:698)
        at org.datanucleus.jpa.EntityManagerFactoryImpl.initialisePMF(EntityManagerFactoryImpl.java:482)
        at org.datanucleus.jpa.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:255)
        at org.datanucleus.store.appengine.jpa.DatastoreEntityManagerFactory.<init>(DatastoreEntityManagerFactory.java:68)
        at org.datanucleus.store.appengine.jpa.DatastorePersistenceProvider.createContainerEntityManagerFactory(DatastorePersistenceProvider.java:45)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:224)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:291)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:269)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:104)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1245)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
        at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:255)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45)
        at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:530)
        at org.mortbay.jetty.servlet.Context.startContext(Context.java:135)
        at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1218)
        at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:500)
        at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:448)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
        at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:117)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
        at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:117)
        at org.mortbay.jetty.Server.doStart(Server.java:217)
        at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
        at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:181)
        at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:116)
        at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:217)
        at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:162)
        at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
        at com.google.appengine.tools.development.DevAppServerMain.<init>(DevAppServerMain.java:113)
        at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:89)
The server is running at http://localhost:1234/

I'm a little confused over this, since I have the same application running locally on GlassFish/MySQL. All I have done is to swap in the relevant jar files, and change the persistence.xml.

My applicationContext.xml looks as follows :

<context:annotation-config/>
    <bean id="clientDao" class="com.jameselsey.salestracker.dao.jpa.JpaDaoClient">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>


    <bean id="org.springframework.context.annotation.internalPersistenceAnnotationProcessor"
  class="com.jameselsey.salestracker.util.GaeFixInternalPersistenceAnnotationProcessor" />



    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

    <tx:annotation-driven/>

    <bean id="clientService" class="com.jameselsey.salestracker.service.ClientService"/>
</beans>

My JPA DAO looks like this

public class JpaDao extends JpaDaoSupport
{
    protected <T> List<T> findAll(Class<T> clazz)
    {
        return getJpaTemplate().find("select c from " + clazz.getName() + " c");
    }
    protected <T> T findOne(String jpql, Map params)
    {
        List<T> results = getJpaTemplate().findByNamedParams(jpql, params);
        if(results.isEmpty())
        {
            return null;
        }
        if(results.size() > 1)
        {
            throw new IncorrectResultSizeDataAccessException(1, results.size());
        }
        return results.get(0);
    }
}

And an example implemented method looks like this :

@Override
    public Client getClientById(Integer clientId)
    {
        String jpql = "SELECT c " +
                "FROM com.jameselsey.salestracker.domain.Client c " +
                "WHERE c.id = " + clientId;

        return (Client) getJpaTemplate().find(jpql).get(0);
    }

Like I say, this works ok on Glassfish/MySQL, is it possible this error could be a red herring to something else?

+1  A: 

My first guess would be that the App Engine SDK doesn't allow this class to be used for some reason. I don't know much about JPA, but ClassNotFoundException in App Engine typically means it's been blacklisted.

Jason Hall