Posts Tagged Google

Google AppEngine and Grails 1.2-M2

I upgraded this morning, figuring that the changes related to the .gsp views and their pre-compiling would reduce the cold start issues I’m having with Google AppEngine.

However the 1.2-M2 release of Grails, doesn’t fly on Google AppEngine right now. As far as I can see on the mailing list others have had this issue as well.

The problem I’m experiencing is that the LogManager cannot instantiate.

Context initialization failed
org.springframework.beans.factory.access.BootstrapException: Error executing bootstraps; nested exception is org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.NoClassDefFoundError: java.util.logging.LogManager is a restricted class. Please see the Google App Engine developer's guide for more details.
	at org.codehaus.groovy.grails.web.context.GrailsContextLoader.createWebApplicationContext(GrailsContextLoader.java:74)
	at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
	at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
	at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:530)

And

Context initialization failed
org.springframework.beans.factory.access.BootstrapException: Error executing bootstraps; nested exception is org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.NoClassDefFoundError: Could not initialize class com.google.apphosting.runtime.security.shared.stub.java.util.logging.LogManager

Update: Chad has created a JIRA for this issue located here:http://jira.codehaus.org/browse/GRAILSPLUGINS-1546

Also here is a link to the discussion on the Grails thread:

http://www.nabble.com/java.util.logging.LogManager-is-a-restricted-class.-Please-see-the–Google-App-Engine-developer%27s-guide-for-more-details.-td25453128.html

, ,

4 Comments

Finding entities with GORM-JPA

I’ve been having this issue for a while. Putting it off, but now I had to get my hands dirty. The findBy… methods weren’t returning any objects even though there were data fitting the specified values.

So tonight I finally took the time to take a look at it. My theory was that I could figure out what was wrong by reading the code in JpaPluginSupport.groovy, located in the GORM-JPA plugin.

Now I didn’t find out why its not working. It even looks like its not supported, but I can’t say for sure. What I did however, was find a workaround.

Instead of doing

User.findByEmail(newSaga.email)

I do

User.findWhere(email: newSaga.email)

Using the findWhere method I get results. This is the workaround I’ll go for for now.

, ,

1 Comment

Sending mail on Google appengine with Grails

Sending emails with Google AppEngine is quite straight forward once you get a hang of things. I ran into some issues, for example I never got the high level api’s to work. The code executed but the emails were never received. Instead I went for Google AppEngines own “low level” api, it worked much better.

What I did is that I set up a really simple MailService, similar to that which is installed with the Mail plug in. However, I do not handle templates instead I just send strings with the mail message.

package mail

import com.google.appengine.api.mail.MailService
import com.google.appengine.api.mail.MailService.Message
import com.google.appengine.api.mail.MailServiceFactory
import javax.mail.MessagingException
import javax.mail.internet.AddressException

class MailService {

 boolean transactional = true

 def sendMail(subject, msgBody, too) {

 try {
 def service = MailServiceFactory.getMailService();

 def msg = new com.google.appengine.api.mail.MailService.Message();
 msg.setSender("xxx");
 msg.setTo(too);
 msg.setSubject(subject);
 msg.setHtmlBody(msgBody);
 service.send(msg);

 } catch (AddressException e) {
 // ...
 } catch (MessagingException e) {
 // ...
 }

 }
}

As you can see it is quite straight forward. I’d like to mention though that in the above code you see a red xxx. This is where you put your sender address. It needs to either be the email to an admin (registered developer) of the app, or it has to be a user logged in using Google’s own login.

With the low-level api it throws an exception like the one below:

Uncaught exception from servlet
org.codehaus.groovy.runtime.InvokerInvocationException: java.lang.IllegalArgumentException: Unauthorized Sender: Unauthorized sender

Good luck!

, ,

3 Comments

Google AppEngine does not like leftshift

I ran into an issue last night where Google AppEngine wouldn’t persist my entities. If I create an entity using the parameters provided by Grails; then the Save operations would fail with the following error

Uncaught exception from servlet
org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingMethodException: No signature of method: java.lang.StringBuilder.leftShift() is applicable for argument types: (org.codehaus.groovy.runtime.GStringImpl) values: [(login.email  = ?1 )]
	at com.studentsonly.grails.plugins.uiperformance.CacheFilter.doFilter(CacheFilter.java:71)
	at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
	at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
	at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:237)
	at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
	at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:139)
	at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:235)
	at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4823)
	at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4821)
	at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)
	at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:359)
	at com.google.net.rpc.impl.Server$2.run(Server.java:820)
	...

