Ошибка NegativeArraySizeException возникает при попытке создать границу между двумя вершинами в удаленном сеансе

#scala #gremlin #janusgraph

#scala #gremlin #janusgraph

Вопрос:

Я пытаюсь добавить ребро между двумя вершинами, используя платформу gremlin scala, подключенную к удаленному серверу JanusGraph. Пока это ребро создается, я все еще получаю «org.apache.tinkerpop.shaded.kryo.Исключение KryoException: java.lang.Исключение ошибки NegativeArraySizeException»

Ребро и вершины создаются, но ошибка все еще выдается, и я не могу ее перехватить. Я использую JanusGraph 0.3.1 и пробовал с разными версиями scala gremlin (3.3, 3.4), все они приводят к одной и той же ошибке.

 val serializer = new GryoMessageSerializerV3d0(GryoMapper.build.addRegistry(TinkerIoRegistryV3d0.instance))
val cluster = Cluster.build.addContactPoint("localhost").port(8182).serializer(serializer).create
implicit val graph: ScalaGraph = EmptyGraph.instance.asScala.configure(_.withRemote(DriverRemoteConnection.using(cluster)))

val Founded = Key[String]("founded")
val Distance = Key[Int]("distance")

// create labelled vertex
val paris = graph   "Paris"

// create vertex with typed properties
val london = graph   ("London", Founded -> "43 AD")

// create labelled edges
paris --- ("OneWayRoad",  Distance -> 495) --> london
cluster.close()
  

Сообщение об ошибке, выданное во время выполнения

 15:34:02.704 [gremlin-driver-loop-1] WARN  o.a.t.g.driver.MessageSerializer - Response [PooledUnsafeDirectByteBuf(ridx: 92, widx: 92, cap: 92)] could not be deserialized by org.apache.tinkerpop.gremlin.driver.ser.AbstractGryoMessageSerializerV3d0.
org.apache.tinkerpop.shaded.kryo.KryoException: java.lang.NegativeArraySizeException
Serialization trace:
id (org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceEdge)
    at org.apache.tinkerpop.shaded.kryo.serializers.ObjectField.read(ObjectField.java:144)
    at org.apache.tinkerpop.shaded.kryo.serializers.FieldSerializer.read(FieldSerializer.java:557)
...
Caused by: java.lang.NegativeArraySizeException: null
    at org.apache.tinkerpop.shaded.kryo.io.Input.readBytes(Input.java:325)
[...]
15:34:02.705 [gremlin-driver-loop-1] ERROR o.a.t.g.d.Handler$GremlinResponseHandler - Could not process the response
io.netty.handler.codec.DecoderException: org.apache.tinkerpop.gremlin.driver.ser.SerializationException: org.apache.tinkerpop.shaded.kryo.KryoException: java.lang.NegativeArraySizeException
Serialization trace:
id (org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceEdge)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:98)
[...]
Caused by: org.apache.tinkerpop.gremlin.driver.ser.SerializationException: org.apache.tinkerpop.shaded.kryo.KryoException: java.lang.NegativeArraySizeException
Serialization trace:
id (org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceEdge)
    at org.apache.tinkerpop.gremlin.driver.ser.AbstractGryoMessageSerializerV3d0.deserializeResponse(AbstractGryoMessageSerializerV3d0.java:159)
[...]
Caused by: org.apache.tinkerpop.shaded.kryo.KryoException: java.lang.NegativeArraySizeException
Serialization trace:
id (org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceEdge)
    at org.apache.tinkerpop.shaded.kryo.serializers.ObjectField.read(ObjectField.java:144)
[...]
Caused by: java.lang.NegativeArraySizeException: null
    at org.apache.tinkerpop.shaded.kryo.io.Input.readBytes(Input.java:325)
[...]
  

Отладчик показывает мне, что ошибка выдается при создании ребра. Используя

 val edge = g.V(paris).as("a").V(london).addE("test").iterate()
  

приводит к той же ошибке.
Вот мой конфигурационный файл gremlin-server.yaml

 host: 0.0.0.0
