Open ekk-cb opened 3 years ago
As far as I knew it didn't either, but when I tried locking down scala-js-fiddle with a security manager that prohibited reflection, play-json broke =( I don't know how or why, but I'm pretty sure it uses reflection for serialization. All I was trying to do was serialize Seq
s and String
s to json and send them to the client
Original Author:lihaoyi Original Author:ekk-cb
That’s weird... Maybe @jroper, @mandubian or @jto could comment on that? Otherwise I’d appear to be spreading fud...
Original Author:stanch Original Author:ekk-cb
FWIW here's a repro
// project/build.sbt
addSbtPlugin("io.spray" % "sbt-revolver" % "0.7.2")
// build.sbt
resolvers += "Typesafe Repo" at "http://repo.typesafe.com/typesafe/releases/"
scalaVersion := "2.10.2"
libraryDependencies += "play" % "play_2.10" % "2.1.0"
Revolver.settings
// Run.scala
import play.api.libs.json._
object Run{
def main(args: Array[String]): Unit = {
println("Hello")
System.setSecurityManager(new SecurityManager());
println(Json.stringify(Json.obj("name" -> "omg")))
}
}
Output:
haoyi-mbp:test haoyi$ sbt
[info] Loading global plugins from /Users/haoyi/.sbt/0.13/plugins
[info] Loading project definition from /Users/haoyi/Dropbox (Personal)/Workspace/test/project
[info] Set current project to test (in build file:/Users/haoyi/Dropbox%20(Personal)/Workspace/test/)
> re-start
[info] Application test not yet started
[info] Starting application test in the background ...
test Starting Run.main()
[success] Total time: 0 s, completed Jul 20, 2014 4:59:34 PM
> test Hello
test[ERROR] java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)
test[ERROR] at java.security.AccessControlContext.checkPermission(AccessControlContext.java:376)
test[ERROR] at java.security.AccessController.checkPermission(AccessController.java:549)
test[ERROR] at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
test[ERROR] at java.lang.SecurityManager.checkMemberAccess(SecurityManager.java:1662)
test[ERROR] at java.lang.Class.checkMemberAccess(Class.java:2195)
test[ERROR] at java.lang.Class.getDeclaredMethods(Class.java:1826)
test[ERROR] at org.codehaus.jackson.map.introspect.AnnotatedClass._addMemberMethods(AnnotatedClass.java:620)
test[ERROR] at org.codehaus.jackson.map.introspect.AnnotatedClass.resolveMemberMethods(AnnotatedClass.java:413)
test[ERROR] at org.codehaus.jackson.map.introspect.BasicClassIntrospector.classWithCreators(BasicClassIntrospector.java:185)
test[ERROR] at org.codehaus.jackson.map.introspect.BasicClassIntrospector.collectProperties(BasicClassIntrospector.java:157)
test[ERROR] at org.codehaus.jackson.map.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:96)
test[ERROR] at org.codehaus.jackson.map.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:16)
test[ERROR] at org.codehaus.jackson.map.SerializationConfig.introspect(SerializationConfig.java:973)
test[ERROR] at org.codehaus.jackson.map.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:251)
test[ERROR] at org.codehaus.jackson.map.ser.StdSerializerProvider._createUntypedSerializer(StdSerializerProvider.java:782)
test[ERROR] at org.codehaus.jackson.map.ser.StdSerializerProvider._createAndCacheUntypedSerializer(StdSerializerProvider.java:735)
test[ERROR] at org.codehaus.jackson.map.ser.StdSerializerProvider.findValueSerializer(StdSerializerProvider.java:344)
test[ERROR] at org.codehaus.jackson.map.ser.StdSerializerProvider.findTypedValueSerializer(StdSerializerProvider.java:420)
test[ERROR] at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:601)
test[ERROR] at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256)
test[ERROR] at org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:1613)
test[ERROR] at play.api.libs.json.JacksonJson$.generateFromJsValue(JsValue.scala:483)
test[ERROR] at play.api.libs.json.Json$.stringify(Json.scala:35)
test[ERROR] at Run$.main(Run.scala:7)
test[ERROR] at Run.main(Run.scala)
test[ERROR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
test[ERROR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
test[ERROR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
test[ERROR] at java.lang.reflect.Method.invoke(Method.java:597)
test[ERROR] at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:71)
test[ERROR] at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
test[ERROR] at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:139)
test[ERROR] at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:71)
test[ERROR] at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:139)
test[ERROR] at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:28)
test[ERROR] at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:45)
test[ERROR] at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:35)
test[ERROR] at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:45)
test[ERROR] at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:74)
test[ERROR] at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
test[ERROR] at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
test[ERROR] at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
test ... finished with exit code 1
I mean, I would also like it if something simple like "converting JSON structure to string" didn't require reflection. If it didn't though, I probably wouldn't have made this library in the first place =P
Original Author:lihaoyi Original Author:ekk-cb
Dayum! This is beyond awful :( On the other hand, why not just create your own Json.stringify
?
Original Author:stanch Original Author:ekk-cb
I did, but why not create my own JSON ast too? It's like 10 lines of code. So I did, and that's the AST that sits underneath uPickle's serialization format =P No point depending on the entirely of play-json and all its stuff just for a 10-line JSON ast
Original Author:lihaoyi Original Author:ekk-cb
Fair enough! It just discourages me that there are already around 10 JSON libraries in the ecosystem, and each of them has approximately one killer feature: dijon uses Dynamic
, argonaut has cool zippers, spray-json is “simple” and typeclass-based, play-json has macros for generation of typeclass instances and rule composition, json4s has “universal” AST, rapture has json
string interpolator, scala-pickling is “boilerplate-free”, etc — but unfortunately every library brings in some downsides in whatever it doesn’t strive to do well, like some don’t use typeclasses, some use a crappy parser/serializer, etc. Don’t get me wrong, competition is cool, but right now it’s more like the Tower of Babel :) Maybe it would be helpful to separate the steps (parsing, AST, manipulation, validation, morphisms) and cultivate some de-facto standards. json4s seemed to be a good effort, but for some reason it isn’t widely adopted by library writers...
P.S. Have you considered changing your name to Li “µ” Haoyi? :)
Original Author:stanch Original Author:ekk-cb
The issue isn't play-json but jackson... When play2.1 was released, it was the fastest json serializer...
Original Author:mandubian Original Author:ekk-cb
Jackson is used for parsing only. As far as I know, that does not employ reflection.
ID: 4 Original Author: stanch ID: 4 Original Author: ekk-cb