maxieduncan
Showing posts with label googleappengine. Show all posts
Showing posts with label googleappengine. Show all posts

Friday, 21 May 2010

Grails 1.3.1 and AppEngine causing java.lang.NoClassDefFoundError: for hibernate classes

I recently upgraded to grails 1.3.1 and suddenly got java.lang.NoClassDefFoundError: org/hibernate/MappingException errors when trying to start up my stack locally using grails run-app. It seems that GrailsDomainConfigurationUtil includes this class in it's interface but the hibernate jar isn't being copied into the lib directory. To fix this I copied $GRAILS_HOME/lib/hibernate-core-3.3.1.GA.jar into my projects web-app/WEB-INF/lib directory manually.

I was seeing similar exceptions when I deployed to appengine which the above also resolved.

AppEngine example

org.springframework.beans.factory.access.BootstrapException: Error executing bootstraps; nested exception is java.lang.NoClassDefFoundError: org/hibernate/mapping/SimpleValue

Local development stack trace


[java] INFO: [1274476930651000] javax.servlet.ServletContext log: Initializing Spring root WebApplicationContext
[java] 2010-05-21 21:22:19,825 [Thread-1] ERROR context.ContextLoader  - Context initialization failed
[java] org.springframework.beans.factory.access.BootstrapException: Error executing bootstraps; nested exception is java.lang.NoClassDefFoundError: org/hibernate/MappingException
[java] May 21, 2010 9:22:19 PM com.google.apphosting.utils.jetty.JettyLogger warn
[java] WARNING: Failed startup of context com.google.apphosting.utils.jetty.DevAppEngineWebAppContext@4e0456{/,/Users/maxieduncan/Documents/workspace/maxieduncan/web-app}
[java] org.springframework.beans.factory.access.BootstrapException: Error executing bootstraps; nested exception is java.lang.NoClassDefFoundError: org/hibernate/MappingException
[java] at org.codehaus.groovy.grails.web.context.GrailsContextLoader.createWebApplicationContext(GrailsContextLoader.java:83)
[java] at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
[java] at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
[java] at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
[java] at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
[java] at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
[java] at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
[java] at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
[java] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[java] at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[java] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[java] at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[java] at org.mortbay.jetty.Server.doStart(Server.java:224)
[java] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[java] at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:185)
[java] at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:146)
[java] at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:222)
[java] at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:171)
[java] at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
[java] at com.google.appengine.tools.development.DevAppServerMain.(DevAppServerMain.java:120)
[java] at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:96)
[java] Caused by: java.lang.NoClassDefFoundError: org/hibernate/MappingException
[java] at org.codehaus.groovy.grails.commons.GrailsDomainConfigurationUtil.evaluateConstraints(GrailsDomainConfigurationUtil.java:358)
[java] at org.codehaus.groovy.grails.commons.GrailsDomainConfigurationUtil.evaluateConstraints(GrailsDomainConfigurationUtil.java:426)
[java] at org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass.refreshConstraints(DefaultGrailsDomainClass.java:747)
[java] at org.codehaus.groovy.grails.commons.DefaultGrailsApplication.refreshConstraints(DefaultGrailsApplication.java:468)
[java] at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.configure(GrailsRuntimeConfigurator.java:181)
[java] at org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator.configure(GrailsRuntimeConfigurator.java:129)
[java] at org.codehaus.groovy.grails.web.context.GrailsConfigUtils.configureWebApplicationContext(GrailsConfigUtils.java:114)
[java] at org.codehaus.groovy.grails.web.context.GrailsContextLoader.createWebApplicationContext(GrailsContextLoader.java:70)
[java] ... 20 more

Saturday, 10 April 2010

JDO Enhancer for Google App Engine with Grails

I had a slightly annoying problem where I'm developing an application using Grails and the Google App Engine but kept getting JDO errors saying "Perhaps you need to run the enhancer on this class?".

The only solution to this if using grails appears to be run the ant task that google supply to enhance the classes; but this isn't initially obvious.

