PDA

View Full Version : Spring Roo and Google App Engine



marceloverdijk
May 8th, 2009, 06:08 AM
Will it be easy to develop a Roo application and deploy it on Google App Engine?

Ben Alex
May 8th, 2009, 11:07 PM
There is no theoretical prohibition to doing this based on Roo's architecture, but you need to consider that GAE's data store does not have the traditional ACID transactions many applications need.

GAE Java support also prefers uses work through JDO instead of JPA, with Roo alpha 2 offering JPA support only. You might notice we've written our commands in a form that is intended to specifically request JPA usage where persistence is involved. This was undertaken so we can easily add JDO support in the future. There is no specific timeframe for this, but it's not really complicated to do. The metadata model within Roo has already been designed to support persistence technology independence, so my best advice is "stay tuned".

Don't forget in the meantime you can very easily deploy Roo applications to EC2. This is where our "voting application" was running from that we developed at last week's SpringOne keynote. Indeed if you download our now-free STS 2.1.0 (the next series) IDE, you'll see it has inbuilt EC2 support. This means you can build a Roo app entirely within STS 2.1.0+, then deploy it straight to an Amazon Web Services cloud environment. This is pretty neat, especially as with the EC2 approach you receive full ACID transactions and can continue to use ORMs like Hibernate, which are likely to be more familiar to most developers than JDO mappers. It also means you can take the same WAR and deploy it to a non-cloud environment, giving you total portability away from the AWS cloud environment should you wish to use it.

marceloverdijk
May 13th, 2009, 04:01 PM
GAE/J also support JPA out of the box. See http://code.google.com/appengine/docs/java/datastore/usingjpa.html

jpreston
Sep 17th, 2009, 08:23 PM
So I ran across this thread and thought I'd voice my findings so far...

My setup:

Spring Framework 3.0.0-M4
Spring Roo 1.0.0-RC1
Google AppEngine API v1.2.5

I can follow the Roo instructions 100%. My roo script appears as:



create project -topLevelPackage family.abe -projectName family-abe
install jpa -provider HIBERNATE -database MYSQL
new persistent class jpa -name ~.reference.EventType -testAutomatically
new persistent class jpa -name ~.domain.Event -testAutomatically
add field string -class ~.reference.EventType -fieldName name -notNull -sizeMax 30
add field string -class ~.reference.EventType -fieldName description -sizeMax 255
add field string -class ~.domain.Event -fieldName name -notNull -sizeMin 5 -sizeMax 60
add field date jdk -type java.util.Date -class ~.domain.Event -fieldName eventDate -notNull
add field date jdk -type java.util.Date -class ~.domain.Event -fieldName rsvp -notNull
add field string -class ~.domain.Event -fieldName description -sizeMax 255
add field string -class ~.domain.Event -fieldName location -sizeMax 255
add field string -class ~.domain.Event -fieldName directions -sizeMax 255
add field string -class ~.domain.Event -fieldName notes -sizeMax 255
add field boolean -class ~.domain.Event -fieldName alcohol
add field boolean -class ~.domain.Event -fieldName food
add field boolean -class ~.domain.Event -fieldName showLocation
add field boolean -class ~.domain.Event -fieldName showDirections
add field reference jpa -class ~.domain.Event -fieldName type -type ~.reference.EventType -notNull
new controller automatic -name ~.web.EventTypeController -formBackingObject ~.reference.EventType
new controller automatic -name ~.web.EventController -formBackingObject ~.domain.Event
configure logging -level INFO -package ALL_SPRING
configure logging -level WARN -package AOP
configure logging -level INFO -package PERSISTENCE
configure logging -level DEBUG -package PROJECT
configure logging -level WARN -package SECURITY
configure logging -level WARN -package TRANSACTIONS
configure logging -level INFO -package WEB


I create src/main/webapp/appengine-web.xml with the usual contents and then I modify my pom.xml as so:



