RMLio / rmlmapper-java

The RMLMapper executes RML rules to generate high quality Linked Data from multiple originally (semi-)structured data sources
http://rml.io
MIT License
144 stars 61 forks source link

MethodNotFoundException: No suitable method 'lookup' ... #218

Closed MathiasVDA closed 9 months ago

MathiasVDA commented 9 months ago

Hello,

I'm trying to convert a JSON file into ttl using rmlmapper.

I use the rmlio/rmlmapper-java docker image with command: docker run --rm -v "%cd%":/data rmlio/rmlmapper-java -m operational-points.rml.ttl -o operationele-punten-van-het-netwerk.ttl -s turtle -v

My input json file can be downloaded from here: https://infrabel.opendatasoft.com/api/explore/v2.1/catalog/datasets/operationele-punten-van-het-netwerk/exports/json?lang=en&timezone=UTC

Here is the RML ttl file I've created:

@prefix rml: <http://semweb.mmlab.be/ns/rml#> .
@prefix ql: <http://semweb.mmlab.be/ns/ql#> .
@prefix rr:     <http://www.w3.org/ns/r2rml#> .
@prefix rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd:    <http://www.w3.org/2001/XMLSchema#> .
@prefix era:    <http://data.europa.eu/949/> .
@prefix gsp:    <http://www.opengis.net/ont/geosparql#> .
@prefix skos:   <http://www.w3.org/2004/02/skos/core#> .
@prefix prov:   <http://www.w3.org/ns/prov#> .
@prefix idlab-fn: <http://example.com/idlab/function/> .
@prefix fnml:   <http://semweb.mmlab.be/ns/fnml#> .
@prefix fno:    <https://w3id.org/function/ontology#> .
@base           <https://data.infrabel.be/edm/> .

<https://data.infrabel.be/mapping/opendata/operationele-punten-van-het-netwerk/1>
  skos:comment "Maps the Opendata JSON export of operational points with the ERA vocabulary";
  prov:used <https://data.infrabel.be/data/Source/Opendata/operationele-punten-van-het-netwerk/>;
  a prov:Activity,
    rr:TriplesMap;

  rml:logicalSource [
    rml:source "operationele-punten-van-het-netwerk.json";
    rml:referenceFormulation ql:JSONPath;
    rml:iterator "$.[*]" ];

  rr:subjectMap [
    rr:template "https://data.infrabel.be/data/OperationalPoint/BE_{symbolicname}";
    rr:class era:OperationalPoint ];

  rr:predicateObjectMap [
    rr:predicate era:opName;
    rr:objectMap [ rml:reference "shortnamefrench" ] ];

  rr:predicateObjectMap [
    rr:predicate era:tafTAPCode;
    rr:objectMap [ rml:reference "taftapcode" ] ];

  rr:predicateObjectMap [
    rr:predicate era:wrongOpType;
    rr:objectMap [ rml:reference "class_en" ] ];

  rr:predicateObjectMap [
      rr:predicate era:opType;
      rr:objectMap [
        fnml:functionValue [
          rr:predicateObjectMap [
            rr:predicate fno:executes;
            rr:objectMap [ rr:constant idlab-fn:lookup ]
          ];
          rr:predicateObjectMap [
            rr:predicate idlab-fn:str;
            rr:objectMap [ rml:reference "class_en"]
          ];
          rr:predicateObjectMap [
            rr:predicate idlab-fn:inputFile;
            rr:objectMap [ rr:constant "map-opType.csv"]
          ];
          rr:predicateObjectMap [
            rr:predicate idlab-fn:fromColumn;
            rr:objectMap [ rr:constant 1; rr:datatype xsd:integer]
          ];
          rr:predicateObjectMap [
            rr:predicate idlab-fn:toColumn;
            rr:objectMap [ rr:constant 2; rr:datatype xsd:integer]
          ]
        ]
      ]
  ].

Here is the relevant debug information:

