Since version 1.2.6 Google AppEngine SDK in development mode requires to run JVM with javaagent.
If you don't do this you'll get the following exception:
java.lang.RuntimeException: Unable to locate the App Engine agent.
Please use dev_appserver, KickStart, or set the jvm flag:
"-javaagent:<sdk_root>/lib/agent/appengine-agent.jar"
at com.google.appengine.tools.development.DevAppServerFactory.testAgentIsInstalled(102)
at com.google.appengine.tools.development.DevAppServerFactory.createDevAppServer(77)
at com.google.appengine.tools.development.DevAppServerFactory.createDevAppServer(38)
at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(153)
at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
at com.google.appengine.tools.development.DevAppServerMain.(DevAppServerMain.java:113)
at com.google.appengine.tools.development.DevAppServerMain.main(89)
Caused by: java.lang.NoClassDefFoundError: com/google/appengine/tools/development/agent/AppEngineDevAgent
at com.google.appengine.tools.development.DevAppServerFactory.testAgentIsInstalled(98)
... 6 more
But if you do you may get very strange behaviour of your app. Here's a few of mines I get developing with Tapestry 5.2.0.0-SNAPSHOT:
java.lang.ClassFormatError: Invalid length 65050 in LocalVariableTable
in class file org/apache/tapestry5/corelib/components/Form
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at javassist.Loader.findClass(Loader.java:379)
at org.apache.tapestry5.internal.services.ComponentInstantiatorSourceImpl$PackageAwareLoader.findClass(94)
...
I've found a discussion where similiar problem was caused by multiple versions of javassist on CLASSPATH. I tried to find them, but I had only one of it.
The other exception is due to previous.
org.apache.tapestry5.ioc.internal.util.TapestryException:
Failure creating embedded component 'sendInvite' of dmitrygusev.ping.pages.Index:
java.lang.ClassNotFoundException: caught an exception while obtaining a class
file for org.apache.tapestry5.corelib.components.Form"
[at context:Index.tml, line 23]
at org.apache.tapestry5.internal.pageload.ComponentAssemblerImpl.createEmbeddedAssembler(316)
at org.apache.tapestry5.internal.pageload.PageLoaderImpl.startComponent(740)
...
Caused by: java.lang.RuntimeException: Class org.apache.tapestry5.corelib.components.Form contains field(s)
(_$bindingSource, _$environment, _$onActionInfo, _$resources, _$type, _$type_0, _$type_1)
that are not private. You should change these fields to private, and add accessor methods if needed.
at org.apache.tapestry5.internal.services.InternalClassTransformationImpl.verifyFields(293)
at org.apache.tapestry5.internal.services.InternalClassTransformationImpl.preloadMemberNames(255)
at org.apache.tapestry5.internal.services.InternalClassTransformationImpl.(151)
at org.apache.tapestry5.internal.services.ComponentClassTransformerImpl.transformComponentClass(163)
at $ComponentClassTransformer_1249f7f3976.transformComponentClass(...)
at org.apache.tapestry5.internal.services.ComponentInstantiatorSourceImpl.onLoad(205)
at javassist.Loader.findClass(Loader.java:340)
... 95 more
This all very strange, because when deployed to Google AppEgine there is no such errors, and this is very similiar to problem with a Security Manager I wrote about in a previous post.
To fix it I had to not specify javaagent on JVM start, but to avoid that "Unable to locate the App Engine agent" exception, I created the following class:
package com.google.appengine.tools.development.agent;
public class AppEngineDevAgent {
public static Object getAgent()
{
return null;
}
}
and putted it to my project:
Now I can run my project without javaagent. Please note, that you may still need to apply patch to Security Manager (its compatible with 1.2.2-6 GAE SDKs) to avoid other potential issues developing with GAE SDK.
Its also okay to deploy your app with this class to GAE, since it won't conflict with GAE environment.