0

I want to access a Java graph library (Titan) from c++. Doing some research showed that JNI would get the job done. I wrote some JNI code, got it working, but it quickly became tedious, so I looked to an automated solution. I found SWIG, more specifically SWIG directors. I have no problem calling functions, however I have a problem of maintaining state going back and forth from Java and c++ using a SWIG director.

For my SWIG directors I wrote c++ interfaces exposing the functionality I wanted. Below is a sample:

GraphIfc.hpp:

struct GraphIfc {
   virtual ~GraphIfc() {}
   virtual VertexIfc * addVertex(const std::string& label) = 0;
};

VertexIfc.hpp:

struct VertexIfc {
   virtual ~VertexIfc() {}
   virtual EdgeIfc * addEdge(const std::string& label, VertexIfc * v) = 0;
};

EdgeIfc.hpp:

struct EdgeIfc {
   virtual ~EdgeIfc() {}
};

Then I wrote the Java implementation:

JGraph.java:

import com.thinkaurelius.titan.core.TitanGraph;

public class JGraph extends GraphIfc {
  private TitanGraph graph;

  public JGraph(TitanGraph g) {
    graph = g;
  }

  public VertexIfc addVertex(final String label) {
    return new Vertex(graph.addVertex(label));
  }
}

JVertex.java:

import com.thinkaurelius.titan.core.TitanVertex;

public class JVertex extends VertexIfc {
  public TitanVertex vertex;

  public JVertex(TitanVertex v) {
    vertex = v;
  }

  public EdgeIfc addEdge(final String label, VertexIfc inV) {
    Vertex v = (Vertex)inV;
    return new Edge(vertex.addEdge(label, v.vertex));
  }
}

JEdge.java:

import org.apache.tinkerpop.gremlin.structure.Edge;

public class JEdge extends EdgeIfc {
  public Edge edge = null;

  public JEdge(Edge e) { 
    edge = e;
  }
}

And here's my SWIG file:

%module(directors="1") graph

%{
#include "graph.hpp"
#include "vertex.hpp"
#include "edge.hpp"
%}

%feature("director") GraphIfc;
%feature("director") VertexIfc;
%feature("director") EdgeIfc;
SWIG_DIRECTOR_OWNED(GraphIfc)
SWIG_DIRECTOR_OWNED(VertexIfc)
SWIG_DIRECTOR_OWNED(EdgeIfc)

%include "graph.hpp"
%include "vertex.hpp"
%include "edge.hpp"

%pragma(java) jniclasscode=%{
  static {
    try {
      System.loadLibrary("graph");
    } catch (UnsatisfiedLinkError e) {
      System.err.println("Native code library graph failed to load.\n" + e);
      System.exit(1);
    }
  }
%}

All of this produces:

  • Java proxy classes: GraphIfc, VertexIfc, EdgeIfc. These hold the c++ pointer as a long.
  • Intermediary JNI class in Java with functions

such as:

public static long SwigDirector_GraphIfc_addVertex(GraphIfc jself, String label) {
  return VertexIfc.getCPtr(jself.addVertex(label));
}

public static long SwigDirector_VertexIfc_addEdge(VertexIfc jself, String label, long inVertex) {
  return EdgeIfc.getCPtr(jself.addEdge(label, (inVertex == 0) ? null : new VertexIfc(inVertex, false)));
}

There are a two problems with these functions:

  1. The VertexIfc being created by SwigDirector_VertexIfc_addEdge is not of type JVertex, thus my cast within addEdge will fail and throw an exception.
  2. But more importantly, even if the type was a JVertex, the new JVertex would not contain the same value of TitanVertex as set by addVertex. Any state within the derived class (JVertex, JEdge, etc) is loss.
shawks03
  • 1
  • 1
  • I think this is a duplicate of a question I answered here: http://stackoverflow.com/a/9889597/168175 - let me know if you agree or not, you'll probably need a few more of the 'directorin' typemaps written (as javaout) for it to completely apply in your scenario. – Flexo Oct 24 '16 at 16:35
  • I looked at that, but using static maps failed when one of my classes was generic (I purposefully left that class out of the description to keep the problem simpler). It failed because I couldn't use the generic type within a static. Also, I have concerns over performance and multi-threading. It just seems like if the jobject is being stored already within the Director class, then why not use it. – shawks03 Oct 24 '16 at 19:34
  • It turns out there is a way to use the information stored within the director class: http://stackoverflow.com/a/42378259/168175 – Flexo Feb 21 '17 at 22:42

0 Answers0