nkons / r2rml-parser

R2RML Parser is an award-winning tool that can export relational database contents as RDF graphs, based on an R2RML mapping document.
Apache License 2.0
69 stars 21 forks source link

Java Comparison method error if more than 32 mappings are used #29

Closed YvesMeersmans closed 6 years ago

YvesMeersmans commented 6 years ago

Hi, If we use more than 32 mappings in our script, the following java error occurs: java.lang.IllegalArgumentException: Comparison method violates its general contract! at java.util.TimSort.mergeLo(Unknown Source) at java.util.TimSort.mergeAt(Unknown Source) at java.util.TimSort.mergeCollapse(Unknown Source) at java.util.TimSort.sort(Unknown Source) at java.util.Arrays.sort(Unknown Source) at java.util.List.sort(Unknown Source) at java.util.Collections.sort(Unknown Source) at gr.seab.r2rml.beans.Parser.parse(Parser.java:136) at gr.seab.r2rml.beans.Main.main(Main.java:94)

The 136th line in the parser java file handles the sort: Collections.sort(mappingDocument.getLogicalTableMappings(), c);

This error -strangely- does not occur if we use less than 32 mappings. The syntax of the mapping script was checked and correct.

Any idea what would be the issue? If you need more info, please let me know.

nkons commented 6 years ago

Hi,

Thank you for your interest in this work, and for spotting this. It looks like the problem is in the LogicalTableMappingComparator. I believe the problem with the comparator is that there are cases when equality in the logical table mappings is not transitive. This means, if A, B, and C are logical table mappings, that it finds a case in the mapping file when A == B and B == C, but A !=C, hence the exception, as the parser doesn't know how to sort the list (see https://stackoverflow.com/questions/19325256/java-lang-illegalargumentexception-comparison-method-violates-its-general-contr).

The whole idea with introducing the comparator was that the first logical table mappings to be processed should be the ones without a reference to a rr:parentTriplesMap in their rr:RefObjectMap. A possible fix would be, since there is no other need for a sorted list, to delete the LogicalTableMappingComparator altogether, and replace lines 135 and 136 in Parser with something like the following:

LinkedList<LogicalTableMapping> first = new LinkedList<LogicalTableMapping>();
LinkedList<LogicalTableMapping> second = new LinkedList<LogicalTableMapping>();
for (LogicalTableMapping ltm : mappingDocument.getLogicalTableMappings()) {
    for (PredicateObjectMap p : ltm.getPredicateObjectMaps()) {
        if (p.getRefObjectMap() != null && p.getRefObjectMap().getParentTriplesMapUri() != null && StringUtils.isNotBlank(p.getRefObjectMap().getParentTriplesMapUri())) second.add(p); else first.add(p);
    }
}
mappingDocument.setLogicalTableMappings(first.addAll(second));

The idea in this (untested!) fix would be to create two lists, first with the logical table mappings without a reference to a rr:parentTriplesMap in their rr:RefObjectMap, and second with a reference. Then, to append list second to list first, and replace the mapping document's logical table mappings with the union of these two lists.

Hope this helps?

Best, Nikos

YvesMeersmans commented 6 years ago

Hi Nikos,

Thanks for the swift reply. We are actively working on this so your help is very much appreciated. Two questions:

  1. Is there a best practice to avoid the scenario where "A == B and B == C"? Does it have to do with the names of certain mappings, or with the construction thereof in the turtle script/code?

  2. Would you be so kind to test the suggested code? I can't seem to be able to get it working (struggling to find the correct casting method). The two errors I'm getting are for second.add(p) and first.add(p): The method add(LogicalTableMapping) in the type LinkedList is not applicable for the arguments (PredicateObjectMap)

nkons commented 6 years ago

Thanks for following up on this. Hope I ll get it fixed before too long. Will update this issue when I do.

Best, Nikos

YvesMeersmans commented 6 years ago

Hi Nikos,

We appreciate your effort! :-) Do you have any update as of yet on this?

Best regards, Yves

nkons commented 6 years ago

Hi,

Sorry for the late reply. Hope commit ae98eb70238c695cd04d3d6ad93858454c16a15b fixes the issue?

Best, Nikos

YvesMeersmans commented 6 years ago

Apologies for the extremely late response. Can confirm that the bug is fixed! Many, many thanks!