I try to deserialize traversal query with none()
step, but it seems like there is no support for such deserialization
Tinkerpop version is 3.5.0
Here is a code that fail
import org.apache.tinkerpop.gremlin.jsr223.JavaTranslator;
import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.io.GraphReader;
import org.apache.tinkerpop.gremlin.structure.io.GraphWriter;
import org.apache.tinkerpop.gremlin.structure.io.Mapper;
import org.apache.tinkerpop.gremlin.structure.io.graphson.*;
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class GraphExperimental {
private static final Mapper<ObjectMapper> GRAPHSON_MAPPER_3_0 = GraphSONMapper.build()
.version(GraphSONVersion.V3_0)
.typeInfo(TypeInfo.PARTIAL_TYPES)
.addCustomModule(GraphSONXModuleV3d0.build().create(false))
.create();
private static final GraphWriter GRAPHSON_WRITER_3_0 = GraphSONWriter.build()
.mapper(GRAPHSON_MAPPER_3_0)
.create();
private static final GraphReader GRAPHSON_READER_3_0 = GraphSONReader.build()
.mapper(GRAPHSON_MAPPER_3_0)
.create();
private GraphExperimental() {
}
public static void main(String[] args) {
Graph graph = TinkerGraph.open();
DefaultGraphTraversal<Object, Object> defaultGraphTraversal = new DefaultGraphTraversal<>(graph.traversal());
// defaultGraphTraversal.addV("A").property("mac", "1");
defaultGraphTraversal.iterate();
Bytecode bytecode = defaultGraphTraversal.getBytecode();
String serialize = writeValueAsString(bytecode);
Graph anotherGraph = TinkerGraph.open();
GraphTraversalSource anotherTraversal = anotherGraph.traversal();
Bytecode bytecodeDeserialized = readValue(serialize, Bytecode.class);
Traversal.Admin<?, ?> translate = JavaTranslator.of(anotherTraversal).translate(bytecodeDeserialized);
}
public static <T> T readValue(String value, Class<? extends T> clazz) {
try (ByteArrayInputStream in = new ByteArrayInputStream(value.getBytes("UTF-8"))) {
return GRAPHSON_READER_3_0.readObject(in, clazz);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String writeValueAsString(Object value) {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
GRAPHSON_WRITER_3_0.writeObject(out, value);
return out.toString("UTF-8");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
In result i catch such an exception:
Exception in thread "main" java.lang.IllegalStateException: Could not locate method: GraphTraversalSource.none()
at org.apache.tinkerpop.gremlin.jsr223.JavaTranslator.invokeMethod(JavaTranslator.java:207)
at org.apache.tinkerpop.gremlin.jsr223.JavaTranslator.translate(JavaTranslator.java:89)
at example.GraphExperimental.main(GraphExperimental.java:63)
If you just remove comment from defaultGraphTraversal.addV("A").property("mac", "1");
The code will work
So why does there is no support for such a deserialization?
Thanks a lot!!!
I would recommend that you not attempt to construct a DefaultGraphTraversal
directly and to instead spawn them from a GraphTraversalSource
(i.e. your g
). I suppose it can work, but that class really wasn't designed to be utilized by users directly so the API could shift out from under you or an initialization behavior could change and cause you trouble.
In a sense, the direct construction is what is causing the problem here as you build traversal bytecode that isn't really valid:
gremlin> defaultGraphTraversal = new DefaultGraphTraversal<>(graph.traversal());[]
gremlin> defaultGraphTraversal.iterate();[]
gremlin> bytecode = defaultGraphTraversal.getBytecode()
==>[[], [none()]]
Since you don't spawn from a GraphTraversalSource
you end up constructing a traversal that doesn't have any source instructions (i.e. the first []
in the above bytecode output). Without that, the JavaTranslator
heads down a different path than it expects and tries to call none()
on a GraphTraversalSource
rather than on a Traversal
. You obviously solve this problem when you uncomment that line that calls addV()
because that is a proper start step that can act as a spawn whereas none()
cannot.