Reflection is not allowed on private final char[] java.lang.String.value

63 views
Skip to first unread message

Blake

unread,
Apr 13, 2010, 10:31:24 PM4/13/10
to twig-persist
I decided to create a new thread, rather than drag that Blob.class
thread any further.

I'm getting the following exception when updating an entity by setting
a Set<String> that was previously null. This collection is annotated
with @Embed. I haven't traced your code all the way through, but I
have a hunch that it's looking at that HashSet<String> to see what it
should serialize, and it errors when it's introspecting the String
values stored in the HashSet.

The error happens when the Reflection class sets the fields accessible
on String.

----------------------------------------
com.vercer.util.Reflection getAccessibleFields: Exception caught while
trying to set field named value accessible on class type
java.lang.String - java.lang.SecurityException:
java.lang.IllegalAccessException: Reflection is not allowed on private
final char[] java.lang.String.value
at com.google.appengine.runtime.Request.process-
fdcdca173c4fd752(Request.java)
at java.lang.reflect.Field.setAccessible(Field.java:166)
at com.vercer.util.Reflection.getAccessibleFields(Reflection.java:67)
at
com.vercer.engine.persist.translator.ObjectFieldTranslator.getSortedFields(ObjectFieldTranslator.java:
263)
at
com.vercer.engine.persist.translator.ObjectFieldTranslator.typesafeToProperties(ObjectFieldTranslator.java:
214)
at
com.vercer.engine.persist.translator.ListTranslator.typesafeToProperties(ListTranslator.java:
150)
at
com.vercer.engine.persist.translator.ObjectFieldTranslator.typesafeToProperties(ObjectFieldTranslator.java:
240)
at
com.vercer.engine.persist.standard.AbstractStatelessObjectDatastore.update(AbstractStatelessObjectDatastore.java:
339)
at
com.vercer.engine.persist.standard.StrategyObjectDatastore.update(StrategyObjectDatastore.java:
554)
at
com.vercer.engine.persist.standard.StrategyObjectDatastore.storeOrUpdate(StrategyObjectDatastore.java:
561)
----------------------------------------

I've pulled the latest twig-persist source code into my project for
tinkering, and found some interesting stuff. First, I don't think
this is related to com.google.appengine.runtime.Request.process....
This is running in a task queue, so I think that's what that class is,
but I don't know why it's at the top of the stack there.

At first, it looked like it didn't like final fields being set
accessible, so in your Reflection.java, I tried changing the following
(on line 69):

if (Modifier.isStatic(field.getModifiers()) == false)

to

if (Modifier.isStatic(field.getModifiers()) == false &&
Modifier.isFinal(field.getModifiers()) == false)

That actually got me past the final fields in String.class, but now
it's complaining that "Reflection is not allowed on private int
java.lang.String.hash". I'm not really sure what to do past this
point.

I haven't tried creating test cases yet, but if you care to look into
it, here's what's going on.

* existing entity already stored with an @Embed'ed Set<String> set to
null
* set that @Embed'ed Set<String> with a new HashSet<String>() that
contains a single String.
* call ds.storeOrUpdate on that entity

John Patterson

unread,
Apr 13, 2010, 11:45:22 PM4/13/10
to twig-p...@googlegroups.com
Ah I see what the problem is. I need to document this better or
capture that exception and add some suggestions.

Remove the @Embed annotation and it should work. Collections of
simple types are all stored as "native" multi-valued properties. The
@Embed annotation tells Twig to break down the instances to store the
individual fields within. So in this case Twig is looking inside the
String's to store the char[] and hashcode etc which it seems is
forbidden.

I have added the check for final fields to AnnotationStrategy.stored()
so final fields are not stored (or restored). Currently it only
ignores transient fields by default.

Blake Caldwell

unread,
Apr 13, 2010, 11:48:03 PM4/13/10
to twig-p...@googlegroups.com
Appreciated. Glad i could help, and as I keep saying, at some point,
I'll start posting failed tests and patches. Thanks

Sent from my iPad

>> com.vercer.engine.persist.translator.ObjectFieldTranslator.getSortedFields(ObjectFieldTranslator.java:
>> 263)
>> at
>> com.vercer.engine.persist.translator.ObjectFieldTranslator.typesafeToProperties(ObjectFieldTranslator.java:
>> 214)
>> at
>> com.vercer.engine.persist.translator.ListTranslator.typesafeToProperties(ListTranslator.java:
>> 150)
>> at
>> com.vercer.engine.persist.translator.ObjectFieldTranslator.typesafeToProperties(ObjectFieldTranslator.java:
>> 240)
>> at
>> com.vercer.engine.persist.standard.AbstractStatelessObjectDatastore.update(AbstractStatelessObjectDatastore.java:
>> 339)
>> at
>> com.vercer.engine.persist.standard.StrategyObjectDatastore.update(StrategyObjectDatastore.java:
>> 554)
>> at
>> com.vercer.engine.persist.standard.StrategyObjectDatastore.storeOrUpdate(StrategyObjectDatastore.java:

> --
> To unsubscribe, reply using "remove me" as the subject.

John Patterson

unread,
Apr 13, 2010, 11:55:44 PM4/13/10
to twig-p...@googlegroups.com
Cool. When you make fixes/improvements just create a clone the the
source page and let me know.

Blake Caldwell

unread,
Apr 14, 2010, 12:03:34 AM4/14/10
to twig-p...@googlegroups.com
Yep. Btw, removing @Embed stopped the error, and in turn emptied a ton
of retrying task queue items.

Sent from my iPad

>>>> com.vercer.engine.persist.translator.ObjectFieldTranslator.getSortedFields(ObjectFieldTranslator.java:
>>>> 263)
>>>> at
>>>> com.vercer.engine.persist.translator.ObjectFieldTranslator.typesafeToProperties(ObjectFieldTranslator.java:
>>>> 214)
>>>> at
>>>> com.vercer.engine.persist.translator.ListTranslator.typesafeToProperties(ListTranslator.java:
>>>> 150)
>>>> at
>>>> com.vercer.engine.persist.translator.ObjectFieldTranslator.typesafeToProperties(ObjectFieldTranslator.java:
>>>> 240)
>>>> at
>>>> com.vercer.engine.persist.standard.AbstractStatelessObjectDatastore.update(AbstractStatelessObjectDatastore.java:
>>>> 339)
>>>> at
>>>> com.vercer.engine.persist.standard.StrategyObjectDatastore.update(StrategyObjectDatastore.java:
>>>> 554)
>>>> at
>>>> com.vercer.engine.persist.standard.StrategyObjectDatastore.storeOrUpdate(StrategyObjectDatastore.java:

Reply all
Reply to author
Forward
0 new messages