The issue is described here. I tried their solution and it works fine for me.

, ,

No Comments

Grails and Google AppEngine Beginners Guide

I recently moved one of my applications to Google AppEngine. What I found missing was an explanatory tutorial to get started. As I mostly work with C#, I kept running into issues simply because I wasn’t too familiar with the technologies used.

Thus I’m writing this easy to follow all-steps-included tutorial, to help people whom are in a similar position to quickly get started developing with Grails for Google AppEngine.

This tutorial will take you through setting up a simple Grails application running on Google AppEngine; using the app-engine and GORM-JPA plugins to Grails. If you run into trouble, I’ve added a trouble shooting section at the end.

First of make sure you have the latest version of the Google AppEngine SDK, and Grails 1.1.1 or better. If you want to deploy your application to Google AppEngine, make sure you have an active account.

I also added a Known Issues section at the end, it’s there to assist you if you run into trouble.

Lets get started.

Create a Grails Application

First create a Grails Application using the create-app command. For this tutorial we’re creating an application called AppEngineDemo; but the name is not important.

C:\Users\Morten\IdeaProjects>grails create-app
Welcome to Grails 1.1.1 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:\dev\grails-1.1.1

Base Directory: C:\Users\Morten\IdeaProjects
Running script c:\dev\grails-1.1.1\scripts\CreateApp_.groovy
Environment set to development
Application name not specified. Please enter:
AppEngineDemo

Install the App-Engine plugin

The app-engine plugin requires a environment variable to be set to the location in which the Google SDK is installed. I recommend you take a minute or two to read through the plugin information page. I’ll add some examples form running the installation on the command line.

Move to the newly created application and install the app-engine plugin to the application.

C:\Users\Morten\IdeaProjects>cd AppEngineDemo

C:\Users\Morten\IdeaProjects\AppEngineDemo>grails install-plugin app-engine
Welcome to Grails 1.1.1 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:\dev\grails-1.1.1

Base Directory: C:\Users\Morten\IdeaProjects\AppEngineDemo
Running script c:\dev\grails-1.1.1\scripts\InstallPlugin.groovy
Environment set to development
Reading remote plugin list ...
Reading remote plugin list ...
Plugin list out-of-date, retrieving..

During the installation the plugin will ask you which persistence provider you want to use. We want to use the GORM-JPA plugin so select JPA for persistence.

Do you want to use JPA or JDO for persistence? (jpa, jdo)
jpa

This will create a file called persistance.xml in your Grails conf directory. In this file we will specify which domain objects we can persist to the Google AppEngine data storage.

Install GORM-JPA plugin

The GORM-JPA plugin will allow us to use the convenient dynamic methods for persistence; for example save() or findby…()

It is a straight forward to install the plugin

C:\Users\Morten\IdeaProjects\AppEngineDemo>grails install-plugin gorm-jpa
Welcome to Grails 1.1.1 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:\dev\grails-1.1.1

Base Directory: C:\Users\Morten\IdeaProjects\AppEngineDemo
Running script c:\dev\grails-1.1.1\scripts\InstallPlugin.groovy
Environment set to development
Reading remote plugin list ...

Create a domain class

We want to create a domain class for the application, in this tutorial we will create a domain class called Note.

C:\Users\Morten\IdeaProjects\AppEngineDemo>grails create-domain-class
Welcome to Grails 1.1.1 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:\dev\grails-1.1.1

Base Directory: C:\Users\Morten\IdeaProjects\AppEngineDemo
Running script c:\dev\grails-1.1.1\scripts\CreateDomainClass.groovy
Environment set to development
Domain class name not specified. Please enter:
Note
Created DomainClass for Note
Created Tests for Note

Next we generate the necessary controllers and views for the Note domain class.

C:\Users\Morten\IdeaProjects\AppEngineDemo>grails generate-all Note
Welcome to Grails 1.1.1 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:\dev\grails-1.1.1

Base Directory: C:\Users\Morten\IdeaProjects\AppEngineDemo
Running script c:\dev\grails-1.1.1\scripts\GenerateAll.groovy
---
Generating views for domain class Note ...
Generating controller for domain class Note ...
Finished generation for domain class Note

Move the domain classes into a package

The storage platform used by Google AppEngine doesn’t allow you to have your persisted domain classes in the default package. Not to worry, this is also good practice. We move our Note domain class into the package called persisted.

