JanusGraph / JanusGraph/janusgraph

Consecutive creation and deletion of Template/graph on remote server causes NullPointerException server side

Open
#1,622 2 comments 2 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
5.8k
Forks
1.2k
Avg merge
13h 53m
Merged PRs (30d)
6

Description

Hi all,

First of all, I would like to state that I am somewhat new to JanusGraph and might have missed something obvious (but I do not think so).

While writing some unit tests, I find myself creating and deleting many graphs with the `storage.backend=inmemory` configuration.
The few first graph creations and deletions of graph and associated templates unfold correctly, but after a while, the commands start to return errors.

In my code, I create the graph itself by injecting the following command via the java gremlin driver using ClusterClient.submit() (with remote connection):
```java
ConfiguredGraphFactory.removeTemplateConfiguration();
map=new HashMap();map.put("storage.backend","inmemory");ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));ConfiguredGraphFactory.create("testgraph2");ConfiguredGraphFactory.removeTemplateConfiguration();
```

Here is a section of my console (and underneath the associated server trace) using the same script:
```
bin/gremlin.sh

\,,,/
(o o)
-----oOOo-(3)-oOOo-----
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/home/illioren/Downloads/janusgraph-0.3.1-hadoop2/lib/slf4j-log4j12-1.7.12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/home/illioren/Downloads/janusgraph-0.3.1-hadoop2/lib/logback-classic-1.1.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
plugin activated: janusgraph.imports
plugin activated: tinkerpop.server
plugin activated: tinkerpop.gephi
plugin activated: tinkerpop.utilities
09:58:18 WARN org.apache.hadoop.util.NativeCodeLoader - Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
plugin activated: tinkerpop.hadoop
plugin activated: tinkerpop.spark
plugin activated: tinkerpop.tinkergraph
gremlin> :remote connect tinkerpop.server conf/remote.yaml session
==>Configured localhost/127.0.0.1:8182-[97c3cc46-57f5-4fe7-afdb-297b788521cb]
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [localhost/127.0.0.1:8182]-[97c3cc46-57f5-4fe7-afdb-297b788521cb] - type ':remote console' to return to local mode
gremlin> ConfiguredGraphFactory.removeTemplateConfiguration();map=new HashMap();map.put("storage.backend","inmemory");ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));ConfiguredGraphFactory.create("testgraph2");ConfiguredGraphFactory.removeTemplateConfiguration();
==>null
gremlin> ConfiguredGraphFactory.getGraphNames()ConfiguredGraphFactory.getGraphNames()
Exception evaluating property 'ConfiguredGraphFactory' for java.util.HashSet, Reason: groovy.lang.MissingPropertyException: No such property: ConfiguredGraphFactory for class: java.lang.String
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> ConfiguredGraphFactory.getGraphNames()
==>testgraph2
gremlin> ConfiguredGraphFactory.drop("testgraph2")
==>null
gremlin> ConfiguredGraphFactory.removeTemplateConfiguration();map=new HashMap();map.put("storage.backend","inmemory");ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));ConfiguredGraphFactory.create("testgraph2");ConfiguredGraphFactory.removeTemplateConfiguration();
==>null
gremlin> ConfiguredGraphFactory.removeTemplateConfiguration();map=new HashMap();map.put("storage.backend","inmemory");ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));ConfiguredGraphFactory.create("testgraph2");ConfiguredGraphFactory.removeTemplateConfiguration();
Configuration for graph testgraph2 already exists.
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> ConfiguredGraphFactory.removeTemplateConfiguration();map=new HashMap();map.put("storage.backend","inmemory");ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));ConfiguredGraphFactory.create("testgraph2");ConfiguredGraphFactory.removeTemplateConfiguration();
Configuration for graph testgraph2 already exists.
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> ConfiguredGraphFactory.drop("testgraph2")
==>null
gremlin> ConfiguredGraphFactory.removeTemplateConfiguration();map=new HashMap();map.put("storage.backend","inmemory");ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));ConfiguredGraphFactory.create("testgraph2");ConfiguredGraphFactory.removeTemplateConfiguration();
==>null
gremlin> ConfiguredGraphFactory.drop("testgraph2")
org.apache.tinkerpop.gremlin.jsr223.console.RemoteException
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> ConfiguredGraphFactory.drop("testgraph2")
org.apache.tinkerpop.gremlin.jsr223.console.RemoteException
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> ConfiguredGraphFactory.getGraphNames()
==>testgraph2
gremlin> ConfiguredGraphFactory.drop("testgraph2")
org.apache.tinkerpop.gremlin.jsr223.console.RemoteException
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> ConfiguredGraphFactory.drop("testgraph2")
org.apache.tinkerpop.gremlin.jsr223.console.RemoteException
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> ConfiguredGraphFactory.drop("testgraph")
org.apache.tinkerpop.gremlin.jsr223.console.RemoteException
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> ConfiguredGraphFactory.drop("testgraph2")
org.apache.tinkerpop.gremlin.jsr223.console.RemoteException
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> ConfiguredGraphFactory.getGraphNames()
==>testgraph2
gremlin> ConfiguredGraphFactory.removeTemplateConfiguration();map=new HashMap();map.put("storage.backend","inmemory");ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));ConfiguredGraphFactory.create("testgraph2");ConfiguredGraphFactory.removeTemplateConfiguration();
Configuration for graph testgraph2 already exists.
Type ':help' or ':h' for help.
Display stack trace? [yN]
gremlin> ConfiguredGraphFactory.drop("testgraph2")
org.apache.tinkerpop.gremlin.jsr223.console.RemoteException
Type ':help' or ':h' for help.
Display stack trace? [yN]
```

