[ 
https://issues.apache.org/jira/browse/TINKERPOP-1230?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15446736#comment-15446736
 ] 

stephen mallette commented on TINKERPOP-1230:
---------------------------------------------

[~mpollmeier] There is a standard method for serializing lambdas to bytecode 
that will apply for all remoting over GLVs. I don't think we'll implement any 
further than that:

http://tinkerpop.apache.org/docs/3.2.2-SNAPSHOT/reference/#_the_lambda_solution

I guess this issue was about serializing purely on the JVM. I looked at your 
sample repo a while back, but I must have forgotten to comment. That approach 
will work, because the code for the predicate you serialized will deserialized 
by the same program - even on two different JVMs. In other words the code for 
the predicate is available to both JVMs in the LambdaSerialisation.java file, 
so - no problem. But if you think about how Gremlin Server works, if you used 
that program to generate the .ser file and then send that file to Gremlin 
Server, it can try to deserialize, but it won't have the predicate code and it 
will fail. The bottom line is that java serialization does not serialize "the 
code" just "data".

You can simulate that pretty easily if you run your project to generate 
lambd.ser, copy the whole project, edit LambdaSerialisation.java and delete the 
Predicate, the run {{LambdaDeserialisation}} from that project on the .ser 
file. It will fail with:

{code}
[INFO] --- exec-maven-plugin:1.4.0:java (default-cli) @ jvm-serialisation ---
reading lambda from lambda.ser
[WARNING] 
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:293)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: MyPredicate
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:348)
        at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:628)
        at 
java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
        at 
java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
        at LambdaDeserialisation.main(LambdaSerialisation.java:10)
        ... 6 more
{code}

So unless you are suggesting as part of your solution here that Gremlin Server 
have the "Predicate" on the server and on the client or something along those 
lines, I'm not sure I see how this will work. Or perhaps i'm missing something 
else?

[~okram] can you update the GLV tutorial about lambdas please?

> Serialising lambdas for RemoteGraph
> -----------------------------------
>
>                 Key: TINKERPOP-1230
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-1230
>             Project: TinkerPop
>          Issue Type: Improvement
>          Components: driver, server
>    Affects Versions: 3.1.1-incubating
>            Reporter: Michael Pollmeier
>            Assignee: Marko A. Rodriguez
>            Priority: Minor
>             Fix For: 3.2.2
>
>
> I just made an attempt to serialise lambdas and send them via the 
> RemoteGraph. I didn't quite get there, but wanted to share my findings: 
> * it's possible to serialise lambdas on the jvm by just extending 
> `Serializable`:
> http://stackoverflow.com/questions/22807912/how-to-serialize-a-lambda/22808112#22808112
> * sending a normal predicate doesn't work (this is a Scala REPL but it should 
> be pretty easy to convert this to java/groovy)
>   val g = RemoteGraph.open("conf/remote-graph.properties").traversal()
>   val pred1 = new java.util.function.Predicate[Traverser[Vertex]] { def 
> test(v: Traverser[Vertex]) = true }
>   g.V().filter(pred1).toList 
> // java.lang.RuntimeException: java.io.NotSerializableException: $anon$1
>                              // on server: nothing
>                              
> * simply adding Serializable let's us send it over the wire, but the server 
> doesn't deserialise it
>   val pred2 = new java.util.function.Predicate[Traverser[Vertex]] with 
> Serializable { def test(v: Traverser[Vertex]) = true }
>   g.V().filter(pred2).toList 
>   // on server: [WARN] OpExecutorHandler - Could not deserialize the 
> Traversal instance
>         org.apache.tinkerpop.gremlin.server.op.OpProcessorException: Could 
> not deserialize the Traversal instance
>         at 
> org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor.iterateOp(TraversalOpProcessor.java:135)
>         at 
> org.apache.tinkerpop.gremlin.server.handler.OpExecutorHandler.channelRead0(OpExecutorHandler.java:68)
>   // on client: 
> org.apache.tinkerpop.gremlin.driver.exception.ResponseException: $anon$1 



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to