package persisted;

import javax.persistence.*;
// import com.google.appengine.api.datastore.Key;

class Note implements Serializable {

 Long id

}

Note the green code line in the above code.

Might as well add some code while were at it. The complete code for the Note domain class should be the following:

package persisted;

import javax.persistence.*;
// import com.google.appengine.api.datastore.Key;

class Note implements Serializable {

 Long id

 String message
}

Update the domain class with annotations

Now we must specify that the Note class can be persisted, and how it will be persisted. This is done using JPA annotations.

You might have noticed the @Entity, @Id,  @GeneratedValue… lines in the above code. These are JPA annotations added by Grails when you created the domain class. Now we must specify one for our added Message property.

We just want to say that it should be persisted along with the class. For this we add the @Basic annotation above the line declaring the message property. This will tell the persistence layer that this property should be saved.

package persisted;

import javax.persistence.*;
// import com.google.appengine.api.datastore.Key;

@Entity
class Note implements Serializable {

 @Id
 @GeneratedValue(strategy = GenerationType.IDENTITY)
 Long id

@Basic
 String message

}

A list of the JPA annotations and their usages can be found here.

Generate the views and controllers

Now it’s time to generate view and controllers for the Note class. This is done as normal, specifying which class to generate for.

C:\Users\Morten\IdeaProjects\AppEngineDemo>grails generate-all persisted.Note
Welcome to Grails 1.1.1 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:\dev\grails-1.1.1

Base Directory: C:\Users\Morten\IdeaProjects\AppEngineDemo
Running script c:\dev\grails-1.1.1\scripts\GenerateAll.groovy
Environment set to development
 [groovyc] Compiling 1 source file to C:\Users\Morten\.grails\1.1.1\projects\AppEngineDemo\classes
 [copy] Copying 1 file to C:\Users\Morten\.grails\1.1.1\projects\AppEngineDemo
 [groovyc] Compiling 1 source file to C:\Users\Morten\.grails\1.1.1\projects\AppEngineDemo\classes
 [copy] Copying 1 file to C:\Users\Morten\.grails\1.1.1\projects\AppEngineDemo
Generating views for domain class persisted.Note ...
Generating controller for domain class persisted.Note ...
Finished generation for domain class persisted.Note
C:\Users\Morten\IdeaProjects\AppEngineDemo>

Notice that I specified the package name for the class.

First time deployment to Google AppEngine

Create an application on Google AppEngine using Google’s AppEngine website. When you create your application you specify an name for it. You need to include this name in the grails-app/conf/config.groovy file in your application. Add the following line to the file:

google.appengine.application = "<your application name>"

To host your application on Google AppEngine you need to set the version to a number between 1-100. It has to be an integer, floats are not accepted.

then do the following:

grails set-version 1
grails app-engine package
$APPENGINE_HOME/bin/appcfg.sh update ./target/war

and now to deploy

grails app-engine deploy

Congratulations, your first, basic Google AppEngine application is now running.

Known Issues

Since Grails on Google AppEngine is pretty new, not to mention Java on Google AppEngine. There are still some issues to work through.

Staging dir not cleared

Before we start I just want to mention some known Issues. There is an issue where the staging dir is not removed, you have to delete this manually. You can find it under:

 <user directory>\.grails\1.1.1\projects\<projectname>\stage

the 1.1.1 is the version Grails your using. This causes issues if you install the ui-performance plugin.

Rendering JSON

There is also an issue with rendering JSON. Rendering JSON can cause access exceptions when rendering entities fetched using the GORM. Please see this blog post for details.

Update: I recentlly wrote this post on Fun times with JSON rendering. Containing more details about JSON Rendering.

Generating controllers

You can run into issues generating controllers and views for your domain classes. The current workaround as far as I know is to install the hibernate plugin, generate the views or controllers, then uninstall the hibernate plugin. You can see the details here.

Command Line too long on Windows machines

If your on a Windows machine you might run into a problem where you cannot enhance your classes (preparing them for storage on the GoogleAppEngine data store). The problem is that the command line when enhancing them becomes too long. You can find more details in my previous blog posts on the subject.

Saving Entities with constraints

If you add constraints to your classes you can run into issues where Google AppEngine will try to save the entity using the wrong class. More details in this blog post.

Recommended reading

Here is link to the open JIRA issues for the AppEngine plugin.

If you find any errors in this tutorial or have ideas to improve it, please let me know.

Hope it helps!

, , ,