<project>
...
<repositories>
...
<repository>
<id>DataNucleus_Repos</id>
<name>DataNucleus Repository</name>
<url>http://www.datanucleus.org/downloads/maven</url>
<layout>legacy</layout>
</repository>
<repository>
<id>DataNucleus_Repos2</id>
<name>DataNucleus Repository</name>
<url>http://www.datanucleus.org/downloads/maven2</url>
</repository>
</repositories>
<pluginRepositories>
...
<pluginRepository>
<id>DataNucleus_2</id>
<url>http://www.datanucleus.org/downloads/maven2/</url>
</pluginRepository>
</pluginRepositories>
<dependencies>
...
<!-- Google App Engine Dependencies which are manually installed -->
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-tools-api</artifactId>
<version>1.2.5</version>
</dependency>

<!-- Data Nucleus Dependencies -->
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-appengine</artifactId>
<version>1.0.2.final</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-core</artifactId>
<version>1.1.4</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-jpa</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-enhancer</artifactId>
<version>1.1.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_3.0_spec</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jta_1.1_spec</artifactId>
<version>1.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.jdo</groupId>
<artifactId>jdo2-api</artifactId>
<version>2.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.2</version>
<scope>compile</scope>
</dependency>

<!-- Use ASM 1.5.3 for Spring at runtime, but we need 3.0+ for Data Nucleus during compile -->
<dependency>
<artifactId>com.springsource.org.objectweb.asm</artifactId>
<groupId>org.objectweb.asm</groupId>
<version>1.5.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<artifactId>com.springsource.org.objectweb.asm.attrs</artifactId>
<groupId>org.objectweb.asm</groupId>
<version>1.5.3</version>
<scope>runtime</scope>
</dependency>

<!-- Included to get rid of a silly error when building this with maven -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.3</version>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.datanucleus</groupId>
<artifactId>maven-datanucleus-plugin</artifactId>
<version>1.1.0</version>
<configuration>
<api>JPA</api>
<enhancerName>ASM</enhancerName>
<log4jConfiguration>src/main/resources/META-INF/spring/log4j.properties</log4jConfiguration>
<persistenceUnitName>transactions-optional</persistenceUnitName>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</project>


Then I replace src/main/resources/META-INF/persistence.xml with the contents:



<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

<persistence-unit name="transactions-optional">
<provider>org.datanucleus.store.appengine.jpa.DatastorePersi stenceProvider</provider>
<class>family.abe.domain.Event</class>
<class>family.abe.reference.EventType</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="datanucleus.NontransactionalRead" value="true"/>
<property name="datanucleus.NontransactionalWrite" value="true"/>
<property name="datanucleus.ConnectionURL" value="appengine"/>
</properties>
</persistence-unit>
</persistence>


Additionally, I create src/main/resources/META-INF/orm.xml with the contents:



<?xml version="1.0" encoding="UTF-8"?>

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
version="1.0">

<entity class="family.abe.reference.EventType">
<id-class class="java.lang.Long" />
</entity>
<entity class="family.abe.domain.Event">
<id-class class="java.lang.Long" />
</entity>

</entity-mappings>


I also modify src/main/resources/META-INF/spring/log4j.properties adding the following:



# Define the destination and format of logging for Data Nucleus
log4j.appender.A1=org.apache.log4j.FileAppender
log4j.appender.A1.File=datanucleus.log
log4j.appender.A1.layout=org.apache.log4j.PatternL ayout
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

# DataNucleus Categories
log4j.category.DataNucleus.JDO=DEBUG, A1
log4j.category.DataNucleus.JPA=DEBUG, A1
log4j.category.DataNucleus.Cache=DEBUG, A1
log4j.category.DataNucleus.MetaData=DEBUG, A1
log4j.category.DataNucleus.General=DEBUG, A1
log4j.category.DataNucleus.Utility=DEBUG, A1
log4j.category.DataNucleus.Transaction=DEBUG, A1
log4j.category.DataNucleus.Datastore=DEBUG, A1
log4j.category.DataNucleus.ClassLoading=DEBUG, A1
log4j.category.DataNucleus.Plugin=DEBUG, A1
log4j.category.DataNucleus.ValueGeneration=DEBUG, A1

