Issue Details (XML | Word | Printable)

Key: XSTR-566
Type: Bug Bug
Status: Open Open
Priority: Major Major
Assignee: Joerg Schaible
Reporter: Paul Hammant
Votes: 5
Watchers: 7
Operations

If you were logged in you would be able to see more operations.
XStream

AppEngine Compatibility.

Created: 16/Apr/09 12:52 PM   Updated: 26/Jan/10 03:30 AM
Return to search
Component/s: Converters
Affects Version/s: 1.3.1
Fix Version/s: None

File Attachments: 1. Text File faster_safer.patch (10 kB)
2. Text File gae-xstream.patch (12 kB)
3. Text File gae-xstream2.patch (9 kB)
4. Text File gae3-xstream.patch (4 kB)
5. Text File gae4-xstream.patch (4 kB)
6. Java Archive File xstream-1.3.2-SNAPSHOT.jar (422 kB)
7. Java Archive File xstream-1.4-SNAPSHOT-GAE.jar (443 kB)

Issue Links:
Related
 


 Description  « Hide

I've been using this for a month now, and I am happy with it. Joe does not like it though, he suggests there is potential for race.

As suggested, I will try more permutations to register a PureJavaReflectionProvider exclusively & report back.



Sort Order: Ascending order - Click to sort in descending order
Joerg Schaible added a comment - 16/Apr/09 04:24 PM

Paul, I think this was the wrong patch. IMHO the second one, you've sent to the list makes this one obsolete anyway.


Paul Hammant added a comment - 30/Jun/09 07:07 AM

gae-xstream.patch -

Adds AppEngineXStream.java
Refactors XStream a little (more to follow if generally approved)

Thoughts?


Paul Hammant added a comment - 01/Jul/09 11:16 AM

gae-xstream2.patch

same idea, refactored to mean less code in subclass


Sean Sullivan added a comment - 26/Jul/09 11:50 PM

I am trying to use XStream 1.4 SNAPSHOT jar on Google AppEngine. Creating an XStream object causes this:

Caused by: java.lang.SecurityException: java.lang.IllegalAccessException: Reflection is not allowed on private java.lang.String java.text.AttributedCharacterIterator$Attribute.name
at com.google.apphosting.runtime.security.shared.intercept.java.lang.reflect.Field_.setAccessible(Field_.java:156)
at com.thoughtworks.xstream.converters.reflection.FieldDictionary.buildMap(FieldDictionary.java:147)
at com.thoughtworks.xstream.converters.reflection.FieldDictionary.fieldsFor(FieldDictionary.java:75)
at com.thoughtworks.xstream.converters.reflection.AbstractAttributedCharacterIteratorAttributeConverter.readResolve(AbstractAttributedCharacterIteratorAttributeConverter.java:83)
at com.thoughtworks.xstream.converters.reflection.AbstractAttributedCharacterIteratorAttributeConverter.<init>(AbstractAttributedCharacterIteratorAttributeConverter.java:52)
at com.thoughtworks.xstream.converters.extended.TextAttributeConverter.<init>(TextAttributeConverter.java:33)
at com.thoughtworks.xstream.XStream.setupConverters(XStream.java:658)
at com.thoughtworks.xstream.XStream.<init>(XStream.java:437)
at com.thoughtworks.xstream.XStream.<init>(XStream.java:362)
at com.thoughtworks.xstream.XStream.<init>(XStream.java:348)
at foobar.internal.xstream.XStreamFactory$1.<init>(XStreamFactory.java:27)
at foobar.internal.xstream.XStreamFactory.createClientXStream(XStreamFactory.java:27)

Are there any plans to commit Paul Hammant's patch (gae-xstream2.patch) ?


Joerg Schaible added a comment - 30/Jul/09 07:01 AM

@Sean: Did you see Paul's and my conversation on the dev list? Actually I don't like to add another specialized facade, but improve the runtime behaviour of the XStream facade itself. However, I don't know currently how I can detect that I am running GAE, since the environment identifies itself as standard Sun 1.6 JVM.


Sean Sullivan added a comment - 02/Aug/09 10:52 PM

I examined Paul Hammant's patch (gae2-xstream.patch) and incoporated the code into a new patch.

Using my patch, I built a custom XStream jar and deployed it in an App Engine application. I have not found any problems (yet).

Please examine gae3-xstream.patch and let me know if the code is acceptable.


Barak added a comment - 17/Aug/09 05:36 AM

I'm tried the attached jar, and it failed on local development server. Trying to convert some JSF component to XML raised that:

