I'm confronted with problems while I#m trying to read and write graphs from and to a text file with JUNG. The situation is as follows: Given is a file that contains coordinates of a multigraph and its weight.
An example is:
6346 6728 5911 156 5
6346 6728 6599 156 10
6346 6728 8555 156 5
I have written a converter with JUNG that reads a file that contains millions of such rows and constructs a
DirectedSparseMultigraph<Node, Edge>
Nodes and Edges are custom made classes listed below
class Node {
int id; // good coding practice would have this as private
public Node(int id) {
this.id = id;
}
public String toString() { // Always a good idea for debuging
return "V"+id;
// JUNG2 makes good use of these.
}
}
class Edge {
Context context;
Time time;
Value value;
int id;
public Edge(int id, Context context, Time time, Value value) {
this.id = id; // This is defined in the outer class.
this.context = context;
this.time = time;
this.value = value;
}
public String toString() { // Always good for debugging
return "E"+id;
}
}
Constructing a graph in memory from this data works fine. We come closer to the problem. It is important to note that saving the constructed graph to disk works fine by using a method save() of the DirectedSparseMultigraph object. In a next step, the constructed DirectedSparseMultigraph is loaded from disk by the following lines of code
GraphMLReader<DirectedSparseMultigraph<Node, Edge>, Node, Edge> gmlr = null;
try
{
gmlr = new GraphMLReader<DirectedSparseMultigraph<Node, Edge>, Node, Edge>();
} catch (ParserConfigurationException e1)
{
e1.printStackTrace();
} catch (SAXException e1)
{
e1.printStackTrace();
}
DirectedSparseMultigraph<Node, Edge> g_new = null;
try
{
gmlr.load("bla.sh", g_new);
} catch (IOException e)
{
e.printStackTrace();
}
And that is where the problem starts. The error message is as follows:
Exception in thread "main" java.lang.IllegalArgumentException: If no edge factory is supplied, edge id may not be null: {source=V6818, target=V2472}
at edu.uci.ics.jung.io.GraphMLReader.createEdge(GraphMLReader.java:693)
at edu.uci.ics.jung.io.GraphMLReader.startElement(GraphMLReader.java:299)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1343)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2786)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:333)
at edu.uci.ics.jung.io.GraphMLReader.parse(GraphMLReader.java:241)
at edu.uci.ics.jung.io.GraphMLReader.load(GraphMLReader.java:192)
at edu.uci.ics.jung.io.GraphMLReader.load(GraphMLReader.java:201)
at main.Graph.main(Graph.java:99)
If you have any Ideas or hints how this problem can be solved, I really look forward to your message. greetings J Bug
There are two ways for GraphMLReader to be able to parse your file:
(1) You supply node and edge factories; in this case your node and edge types can be anything you want. (constructor with factories)
(2) You don't supply node and edge factories; in this case your node and edge types must be String
s. (constructor without factories)
Your code doesn't supply node and edge factories, and your Edge
type is not assignment-compatible with String
, so it blows up. Admittedly this is not super-obvious from the error message, but it's fairly clear in the code.
In this case you can't really provide Node
and Edge
factories (without redesigning them), because you don't have a no-arg constructor. So you'd either need to redesign those classes, or use a two-stage process, i.e.: parse the graph using simple String keys for the nodes and edges + populate the metadata, and then build a new graph based on the data structures that GraphMLReader provides.