为什么不能用 none() 步骤反序列化 gremlin.process.traversal.Bytecode?

Why cant deserialize gremlin.process.traversal.Bytecode with none() step?

我尝试用none()步反序列化遍历查询,但似乎不支持这种反序列化

Tinkerpop 版本为 3.5.0

这是一个失败的代码

 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);
         }
     }
 }

结果我捕获了这样一个异常:

    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)

如果您只是从 defaultGraphTraversal.addV("A").property("mac", "1");

中删除评论

代码会起作用

那么为什么不支持这种反序列化?

非常感谢!!!

我建议您不要尝试直接构建 DefaultGraphTraversal,而是从 GraphTraversalSource(即您的 g)生成它们。我想它可以工作,但是 class 确实不是为用户直接使用而设计的,因此 API 可能会从您的下方移出,或者初始化行为可能会改变并给您带来麻烦。

从某种意义上说,直接构造是导致问题的原因,因为您构建的遍历字节码实际上并不有效:

gremlin> defaultGraphTraversal = new DefaultGraphTraversal<>(graph.traversal());[]
gremlin> defaultGraphTraversal.iterate();[]
gremlin> bytecode = defaultGraphTraversal.getBytecode()
==>[[], [none()]]

由于您不是从 GraphTraversalSource 生成的,因此您最终构建了一个没有任何源指令的遍历(即上述字节码输出中的第一个 [])。否则,JavaTranslator 会沿着与预期不同的路径前进,并尝试在 GraphTraversalSource 而不是 Traversal 上调用 none()。当您取消注释调用 addV() 的行时,您显然解决了这个问题,因为这是一个可以作为生成的正确开始步骤,而 none() 不能。