java.security.AccessControlException: access denied (java.io.SerializablePermission enableSubclassImplementation)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
at java.security.AccessController.checkPermission(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:128)
at java.io.ObjectOutputStream.<init>(ObjectOutputStream.java:253)
at com.thoughtworks.xstream.core.util.CustomObjectOutputStream.<init>(CustomObjectOutputStream.java:58)
at com.thoughtworks.xstream.core.util.CustomObjectOutputStream.getInstance(CustomObjectOutputStream.java:33)
at com.thoughtworks.xstream.converters.reflection.SerializableConverter.doMarshal(SerializableConverter.java:214)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshallField(AbstractReflectionConverter.java:157)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.writeField(AbstractReflectionConverter.java:148)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.visit(AbstractReflectionConverter.java:118)
at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:129)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:100)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshallField(AbstractReflectionConverter.java:157)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.writeField(AbstractReflectionConverter.java:148)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.visit(AbstractReflectionConverter.java:118)
at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:129)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:100)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.writeItem(AbstractCollectionConverter.java:64)
at com.thoughtworks.xstream.converters.collections.MapConverter.marshal(MapConverter.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshallField(AbstractReflectionConverter.java:157)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.writeField(AbstractReflectionConverter.java:148)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.visit(AbstractReflectionConverter.java:118)
at com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider.visitSerializableFields(PureJavaReflectionProvider.java:129)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:100)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:58)
at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:78)
at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:63)
at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:98)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:38)
at com.thoughtworks.xstream.XStream.marshal(XStream.java:841)
at com.thoughtworks.xstream.XStream.marshal(XStream.java:830)
at com.thoughtworks.xstream.XStream.toXML(XStream.java:805)
at com.thoughtworks.xstream.XStream.toXML(XStream.java:793)
at com.me.jsf.QueryBeanV4.setUiData(QueryBeanV4.java:375)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.myfaces.el.PropertyResolverImpl.setProperty(PropertyResolverImpl.java:410)
at org.apache.myfaces.el.PropertyResolverImpl.setValue(PropertyResolverImpl.java:177)
at org.apache.myfaces.el.ValueBindingImpl.setValue(ValueBindingImpl.java:278)
at org.apache.myfaces.shared_impl.util.RestoreStateUtils.recursivelyHandleComponentReferencesAndSetValid(RestoreStateUtils.java:86)
at org.apache.myfaces.shared_impl.util.RestoreStateUtils.recursivelyHandleComponentReferencesAndSetValid(RestoreStateUtils.java:57)
at org.apache.myfaces.shared_impl.util.RestoreStateUtils.recursivelyHandleComponentReferencesAndSetValid(RestoreStateUtils.java:94)
at org.apache.myfaces.shared_impl.util.RestoreStateUtils.recursivelyHandleComponentReferencesAndSetValid(RestoreStateUtils.java:57)
at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:98)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:105)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:80)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:143)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:124)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:54)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:313)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
at org.mortbay.jetty.Server.handle(Server.java:313)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:844)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:644)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396)
at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)

Is there some configuration I missed in order to make xstream working with gae?


Sean Sullivan added a comment - 08/Sep/09 01:41 AM

Jörg,

Have you had time to review the patch that I submitted on August 2nd?

https://jira.codehaus.org/secure/attachment/43548/gae3-xstream.patch


Joerg Schaible added a comment - 08/Sep/09 02:40 AM

@Sean, yes I had a look, that's exactly what I had in mind in first place. It's just that I am currently in the middle of the work for a different area of XStream and I had no time to come back to GAE compatibility. The only thing that itches me still is, that this looks all like a standard environment with a SecurityManager similar using XStream in an applet. In this case it might be possible as alternative to check the runtime permissions in a general way. Barak's issue with the SerializationConverter makes me think about this alternative.


John Nichol added a comment - 16/Sep/09 05:37 PM

Any progress on this issue? I have patched 1.3.1-src download of XStream with the gae3-xstream.patch and it doesn't seem to work with app engine 1.2.5. The exception is below. Basically I am not allowed to create a CustomObjectInputStream due to permissioning issues.

I am attempting to parse an XML file containing a list of XStreamed data objects.

Thanks,

John

java.security.AccessControlException: access denied (java.io.SerializablePermission enableSubclassImplementation)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323)
at java.security.AccessController.checkPermission(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:139)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:303)
at com.thoughtworks.xstream.core.util.CustomObjectInputStream.<init>(CustomObjectInputStream.java:62)
at com.thoughtworks.xstream.XStream.createObjectInputStream(XStream.java:1501)
at com.thoughtworks.xstream.XStream.createObjectInputStream(XStream.java:1481)
at com.cloudscapesolutions.wavacalculator.server.UploadFileServlet.loadData(UploadFileServlet.java:71)
at com.cloudscapesolutions.wavacalculator.server.UploadFileServlet.service(UploadFileServlet.java:51)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:121)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:712)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at com.google.apphosting.utils.jetty.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:54)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:313)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
at org.mortbay.jetty.Server.handle(Server.java:313)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:844)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:644)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396)
at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)


Joerg Schaible added a comment - 17/Sep/09 02:23 AM

Hi John,

as long as you cannot grant more permissions for an app on GAE, it is not possible to use the SerializationProvider nor will the XStream.createObjectInputStream/XStream.createObjectOutputStream work. However, this is nothing XStream can do about - except for not registering the SerializationConverter also.

  • Jörg

John Nichol added a comment - 17/Sep/09 04:20 AM

Jörg,

I understand the problem and can see its not straightforward to fix.

In case its useful to anyone else I will point out that if its possible for your application if you change from using an Input/Output
stream approach with XStream and instead use toXml/fromXml on lists/sets of objects you can workaround the GAE security problem.
I assume you will still need to apply one of the patches attached to this case, I have tested with the gae3-xstream.patch and managed to
upload a list of objects created with xstream.toXml() and then converted back to objects in GAE with xstream.fromXml(inputStream) where the inputStream is a standard input stream obtained from an HTTPRequest.

Pity XStream and GAE can't work together better yet, hopefully as GAE evolves it will be possible. XStream is an incredibly useful library.

Cheers, John


DEWITTE Pierre-Alban added a comment - 01/Dec/09 01:21 AM - edited

Hi all,

I just improve the patch (file gae4-xstream.patch and xstream-1.4-SNAPSHOT-GAE.jar) for XStream 1.4 version. The jar attach to this issue is working in a GAE App.

Best regards


Thierry Boileau added a comment - 26/Jan/10 03:30 AM

I've just tested the 1.4 patch, and I was unable to convert an XML representation to an object instance, having the following exception: java.lang.NoClassDefFoundError: sun.reflect.ReflectionFactory is a restricted class.

I'm using gae 1.3.

Best regards