I see in <
http://code.google.com/p/twig-persist/source/browse/src/main/
java/com/vercer/engine/persist/annotation/AnnotationStrategy.java>
this line of code:
67 throw new IllegalStateException("Final field " + field + " cannot
be stored");
I think that line of code is why all of my classes with 'final' fields
are throwing an exception like the one at the bottom of this post.
That tells me it was an explicit design decision to not support
'final' class fields. I'm new to Twig and GAE, so it may be obvious
why I can't use final fields in objects (or I may be misunderstanding
what's happening), but I've been searching the discussion group and
documentation around for an hour trying to figure out why, and it
still isn't clear to me. The closest I've found to an explanation was
this line from the wiki on configuration (
http://code.google.com/p/
twig-persist/wiki/Configuration)
"The only requirement of your data classes is that they have a no-args
or default constructor which can even be private."
I didn't have a default or no-args constructor in any of my classes
with final objects. But after reading this I made a test class that
had a final field and a no-args constructor that assigned the field a
trivial value and it still failed, so I don't think this is it.
Help would be appreciated, just pointing me to docs or posts
explaining it would be great.
***Exception***
SEVERE: javax.servlet.ServletContext log: Exception while dispatching
incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method
'public abstract java.lang.String
com.pabutab.client.GreetingService.greetServer(java.lang.String)
throws java.lang.IllegalArgumentException' threw an unexpected
exception: java.lang.IllegalStateException: Final field private final
long com.pabutab.dataObjects.FoodAttribute.foodID cannot be stored
at
com.google.gwt.user.server.rpc.RPC.encodeResponseForFailure(RPC.java:
385)
at
com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:
588)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:
208)
at
com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:
248)
at
com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:
62)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:
511)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1166)
at
com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:
35)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1157)
at
com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:
60)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1157)
at
com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:
43)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1157)
at
com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:
122)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1157)
at
com.google.appengine.tools.development.BackendServersFilter.doFilter(BackendServersFilter.java:
97)
at org.mortbay.jetty.servlet.ServletHandler
$CachedChain.doFilter(ServletHandler.java:1157)
at
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:
388)
at
org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:
216)
at
org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:
182)
at
org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:
765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:
418)
at
com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:
78)
at
org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:
152)
at com.google.appengine.tools.development.JettyContainerService
$ApiProxyHandler.handle(JettyContainerService.java:362)
at
org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:
152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:
542)
at org.mortbay.jetty.HttpConnection
$RequestHandler.content(HttpConnection.java:938)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at
org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:
409)
at org.mortbay.thread.QueuedThreadPool
$PoolThread.run(QueuedThreadPool.java:582)
Caused by: java.lang.IllegalStateException: Final field private final
long com.pabutab.dataObjects.FoodAttribute.foodID cannot be stored
at
com.google.code.twig.annotation.AnnotationConfiguration.store(AnnotationConfiguration.java:
92)
at com.google.code.twig.standard.TranslatorObjectDatastore
$StrategyObjectFieldTranslator.stored(TranslatorObjectDatastore.java:
574)
at
com.google.code.twig.translator.ObjectFieldTranslator.encode(ObjectFieldTranslator.java:
301)
at
com.google.code.twig.standard.StandardCommonStoreCommand.instanceToEntity(StandardCommonStoreCommand.java:
245)
at
com.google.code.twig.standard.StandardSingleStoreCommand.now(StandardSingleStoreCommand.java:
51)
at
com.google.code.twig.standard.TranslatorObjectDatastore.store(TranslatorObjectDatastore.java:
144)
at
com.pabutab.server.GreetingServiceImpl.greetServer(GreetingServiceImpl.java:
71)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at
com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:
104)
at
com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:
569)
... 34 more