20:18:54.439 [main] DEBUG b.u.i.k.functions.agent.AgentImpl   .execute(71) - Executing function 'http://example.com/idlab/function/lookup' with arguments '('http://example.com/idlab/function/inputFile' -> 'map-opType.csv')('http://example.com/idlab/function/toColumn' -> '2')('http://example.com/idlab/function/fromColumn' -> '1')('http://example.com/idlab/function/str' -> 'Station')'
20:18:54.440 [main] DEBUG b.u.i.k.f.a.f.Instantiator          .getMethod(74) - Getting instantiation for http://example.com/idlab/function/lookup
20:18:54.440 [main] DEBUG b.u.i.k.f.a.f.Instantiator          .getClass(330) - Trying to find a Class for be.ugent.knows.idlabFunctions.IDLabFunctions
20:18:54.444 [main] DEBUG b.u.i.k.f.a.f.Instantiator          .getMethod(87) - Found class class be.ugent.knows.idlabFunctions.IDLabFunctions
20:18:54.444 [main] DEBUG b.u.i.k.f.a.f.Instantiator          .getMethod(385) - Trying to find method with name lookup
20:18:54.445 [main] DEBUG b.u.i.k.f.a.f.Instantiator          .getMethod(392) - Found method with matching name lookup and matching parameter count (4)
20:18:54.447 [main] ERROR be.ugent.rml.cli.Main               .run(416) - No suitable method 'lookup' with matching parameter types found in class 'be.ugent.knows.idlabFunctions.IDLabFunctions'.
20:18:54.448 [main] DEBUG b.u.i.k.f.a.f.Instantiator          .lambda$close$12(493) - Closing be.ugent.knows.idlabFunctions.IDLabFunctions
20:18:54.450 [main] ERROR be.ugent.rml.cli.Main               .run(453) - No suitable method 'lookup' with matching parameter types found in class 'be.ugent.knows.idlabFunctions.IDLabFunctions'.
be.ugent.idlab.knows.functions.agent.functionIntantiation.exception.MethodNotFoundException: No suitable method 'lookup' with matching parameter types found in class 'be.ugent.knows.idlabFunctions.IDLabFunctions'.
        at be.ugent.idlab.knows.functions.agent.functionIntantiation.Instantiator.getMethod(Instantiator.java:453)
        at be.ugent.idlab.knows.functions.agent.functionIntantiation.Instantiator.getMethod(Instantiator.java:95)
        at be.ugent.idlab.knows.functions.agent.AgentImpl.execute(AgentImpl.java:85)
        at be.ugent.idlab.knows.functions.agent.AgentImpl.execute(AgentImpl.java:54)
        at be.ugent.rml.functions.DynamicMultipleRecordsFunctionExecutor.execute(DynamicMultipleRecordsFunctionExecutor.java:74)
        at be.ugent.rml.functions.AbstractSingleRecordFunctionExecutor.execute(AbstractSingleRecordFunctionExecutor.java:15)
        at be.ugent.rml.termgenerator.LiteralGenerator.generate(LiteralGenerator.java:47)
        at be.ugent.rml.Executor.generatePredicateObjectGraphs(Executor.java:209)
        at be.ugent.rml.Executor.executeWithFunction(Executor.java:165)
        at be.ugent.rml.Executor.execute(Executor.java:123)
        at be.ugent.rml.cli.Main.run(Main.java:412)
        at be.ugent.rml.cli.Main.main(Main.java:46)

If I understand all the code correctly, the lookup function is declared here: https://github.com/FnOio/idlab-functions-java/blob/d7aa5443f23479c9335537701db84ab301f479f7/src/main/java/be/ugent/knows/idlabFunctions/IDLabFunctions.java#L763 public static String lookup(String searchString, String inputFile, Integer fromColumn, Integer toColumn)

It expects 2 strings and 2 integers.

In the debug log I see:

with arguments '('http://example.com/idlab/function/inputFile' -> 'map-opType.csv')('http://example.com/idlab/function/toColumn' -> '2')('http://example.com/idlab/function/fromColumn' -> '1')

So it seems that my 2 integers are interpreted as strings. But I did declare them as integer in my RML file:

          rr:predicateObjectMap [
            rr:predicate idlab-fn:fromColumn;
            rr:objectMap [ rr:constant 1; rr:datatype xsd:integer]
          ];
          rr:predicateObjectMap [
            rr:predicate idlab-fn:toColumn;
            rr:objectMap [ rr:constant 2; rr:datatype xsd:integer]
          ]

When I test [rr:constant 1; rr:datatype xsd:integer] without a function, RMLmapper exports a clean integer in the resulting file.

So my guess is that somewhere in between my integer is converted into a string?

ghsnd commented 9 months ago

Hello, We found a bug indeed in how the lookup function is called, and are fixing it. We'll keep you informed. Best regards, Gerald

ghsnd commented 9 months ago

We fixed the issue and have made a new release (6.2.2), also available on Docker. Can you try again with the new version?

MathiasVDA commented 9 months ago

Thank you for the fast intervention. I'm one step further. But now I have this error for which I think that there is still a functional issue:

14:10:21.198 [main] ERROR b.u.k.idlabFunctions.IDLabFunctions .lookupWithDelimiter(912) - Column index out of boundaries; inputFile: "map-opType.csv", fromColumn: "1", toColumn: "2"
14:10:21.226 [main] ERROR be.ugent.rml.cli.Main               .run(416) - Not a valid (absolute) IRI: nullera-domain/BE_FIZG
MathiasVDA commented 9 months ago

Sorry I just realized that the columns indexing is 0 based. That explains the first ERROR in my previous message. Changing to 0 and 1 as column indexes solves it.

I haven't found a solution/reason for the second ERROR yet.

MathiasVDA commented 9 months ago

Ok second error is fixed and had nothing to do with the initial problem but was a RML typo on my side. So I can confirm that your new deploy functions correctly on my side! Thanks again