Take the 2-minute tour ×

I try to run cucumber tests in a JRuby environment. I configured the cucumber rake task to startup an embedded Vert.x application server in another thread but in the same JVM. During the application startup, an embedded instance of Neo4j is initialized. So finally, there are Cucumber, Vert.x and Neo4j all running in the same JVM (tada!).

At the end of some test scenarios, I would like to check if certian data has been placed in the database base. And since the Neo4j docs say...


...I try to get the already initialized Neo4j instance and use it for these checks. To make that happen, I wrote the following factory.

public class ConcurrentGraphDatabaseFactory {

  private static HashMap<String, GraphDatabaseService> databases = new HashMap<String, GraphDatabaseService>();

  public static synchronized GraphDatabaseService getOrCreateDatabase(String path, String autoIndexFields) {
    System.out.println("databases: " + databases.toString());
    if (databases.containsKey(path)) {
      return databases.get(path);
    } else {
      final GraphDatabaseService database = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(path).
        setConfig(GraphDatabaseSettings.node_keys_indexable, autoIndexFields).
        setConfig(GraphDatabaseSettings.node_auto_indexing, GraphDatabaseSetting.TRUE).

      Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {

      databases.put(path, database);
      return database;


This factory should ensure that only on instance per path is initialized. But if the function getOrCreateDatabase accessed the second time, the internal databases HashMap is still empty. That cause the code to initialize a second Neo4j instance on the same data, which fails with

NativeException: java.lang.IllegalStateException: Unable to lock store

It's all running in the same JVM, but it seems, that the different threads have separated memory.

What am I doing wrong here?

share|improve this question
add comment

2 Answers

Are you sure you are only running one single neo4j instance from all threads? Otherwise, several neo4j instances will fight on locking the store files. Neo4j is thread safe, but not doing several embedded instances on the same store, for scaling it, you use the High Availability setup, see http://docs.neo4j.org/chunked/snapshot/ha.html

share|improve this answer
Sorry - maybe I missed something in the description of the problem. I want to use only one Neo4j instance. The code above should ensure, that only one instance per path is created. The problem is, that this instance isn't shared between the threads. The second thread, that runs the code finds an empty databases hash structure and tries to create a second instance, which ends up in the lock-error. So my question is: Why is this databases object not accessible by the second thread? –  Philipp Brüll Jul 17 '12 at 17:29
Philipp, you can't open two different embedded DB instances against the same store - the first one is locking the files since they are memory-mapped etc etc. What do you want to achieve? –  Peter Neubauer Jul 19 '12 at 6:37
Peter, as I meantioned in the initial question and in the comment to your answer, I never wanted to create a second instance on the same store. The problem is, that the one instance is not shared between the threads. –  Philipp Brüll Jul 23 '12 at 10:46
Meanwhile, I think it's not an issue of Neo4j or cucumber. I guess, my knowledge of the internals of Vertx, JRuby and JVM scripting environment in general is too little. For some reason, I don't get access to that Neo4j instance from another JRuby environment. –  Philipp Brüll Jul 23 '12 at 10:54
add comment

I've spend some time on the problem and finally found a solution.

The verticles in Vert.x create strictly isolated environments. This causes a second version of my factory (see the code above) to be initialized. And the second factory tries to initialized a second Neo4j instance.

The solution was, to separate the Neo4j code into a dedicated storage verticle and write test code that accesses that verticle via the event bus.

share|improve this answer
nice! Care to write a short blog post about that? –  Peter Neubauer Jul 28 '12 at 13:13
add comment

Your Answer