log4j.category.DataNucleus.Enhancer=DEBUG, A1
log4j.category.DataNucleus.SchemaTool=DEBUG, A1

jpreston
Sep 17th, 2009, 08:39 PM
I then run mvn -e -o clean package with the following output (trimmed for size)



+ Error stacktraces are turned on.

[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building family-abe
[INFO] task-segment: [clean, compile, package]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean]
[INFO] Deleting directory /Users/jpreston/src/family-abe/target
[INFO] [aspectj:compile {execution: default}]
[INFO] [resources:resources]
[INFO] Using encoding: 'UTF-8' to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [aspectj:compile {execution: default}]
[INFO] [resources:resources]
[INFO] Using encoding: 'UTF-8' to copy filtered resources.
[INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [datanucleus:enhance {execution: default}]
[INFO] DataNucleus Enhancer : Using ClassEnhancer "ASM" for API "JPA"

MetaDataManager : Input=(XML, Annotations), XML-Validation=true
Parsing MetaData file "file:/Users/jpreston/src/family-abe/target/classes/META-INF/persistence.xml" using handler "persistence" (validation="true")
XML Entity Public="" System="http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" : using local source "/org/datanucleus/jpa/jpa_persistence_1_0.xsd"
MetaData Management : Loading Metadata for persistence-unit "transactions-optional" ...
Parsing MetaData file "file:/Users/jpreston/src/family-abe/target/classes/META-INF/orm.xml" using handler "jpa" (validation="true")
XML Entity Public="" System="http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" : using local source "/org/datanucleus/jpa/jpa_orm_1_0.xsd"

Populating all MetaData ...
Populating Meta-Data for class family.abe.reference.EventType.
Class "family.abe.reference.EventType" has been specified with JPA annotations so using those.
Ignoring metadata for field family.abe.reference.EventType.description since we already have MetaData for the property family.abe.reference.EventType.description
Ignoring metadata for field family.abe.reference.EventType.name since we already have MetaData for the property family.abe.reference.EventType.name
Class "family.abe.reference.EventType" is having internal MetaData definition updated with Annotations information
Populating Meta-Data for class family.abe.domain.Event.
Class "family.abe.domain.Event" has been specified with JPA annotations so using those.
Ignoring metadata for field family.abe.domain.Event.eventDate since we already have MetaData for the property family.abe.domain.Event.eventDate
Ignoring metadata for field family.abe.domain.Event.location since we already have MetaData for the property family.abe.domain.Event.location
Ignoring metadata for field family.abe.domain.Event.type since we already have MetaData for the property family.abe.domain.Event.type
Ignoring metadata for field family.abe.domain.Event.directions since we already have MetaData for the property family.abe.domain.Event.directions
Ignoring metadata for field family.abe.domain.Event.description since we already have MetaData for the property family.abe.domain.Event.description
Ignoring metadata for field family.abe.domain.Event.name since we already have MetaData for the property family.abe.domain.Event.name
Ignoring metadata for field family.abe.domain.Event.notes since we already have MetaData for the property family.abe.domain.Event.notes
Class "family.abe.domain.Event" is having internal MetaData definition updated with Annotations information
Annotations information
Initialising all MetaData ...
Initialising Meta-Data for class family.abe.reference.EventType.

[ERROR] --------------------
[ERROR] Standard error from the DataNucleus tool + org.datanucleus.enhancer.DataNucleusEnhancer :
[ERROR] --------------------
[ERROR] Exception in thread "main" java.lang.AbstractMethodError: org.datanucleus.jpa.JPAAdapter.isValidPrimaryKeyCl ass(Ljava/lang/Class;Lorg/datanucleus/metadata/AbstractClassMetaData;Lorg/datanucleus/ClassLoaderResolver;ILorg/datanucleus/metadata/MetaDataManager;)Z
at org.datanucleus.metadata.AbstractClassMetaData.val idateObjectIdClass(AbstractClassMetaData.java:1082 )
at org.datanucleus.metadata.ClassMetaData.initialise( ClassMetaData.java:599)
at org.datanucleus.metadata.MetaDataManager$2.run(Met aDataManager.java:2442)
at java.security.AccessController.doPrivileged(Native Method)
at org.datanucleus.metadata.MetaDataManager.initialis eAbstractClassMetaData(MetaDataManager.java:2436)
at org.datanucleus.metadata.MetaDataManager.initialis eClassMetaData(MetaDataManager.java:2295)
at org.datanucleus.metadata.MetaDataManager.initialis eFileMetaData(MetaDataManager.java:2243)
at org.datanucleus.metadata.MetaDataManager.initialis eFileMetaDataForUse(MetaDataManager.java:938)
at org.datanucleus.metadata.MetaDataManager.loadPersi stenceUnit(MetaDataManager.java:851)
at org.datanucleus.enhancer.DataNucleusEnhancer.getFi leMetadataForInput(DataNucleusEnhancer.java:808)
at org.datanucleus.enhancer.DataNucleusEnhancer.enhan ce(DataNucleusEnhancer.java:551)
at org.datanucleus.enhancer.DataNucleusEnhancer.main( DataNucleusEnhancer.java:1260)

[ERROR] --------------------
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] The DataNucleus tool org.datanucleus.enhancer.DataNucleusEnhancer exited with a non-null exit code.
[INFO] ------------------------------------------------------------------------
[INFO] Trace
org.apache.maven.lifecycle.LifecycleExecutionExcep tion: The DataNucleus tool org.datanucleus.enhancer.DataNucleusEnhancer exited with a non-null exit code.
at org.apache.maven.lifecycle.DefaultLifecycleExecuto r.executeGoals(DefaultLifecycleExecutor.java:583)
at org.apache.maven.lifecycle.DefaultLifecycleExecuto r.executeGoalWithLifecycle(DefaultLifecycleExecuto r.java:499)
at org.apache.maven.lifecycle.DefaultLifecycleExecuto r.executeGoal(DefaultLifecycleExecutor.java:478)
at org.apache.maven.lifecycle.DefaultLifecycleExecuto r.executeGoalAndHandleFailures(DefaultLifecycleExe cutor.java:330)
at org.apache.maven.lifecycle.DefaultLifecycleExecuto r.executeTaskSegments(DefaultLifecycleExecutor.jav a:291)
at org.apache.maven.lifecycle.DefaultLifecycleExecuto r.execute(DefaultLifecycleExecutor.java:142)
at org.apache.maven.DefaultMaven.doExecute(DefaultMav en.java:336)
at org.apache.maven.DefaultMaven.execute(DefaultMaven .java:129)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:2 87)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(L auncher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher. java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode (Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.ja va:375)
Caused by: org.apache.maven.plugin.MojoExecutionException: The DataNucleus tool org.datanucleus.enhancer.DataNucleusEnhancer exited with a non-null exit code.
at org.datanucleus.maven.AbstractDataNucleusMojo.exec uteCommandLine(AbstractDataNucleusMojo.java:263)
at org.datanucleus.maven.AbstractEnhancerMojo.enhance (AbstractEnhancerMojo.java:184)
at org.datanucleus.maven.AbstractEnhancerMojo.execute DataNucleusTool(AbstractEnhancerMojo.java:81)
at org.datanucleus.maven.AbstractDataNucleusMojo.exec ute(AbstractDataNucleusMojo.java:107)
at org.apache.maven.plugin.DefaultPluginManager.execu teMojo(DefaultPluginManager.java:451)
at org.apache.maven.lifecycle.DefaultLifecycleExecuto r.executeGoals(DefaultLifecycleExecutor.java:558)
... 16 more
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 14 seconds
[INFO] Finished at: Thu Sep 17 21:25:07 EDT 2009
[INFO] Final Memory: 27M/81M
[INFO] ------------------------------------------------------------------------


I'm fresh out of ideas from here; I've tried manually compiling AspectJ and then manually running the Data Nucleus Enhancer, however, the result is the same. It's getting late now, but hopefully I'll get some time to dig into the source for everything and see where the hiccup is.

Anyone have any ideas where to look or go to next until then?

Thanks in advance!

** Update

This was caused by the use of the incorrect version of the datanucleus enhancer plugin. I switched the plugin version to 1.1.4 and it worked properly.

jpreston
Sep 18th, 2009, 07:32 AM
I've managed to get the Data Nucleus Enhancer to work with the Roo Project, and the Roo application deployed to the dev_appsrv for Google AppEngine. However, there appears to be issues with transaction management and the bytecode enhancement. When it runs, it runs VERY slowly and some of my domain classes are being looked up at java.lang, which is strange. I'm going to continue looking at it, and see what the deal is.

** Update
JSPs compile painfully slow on the dev app server, but once deployed on app engine it is not an issue because all JSPs are precompiled.

jpreston
Sep 21st, 2009, 07:05 AM
The interesting part is that I am able to successfully get a Roo application deployed to Google App Engine; however, the manner in which Google App Engine handles relationships (mainly parent/child) requires the use of the com.google.appengine.api.datastore.Key, not Longs. It does appear that this Key essentially wraps a Long as a primary key, but it also contains information regarding parent/child relationships. I'm guessing this is a "feature" of the BigTable datastore they use. I was able to get it working, however, it is no small feat. Basically what I had to do was add a Key field to all of my persistent classes and make it the primary key. I removed the Long id field, but retained the getter/setters, replacing them with the following contents:



public Long getId() {
return getKey.getId();
}

public void setId(Long id) {
setKey(KeyFactory.createKey(this.getClass().getSim pleName(), id);
}


You can see more about using Keys here (http://code.google.com/appengine/docs/java/datastore/creatinggettinganddeletingdata.html#Keys).

While it wasn't the most straight forward or easiest approach, it did work. The only other things worth noting is that if you're using Maven to enhance your persistent classes, make sure you do not include the datanucleus-enhancer.jar library with your WAR as it will prevent JSPs from compiling correctly. Also, do not include any file appenders to your log4j configuration as it has dependencies to classes not on the app engine class whitelist (http://code.google.com/appengine/docs/java/jrewhitelist.html). You may use them for the local dev app server, but don't keep them in there when you deploy to app engine.

Hope this helps someone ;-)

Ben Alex
Sep 23rd, 2009, 09:09 PM
Hi Joshua

This is very interesting. Would you mind pasting some info/tips/attachments in the comments of http://jira.springframework.org/browse/ROO-146 so other people interested in GAE support can get started with Roo? In the meantime I've pasted a link to this thread, to help people find it.

Thanks again
Ben

lhwong
Dec 1st, 2009, 08:44 PM
Thanks for your post.

I use AspectJ Push In Refactoring (http://contraptionsforprogramming.blogspot.com/2009/05/push-in-refactoring-for-ajdt.html) to refactor the ROO generated code and copy the code to an Google App Engine project in Eclipse. I manage to run it using the GAE plug-in.

However, after deploying on to google app engine appspot I got the following error:

Nested in javax.servlet.ServletException:
org.springframework.beans.factory.BeanCreationExce ption: Error
creating bean with name 'tilesConfigurer' defined in ServletContext
resource [/WEB-INF/config/webmvc-config.xml]: Invocation of init
method failed; nested exception is java.lang.NoClassDefFoundError:
javax/el/ELContext:
org.springframework.beans.factory.BeanCreationExce ption: Error
creating bean with name 'tilesConfigurer' defined in ServletContext
resource [/WEB-INF/config/webmvc-config.xml]: Invocation of init
method failed; nested exception is java.lang.NoClassDefFoundError:
javax/el/ELContext
at
org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.initializeBean
(AbstractAutowireCapableBeanFactory.java:1395)
at
org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.doCreateBean
(AbstractAutowireCapableBeanFactory.java:512)
at
org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean
(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.Abstract BeanFactory
$1.getObject(AbstractBeanFactory.java:289)
at
org.springframework.beans.factory.support.DefaultS ingletonBeanRegistry.getSingleton
(DefaultSingletonBeanRegistry.java:222)
at
org.springframework.beans.factory.support.Abstract BeanFactory.doGetBean
(AbstractBeanFactory.java:286)
at
org.springframework.beans.factory.support.Abstract BeanFactory.getBean
(AbstractBeanFactory.java:188)
at
org.springframework.beans.factory.support.DefaultL istableBeanFactory.preInstantiateSingletons
(DefaultListableBeanFactory.java:543)
at
org.springframework.context.support.AbstractApplic ationContext.finishBeanFactoryInitialization
(AbstractApplicationContext.java:730)
at
org.springframework.context.support.AbstractApplic ationContext.refresh
(AbstractApplicationContext.java:387)
at
org.springframework.web.servlet.FrameworkServlet.c reateWebApplicationContext
(FrameworkServlet.java:447)
at
org.springframework.web.servlet.FrameworkServlet.i nitWebApplicationContext
(FrameworkServlet.java:342)
at org.springframework.web.servlet.FrameworkServlet.i nitServletBean
(FrameworkServlet.java:308)
at org.springframework.web.servlet.HttpServletBean.in it
(HttpServletBean.java:127)
at javax.servlet.GenericServlet.init(GenericServlet.j ava:215)
at org.mortbay.jetty.servlet.ServletHolder.initServle t

.....

.....

Nested in org.springframework.beans.factory.BeanCreationExce ption:
Error creating bean with name 'tilesConfigurer' defined in
ServletContext resource [/WEB-INF/config/webmvc-config.xml]:
Invocation of init method failed; nested exception is
java.lang.NoClassDefFoundError: javax/el/ELContext:
java.lang.ClassNotFoundException: javax.el.ELContext
at com.google.appengine.runtime.Request.process-408eddf7cf6cb8bd
(Request.java)
at java.lang.Class.forName(Class.java:124)
at org.apache.tiles.reflect.ClassUtil.getClass(ClassU til.java:60)
at org.apache.tiles.reflect.ClassUtil.instantiate(Cla ssUtil.java:96)
at org.apache.tiles.reflect.ClassUtil.instantiate(Cla ssUtil.java:75)
at org.apache.tiles.factory.TilesContainerFactory.cre ateFactory
(TilesContainerFactory.java:525)
at
org.apache.tiles.factory.TilesContainerFactory.sto reContainerDependencies
(TilesContainerFactory.java:432)
at org.apache.tiles.factory.TilesContainerFactory.ini tializeContainer
(TilesContainerFactory.java:368)
at org.apache.tiles.factory.TilesContainerFactory.cre ateTilesContainer
(TilesContainerFactory.java:287)
at org.apache.tiles.factory.TilesContainerFactory.cre ateContainer
(TilesContainerFactory.java:231)
at org.apache.tiles.startup.BasicTilesInitializer.cre ateContainer
(BasicTilesInitializer.java:117)
at org.apache.tiles.startup.BasicTilesInitializer.ini tialize
(BasicTilesInitializer.java:53)
at
org.springframework.web.servlet.view.tiles2.TilesC onfigurer.afterPropertiesSet
(TilesConfigurer.java:196)
at
org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory
$5.run(AbstractAutowireCapableBeanFactory.java:144 5)
at java.security.AccessController.doPrivileged(Native Method)
at
org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.invokeInitMethods
(AbstractAutowireCapableBeanFactory.java:1443)
at
org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.initializeBean
(AbstractAutowireCapableBeanFactory.java:1392)
at
org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.doCreateBean
(AbstractAutowireCapableBeanFactory.java:512)
at
org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean
(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.Abstract BeanFactory
$1.getObject(AbstractBeanFactory.java:289)
at
org.springframework.beans.factory.support.DefaultS ingletonBeanRegistry.getSingleton
(DefaultSingletonBeanRegistry.java:222)
at
org.springframework.beans.factory.support.Abstract BeanFactory.doGetBean
(AbstractBeanFactory.java:286)
at
org.springframework.beans.factory.support.Abstract BeanFactory.getBean
(AbstractBeanFactory.java:188)
at
org.springframework.beans.factory.support.DefaultL istableBeanFactory.preInstantiateSingletons
(DefaultListableBeanFactory.java:543)
at
org.springframework.context.support.AbstractApplic ationContext.finishBeanFactoryInitialization
(AbstractApplicationContext.java:730)
at

marceloverdijk
Jan 15th, 2010, 02:25 PM
I'm wondering if someone made some progress with Roo on App Engine.

mirror303
Mar 9th, 2010, 05:39 PM
@Jpreston... I was wondering how you configured your EntityManagerFactory and more specifically the datasource that that bean requires...

mirror303
Mar 9th, 2010, 05:50 PM
Nevermind, did it like this:



<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFact oryBean" lazy-init="true">
<property name="persistenceUnitName" value="transactions-optional" />
</bean>
<bean name="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>


where 'transactions-optional' is the same as the name attribute of the persistence-unit tag in persistence.xml

yonny4103
May 25th, 2010, 06:59 AM
Does anybody know if the source code for the expense application demoed at the Google IO is available for download, It would give a lot of insight on how to do roo development og Google App Engine Java.
Thanks

Ben Alex
May 25th, 2010, 07:14 PM
The final version of the expenses application is not available for download as it's a work-in-progress as we improve widgets and features in the GWT 2.1 / Roo 1.1 integration. However, in the Roo 1.1.0.M1 samples directory you will find expenses.roo. This shows you what we used to start building the expenses application and can be executed in Roo just by typing "script expenses.roo" and pressing enter (just be sure you're in an empty directory).

ganeshkrishnan
Aug 10th, 2010, 04:37 PM
I have got the 1.1.0M2 version of ROO and successfully ran a simple GWT application. When I tried to move my app to GWT/ROO I realized that roo+ GWT doesnt support parent-child relationship. FWOOOOP!

Alan Stewart
Aug 11th, 2010, 08:09 AM
Please wait for Roo 1.1M3 with GWT 2.1M3 for improvements in relationship handling - by end August

donut
Oct 24th, 2010, 04:56 PM
I'm brand new to ROO. I brought up the expense app using ROO 1.1.0.RC1

And I made an attempt to change the persistence.xml to use JPA for the entities I'm going to create next (this is where I'm coming from: http://code.google.com/appengine/docs/java/datastore/usingjpa.html):


<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">

<persistence-unit name="transactions-optional">
<provider>org.datanucleus.store.appengine.jpa.DatastorePersi stenceProvider</provider>
<properties>
<property name="datanucleus.NontransactionalRead" value="true" />
<property name="datanucleus.NontransactionalWrite" value="true" />
<property name="datanucleus.ConnectionURL" value="appengine" />
</properties>
</persistence-unit>
</persistence>

I fired it up in STS 2.5.0.RC1 and it gave me a class not found: org.datanucleus.store.appengine.jpa.DatastorePersi stenceProvider

I know I'm probably missing a ton of stuff here, but could someone give me a hint on what is need to get it to play nice with the way GAE works today? Or let me know if this isn't supported and I shouldn't bother trying.