port: 8182
scriptEvaluationTimeout: 180000
channelizer: org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer
graphs: {
  graph: conf/gremlin-server/janusgraph-cql-es-server.properties,
  ConfigurationManagementGraph: conf/janusgraph-cql-configurationgraph.properties
}
scriptEngines: {
  gremlin-groovy: {
    plugins: { org.janusgraph.graphdb.tinkerpop.plugin.JanusGraphGremlinPlugin: {},
               org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {},
               org.apache.tinkerpop.gremlin.tinkergraph.jsr223.TinkerGraphGremlinPlugin: {},
               org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {classImports: [java.lang.Math], methodImports: [java.lang.Math#*]},
               org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin: {files: [scripts/empty-sample.groovy]}}}}
serializers:
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV3d0, config: { serializeResultToString: true }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  # Older serialization versions for backwards compatibility:
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoLiteMessageSerializerV1d0, config: {ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GryoMessageSerializerV1d0, config: { serializeResultToString: true }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV2d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerGremlinV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }}
  - { className: org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV1d0, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }}
processors:
  - { className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, config: { sessionTimeout: 28800000 }}
  - { className: org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor, config: { cacheExpirationTime: 600000, cacheMaxSize: 1000 }}
metrics: {
  consoleReporter: {enabled: true, interval: 180000},
  csvReporter: {enabled: true, interval: 180000, fileName: /tmp/gremlin-server-metrics.csv},
  jmxReporter: {enabled: true},
  slf4jReporter: {enabled: true, interval: 180000},
  gangliaReporter: {enabled: false, interval: 180000, addressingMode: MULTICAST},
  graphiteReporter: {enabled: false, interval: 180000}}
maxInitialLineLength: 4096
maxHeaderSize: 8192
maxChunkSize: 8192
maxContentLength: 65536
maxAccumulationBufferComponents: 1024
resultIterationBatchSize: 64
writeBufferLowWaterMark: 32768
writeBufferHighWaterMark: 65536
  

Ошибка не появляется при работе без использования удаленного сервера:

 implicit val graph: ScalaGraph = EmptyGraph.instance
  

работает нормально.

Ответ №1:

Эта проблема обычно указывает на проблему совместимости с Gryo, которая обычно возникает при смешивании версий TinkerPop. По большей части Gryo имеет тенденцию быть обратно совместимым между версиями, таким образом, Gryo 1.0 из 3.3.3 будет работать с 3.3.4, но бывают случаи, когда это не всегда верно (например, обнаружена ошибка в ядре формата, и необходимо кардинальное изменение).)

TinkerPop рекомендует при использовании Gryo согласовать версию TinkerPop на сервере с версией клиента. Итак, JanusGraph 0.3.1 использует TinkerPop 3.3.3, поэтому ваша версия Gremlin Scala должна быть 3.3.3.x (я почти уверен, что Gremlin Scala привязывает свои первые три номера версий к номерам TinkerPop). Кажется, вы уже пробовали это, поэтому давайте рассмотрим вашу конфигурацию.

Я отмечаю, что вы добавили TinkerIoRegistryV3d0 но поскольку вы используете JanusGraph, вам также может потребоваться добавить их пользовательский IoRegistry :

 GryoMessageSerializerV3d0(GryoMapper.build.addRegistry(JanusGraphIoRegistry.getInstance()))
  

Вы можете добавить TinkerIoRegistryV3d0 , если этого требует ваш вариант использования — обычно это полезно только для возврата подграфов. Если ничто из этого не устраняет проблему, то моим единственным предложением было бы значительно упростить: удалите все конфигурации сериализатора из конфигурации сервера Gremlin, кроме той, которую вы используете, убедитесь, что вы можете подключиться к ней с помощью нескольких простых сценариев, настраивающих ваш драйвер, используя только консоль Gremlin, и обратите внимание на то, что это за конфигурация, чтобы заставить соединение работать, чтобы вы могли перенести конфигурацию в Gremlin Scala.

Я вижу, что в настоящее время вы изолировали проблему от:

 val edge = g.V(paris).as("a").V(london).addE("test").iterate()
  

Обратите внимание, что этот код не делает именно то, что, я думаю, вы хотите по нескольким причинам:

  1. Если вы хотите вернуть ребро, вам нужно next() а не iterate()
  2. Это не добавляет ребро между «парижем» и «Лондоном» — это добавляет самоссылающееся ребро к «лондону». Вам нужно указать from() или to() после addE() .

Я надеюсь, что что-то там поможет.