A bit of googling and the solution came up as being that if using Eclipse you needed to have the Google Plugin for Eclipse installed. This itself wasn't entirely helpful as the plugin was installed so why wasn't it working? Well since I'm using the grails app-engine plugin the project had been created outside Eclipse and wasn't linked to the plugin. Right clicking on the project and going:

Google -> App Engine Settings and selecting Use Google App Engine

Resulted in the output DataNucleus Enhancer starting to run.

DataNucleus Enhancer (version 1.1.4) : Enhancement of classes
DataNucleus Enhancer completed with success for 0 classes. Timings : input=43 ms, enhance=0 ms, total=43 ms. Consult the log for full details
DataNucleus Enhancer completed and no classes were enhanced. Consult the log for full details

So now that it was running why weren't any of the classes being enhanced? Well it seemed likely that this is due to the groovy files not being picked up by the google plugin and indeed there's a defect raised on googleappengine for the plugin not working on anything other than .java files.

Fortunately google provide another method in the ant task; not surprising it turns out that the Grails app-engine plugin makes use of this when you deploy the project. So what does this mean? Basically until the Google plugin picks up other source files than just .java you'll need to make sure that you use the grails app-engine plugin from the command line and not the Google Eclipse plugin.


For reference the exception that kept getting thrown was:

Error 500: javax.jdo.JDOFatalUserException: No meta data for com.maxieduncan.download.DownloadCount. Perhaps you need to run the enhancer on this class? NestedThrowables: org.datanucleus.exceptions.NucleusUserException: No meta data for com.maxieduncan.download.DownloadCount. Perhaps you need to run the enhancer on this class?
Servlet: grails
URI: /grails/software/download.dispatch
Exception Message: No meta data for com.maxieduncan.download.DownloadCount. Perhaps you need to run the enhancer on this class?
Caused by: javax.jdo.JDOFatalUserException: No meta data for com.maxieduncan.download.DownloadCount. Perhaps you need to run the enhancer on this class? NestedThrowables: org.datanucleus.exceptions.NucleusUserException: No meta data for com.maxieduncan.download.DownloadCount. Perhaps you need to run the enhancer on this class?

Using the Google Data APIs Java Client in Google App Engine

Yay, Issue 122 has been fixed and you no longer have to disable the Cookie Handler (as I mentioned before) to use the Goole Data API in the Google App Engine.

If using the grails app-engine plugin make sure you do a clean after you've updated the Data API libs to ensure that the latest versions are deployed.

Google App Engine Virtual File System

One of the limitations of the Google App Engine is that there isn't a file system that you can write to. There is however a project that provides a Virtual File System in Java for those that really need it: GaeVFS.

Sunday, 25 October 2009

Using the Google Data API on the Google App Engine

Disabling the Cookie Handler is no longer required
Issue 122 has been fixed and you no longer have to disable the Cookie Handler (as I mentioned before) to use the Goole Data API in the Google App Engine.

Google Data API on the Google App Engine

Enabling support for the Google Data API on the Google App Engine is really straight forward and is covered by google in their documentation:

Add the following to your appengine-web.xml file:

<system-properties>
  <property name="com.google.gdata.DisableCookieHandler" value="true"/>
<system-properties>

If the following is not included, you may see the following exception:

java.security.AccessControlException: access denied (java.net.NetPermission getCookieHandler)

In my case the exception that I noticed was a java.lang.NoClassDefFoundError: Could not initialize class com.google.gdata.client.http.GoogleGDataRequest but this had been preceded by the java.security.AccessControlException.


Grail AppEngine plugin


As I'm using Grails and the Grail AppEngine plugin things got a little more complicated however. The plugin automatically generates the appengine-web.xml file and their is currently no way specify system properties to be included (there is an Improvement request that would add this support).  


In order to add the system property I had to edit the _Events.groovy file in ~/.grails//projects//plugins/app-engine-0.8.5/scripts/_Events.groovy and manually paste in the change that I required. While this works, an update to the plugin will obviously wipe the changes that I've made and they would have to be applied again.