for each org.apache.tinkerpop.gremlin.jsr223.console.RemoteException following a ConfiguredGraphFactory.drop("testgraph2") command, the servers produces the following trace:
```console
akmh_janusgraph_1 | 182325 [gremlin-server-session-1] WARN org.apache.tinkerpop.gremlin.server.op.AbstractEvalOpProcessor - Exception processing a script on request [RequestMessage{, requestId=a5b52250-f070-4428-bc2f-a219a05b7bae, op='eval', processor='session', args={gremlin=ConfiguredGraphFactory.drop("testgraph2"), session=97c3cc46-57f5-4fe7-afdb-297b788521cb, bindings={}, manageTransaction=false, batchSize=64}}].
akmh_janusgraph_1 | java.lang.NullPointerException
akmh_janusgraph_1 | at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:210)
akmh_janusgraph_1 | at org.janusgraph.core.JanusGraphFactory.drop(JanusGraphFactory.java:199)
akmh_janusgraph_1 | at org.janusgraph.core.ConfiguredGraphFactory.drop(ConfiguredGraphFactory.java:160)
akmh_janusgraph_1 | at org.janusgraph.core.ConfiguredGraphFactory$drop$3.call(Unknown Source)
akmh_janusgraph_1 | at Script8.run(Script8.groovy:1)
akmh_janusgraph_1 | at org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine.eval(GremlinGroovyScriptEngine.java:690)
akmh_janusgraph_1 | at org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine.eval(GremlinGroovyScriptEngine.java:395)
akmh_janusgraph_1 | at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:233)
akmh_janusgraph_1 | at org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor.lambda$eval$0(GremlinExecutor.java:263)
akmh_janusgraph_1 | at java.util.concurrent.FutureTask.run(FutureTask.java:266)
akmh_janusgraph_1 | at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
akmh_janusgraph_1 | at java.util.concurrent.FutureTask.run(FutureTask.java:266)
akmh_janusgraph_1 | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
akmh_janusgraph_1 | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
akmh_janusgraph_1 | at java.lang.Thread.run(Thread.java:748)
```

The server seems to be confused regarding the existence of my graph. And this does not seem to settle regardless how much time I wait between commands and/or restart of my local gremlin console. The graph being configured with `storage.backend=inmemory`, the problem temporarily appearers after restarting the server.

The session pre-empting the restart that yielded the traces above displayed a similar problem but with the existence of the `root.storage.backend` argument within my creation command:
```
gremlin> ConfiguredGraphFactory.removeTemplateConfiguration();map=new HashMap();map.put("storage.backend","inmemory");ConfiguredGraphFactory.createTemplateConfiguration(new MapConfiguration(map));ConfiguredGraphFactory.create("testgraph2");ConfiguredGraphFactory.removeTemplateConfiguration();
Need to set configuration value: root.storage.backend
Type ':help' or ':h' for help.
Display stack trace? [yN]
```
And the sessions prior to this returned errors telling me that my configuration object was empty, or that a template was already existing (despite the command to delete it at the beginning and end of the submitted String). Unfortunately, I do not have access to those specific traces.

A few environmental details:
- I am running the JanusGraph Server within a docker container (Docker version 18.06.3-ce, build d7080c1), using the base openjdk:8-jdk image (following the [official JanusGraph image](https://github.com/JanusGraph/janusgraph-docker)).
- The docker container is ran within a docker-compose context (docker-compose version 1.24.0, build 0aa59064)
- JanusGraph version is 0.3.1.
- Tinkerpop is version 3.3.3 for both the client and server.
- The java gremlin server library is on version 3.3.3
- My OS is Ubuntu 17.10
- Local Java info:
openjdk version "1.8.0_171"
OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-0ubuntu0.17.10.1-b11)
OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)
- The server runs with `ConfigurationManagementGraph` enabled and no pre-configured graph

Thank you all for your time and efforts.
JanusGraph is currently - and as far as I know - one of the very few (if not only) open source graph database under the Apache2 license. Great work so far!

Contributor guide

Open the contributing guide

Research direction

Reproduce the repeated remote-session sequence using ConfiguredGraphFactory.create, drop, and template configuration with the inmemory backend. Trace ConfiguredGraphFactory.drop into JanusGraphFactory.drop and ConfigurationManagementGraph, then add a regression test showing repeated create/delete cycles finish without a NullPointerException or stale graph configuration.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.