25 Comments

Rendering lists from Google AppEngine as JSON

I ran into another problem with Google AppEngine. I finally got it to save my entities, only to find it crashing as I wanted to send them back again rendered as JSON.

I had a piece of code looking like this:

def services = {
 params.max = Math.min(params.max ? params.max.toInteger() : 10, 100)
 render Offering.list(params) as JSON;
 }

The code is simple enough, it loads all the Service offerings using GORM and then renders them as JSON using the built in converter. This resulted in the following error:

Uncaught exception from servlet
org.codehaus.groovy.runtime.InvokerInvocationException: org.codehaus.groovy.grails.web.converters.exceptions.ConverterException: Error converting Bean with class org.codehaus.groovy.reflection.ClassLoaderForClassArtifacts
...
Caused by: org.codehaus.groovy.grails.web.converters.exceptions.ConverterException: Error converting Bean with class org.codehaus.groovy.reflection.ClassLoaderForClassArtifacts
	at grails.converters.JSON.value(JSON.java:199)
	at grails.converters.JSON.convertAnother(JSON.java:156)
...
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_$3.run(Method_.java:149)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.privilegedInvoke(Method_.java:147)
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.invoke(Method_.java:120)
	... 26 more
Caused by: java.lang.reflect.InvocationTargetException
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_$3.run(Method_.java:149)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.privilegedInvoke(Method_.java:147)
	at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Method_.invoke(Method_.java:120)
...
Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader)
	at java.security.AccessControlContext.checkPermission(Unknown Source)
	at java.security.AccessController.checkPermission(Unknown Source)
	at java.lang.SecurityManager.checkPermission(Unknown Source)
	at java.lang.ClassLoader.getParent(Unknown Source)
	... 59 more

The problem is that the GORM loads the class with some meta data attached to it. I’m not allowed to reflect over this meta data, so the normal converter fails with the above error. I took the privilege to shorten the stack trace somewhat.

The work around is simple and elegant. I use the groovy collection method called select. With this I can construct a list with maps with the fields I want in my JSON and render them using the normal converter.

def services = {
 params.max = Math.min(params.max ? params.max.toInteger() : 10, 100)
 def list =  Offering.list(params);
 render list.collect { offering->[id:offering.id, name:offering.name]} as JSON
 }

The above code works fine on Google AppEngine.

I hope this helps someone else.

, ,

4 Comments

Researching Android Calendar

I’m itching to buy a HTC Hero. However I want to test it out before committing myself to buying one. One feature in particular I want to test is the Calendar application. A good Calendar application is a must for me.

I got the idea that I could run android on an Emulator to testout the calendar application, to get a look and feel.

I downloaded the SDK for Android, installed it to my dev folder and within minutes I had an emulator running on my desktop. One thing I can mention straight away is that the emulator feels fast, much faster than the Windows Mobile emulator which I’m used to.

However with the basic setup there is no calendar application running in the Android phone. The suggestion on forums is to download the Android source, compile it and then you get the Calendar.apk files which you can install on the phone. However, you cannot compile the source on Windows Machines. Which means I have to figure out some other way of getting my hands on the calendar application.

While researching this I had the chance to look at the development guide for Android, and I must say that I am impressed. The best practice section is great, and I really like the details given in the UI guidelines.

,

No Comments

Moving from Mor.ph to Google AppEngine

Moving from Mor.ph AppSpace to Google AppEngine isn’t as easy as I hoped.

Installing AppEngine plug in

Initially moving the Application by installing the app-engine plug in is straight forward. Except that the command-line written in the plug in page for executing the initial setup is wrong. Ive corrected it now.

Windows users need to run the update command with the following command-line:

%APPENGINE_HOME%/bin/appcfg.cmd update ./target/war

Also unless the app-engine code executes correctly it will not clean up the staging directory. This causes problems if your using plug ins such as the ui-performance plug in. That is written to execute on a “clean” staging directory. If you it’s not cleaned up the plug in will try to compress the gziped version the files as well.

GORM

The problem however is that the GORM functions are not available, since the AppEngine is using a different data storage not supported by Hibernate.

There is a solution to this, install the GORM-JPA plug in. This gives you most GORM functions, but using Google AppEngines data storage.

Issues

From here I’ve run into several issues along the way. The framework for deploying to Google AppEngine crashes when running on Windows machines; if you have allot of libraries and classes in your project. Google AppEngine fails to save my entities, JSON conversion is acting up as it tries to serialize class meta data for some reason, which is were I’m currently stuck.

Light at the end of the Tunnel

Now I’d also like to mention that these issues are being ironed out. There are people looking at most of them, it’s just that Grails on Google AppEngine is relatively young so to speak. Even Java on Google AppEngine is quite new, if not Google AppEngine in it self.

Also I’d also like to mention the dashboard on Google AppEngine. It’s great!

The Dashboard on Google AppEngine gives the overview logs I got from Mor.ph, but they are presented better. They also give me some summaries on where most errors occur (which URLs crash) and which URLs are consuming the most CPU. This helps me to optimize specific URLs.

Since my application uses a REST service consumed through AJAX I can optimize parts of the application on the back end, and monitor the usage of parts of the web service.

, ,

No Comments

Saving entites on Google AppEngine

I ran into a problem with Grails on Google AppEngine. When I was saving my entities it tried to save the wrong type of entity. I ran out of ideas on this one and brought it up on the Grails User mailinglist.

I started to work on some reproduction code and then I went to Denmark for some vacation. When I get back however, Keith Thomas had run into the same issue and figured out that it had something to do with the constraints on the domain classes.

Sure enough removing the constraints fixed the issue with saving. Ill try to see if the problem is specific to some kinds of constraints, since I still have my reproduction project to test it in.

, ,

No Comments

Grails and Google AppEngine on Windows

In a previous post I described a problem where the app-engine command would fail when enhancing the domain objects for persistence.

The problem was that the command line became too long to execute on windows, when executing the enhancement task.

I’ve been working on several workarounds for this problem.

  • Enhancing the classes during compilation
  • Enhancing the classes manually
  • Enhancing the classes programmatically
  • Modifying the ant target to produce shorter command line calls

Enhancing during compilation

Make sure you have version JDK 1.6 and add the enhancer and its requirements to the compilation class-path. Produces no errors during compilation, but no enhancement is done. Fails when not all libraries included, so something is happening. I’m not sure it can find the persistence.xml file to use.

Enhancing the classes manually

I had problems where the enhancer wouldn’t find the domain objects when compiled into a package. It would say that the classes we’re not included in my class-path, even though they were.

However, working with the manual enhancement I found a wonderful option called checkonly. So you could set the enhancement tool to just check if the classes are enhanced. This would be a excellent extra option for the grails app-engine plug-in, if you could call grails app-engine diagnostic and see which files that are enhanced.

Enhancing the classes programmatically

This seems to be a viable option. I modified the app-engine plugin for grails to do the enhancement programmatically, however it failed to enhance the files with two problems. Out of the box, the persistance.xml file is not located where it should be to enhance the compiled classes. It must be copied to a location where the enhancer can find it. The other problem was that of how grails organizes its compiled files.

Modifying the ant target to produce shorter command line calls

This is what I’ve got working right now. In the Google SDK I modify the ant-macros.xml

<macrodef name="enhance_war" description="Run the ORM enhancer on an exploded war">
 <attribute name="war" description="The exploded war directory containing the application"/>
 <element name="args" optional="true" description="Additional arguments to the enhancer"/>
 <sequential>
 <enhance failonerror="true" >
 <args/>
 <classpath>
 <pathelement path="${appengine.tools.classpath}"/>
 <pathelement path="@{war}/WEB-INF/classes"/>
 <fileset dir="@{war}/WEB-INF/lib" includes="*.jar"/>
 </classpath>
 <fileset dir="@{war}/WEB-INF/classes" includes="**/*.class"/>
 </enhance>
 </sequential>
 </macrodef>

becomes

<macrodef name="enhance_war" description="Run the ORM enhancer on an exploded war">
 <attribute name="war" description="The exploded war directory containing the application"/>
 <element name="args" optional="true" description="Additional arguments to the enhancer"/>
 <sequential>
 <enhance failonerror="true" >
 <args/>
 <classpath>
 <pathelement path="${appengine.tools.classpath}"/>
 <pathelement path="@{war}/WEB-INF/classes"/>
 <fileset dir="@{war}/WEB-INF/lib" includes="*.jar"/>
 </classpath>
 <fileset dir="@{war}/WEB-INF/classes/persisted" includes="**/*.class"/>
 </enhance>
 </sequential>
 </macrodef>

Now all my domain classes that requires persistence is in a package called persisted.  The macro should be modified to fit your needs or find a convention to follow in all your projects running on Google AppEngine.

, , ,

11 Comments