OWLAPI: Parser not found if run from Jar

2019-06-11 07:43发布

I wrote an ontology importer in Java to parse an RDF-formatted .owl file into a JSON-formatted string. More specifically, the static method parseOntologyObjectHierarchy parses the class hierarchy defined in the ontology into JSON. Everything works fine if I call the method from a JUnit test or the main method of a class (JUnit and the class main are invoked from IntelliJ IDEA Professional 2017). However, if I package my classes as a jar using gradle (including all dependencies), I get an org.semanticweb.owlapi.io.UnparsableOntologyException. The jar actually contains the required RDFXMLParser. Is the classpath in the jar not set properly?

Here is a minimal example IntelliJ IDEA project: https://drive.google.com/open?id=0B10MbhsMWfrydVNKZVJ0QVg1NlE

And here is the corresponding minimal jar: https://drive.google.com/open?id=0B10MbhsMWfrybjJIcDNWd0JFMUk

Here is the code:

public static String parseOntologyObjectHierarchy(String filename) throws OWLException {
    System.out.println("OWL file: " + filename);
    OWLOntology ontology = loadOntology(filename);
    OWLDataFactory df = OWLManager.getOWLDataFactory();
    return json = hierarchyToString(ontology, df.getOWLThing());
}

public static OWLOntology loadOntology(String filename) throws OWLOntologyCreationException {
    File ontologyFile = new File(filename);
    if (!ontologyFile.exists() || !ontologyFile.isFile()) {
        throw new IllegalArgumentException("OWL file is not a file");
    }
    OWLOntologyManager ontologyManager = OWLManager.createOWLOntologyManager();
    OWLOntologyDocumentSource source = new FileDocumentSource(new File(filename), new RDFXMLDocumentFormat());
    return ontologyManager.loadOntologyFromOntologyDocument(source);
}

Here is my build.gradle:

group 'com.example'
version '0.1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
    mavenCentral()
}
dependencies {
    compile group: 'net.sourceforge.owlapi', name: 'owlapi-osgidistribution', version: '5.1.0'
    compile group: 'net.sourceforge.owlapi', name: 'owlapi-apibinding', version: '5.1.0'
    compile group: 'net.sourceforge.owlapi', name: 'owlapi-parsers', version: '5.1.0'
    compile group: 'net.sourceforge.owlapi', name: 'owlapi-impl', version: '5.1.0'

    compile 'com.google.code.gson:gson:2.8.0'
    compile 'net.sourceforge.owlapi:org.semanticweb.hermit:1.3.8.510'
    compile group: 'org.glassfish', name: 'javax.json', version: '1.0.4'
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

task fatJar(type: Jar) {
    manifest {
    attributes 'Implementation-Title': 'ExampleCom Ontology Importer',
            'Implementation-Version': version,
            'Main-Class': 'com.example.ontology.OntologyImporter'
    }
    baseName = project.name + '-all'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

Here is the exception text:

$ java -jar am-ontology_importer-all-0.1.0-SNAPSHOT.jar
OWL file: C:/Users/me/Desktop/Projects/example/example-0.1.0.owl
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further detail
s.
Exception in thread "main" org.semanticweb.owlapi.io.UnparsableOntologyException
: Problem parsing file:/C:/Users/me/Desktop/Projects/example/example-0.1.0.owl
Could not parse ontology.  Either a suitable parser could not be found, or parsi
ng failed.  See parser logs below for explanation.
The following parsers were tried:
1) org.coode.owlapi.obo12.parser.OWLOBO12Parser@1ca3d04


Detailed logs:
--------------------------------------------------------------------------------

Parser: org.coode.owlapi.obo12.parser.OWLOBO12Parser@1ca3d04
    Stack trace:
Lexical error at line 1, column 22.  Encountered: "\n" (10), after : ""        o
rg.coode.owlapi.obo12.parser.OBOParserTokenManager.getNextToken(OBOParserTokenMa
nager.java:1059)
        org.coode.owlapi.obo12.parser.OBOParser.jj_ntk_f(OBOParser.java:296)
        org.coode.owlapi.obo12.parser.OBOParser.TagValuePair(OBOParser.java:147)

        org.coode.owlapi.obo12.parser.OBOParser.Header(OBOParser.java:110)
        org.coode.owlapi.obo12.parser.OBOParser.parse(OBOParser.java:80)
        org.coode.owlapi.obo12.parser.OWLOBO12Parser.parse(OWLOBO12Parser.java:1
09)
        uk.ac.manchester.cs.owl.owlapi.OWLOntologyFactoryImpl.loadOWLOntology(OW
LOntologyFactoryImpl.java:188)
        uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.load(OWLOntologyMa
nagerImpl.java:1072)
        uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.loadOntology(OWLOn
tologyManagerImpl.java:1033)
        uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.loadOntologyFromOn
tologyDocument(OWLOntologyManagerImpl.java:982)



        at uk.ac.manchester.cs.owl.owlapi.OWLOntologyFactoryImpl.loadOWLOntology
(OWLOntologyFactoryImpl.java:229)
        at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.load(OWLOntolog
yManagerImpl.java:1072)
        at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.loadOntology(OW
LOntologyManagerImpl.java:1033)
        at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.loadOntologyFro
mOntologyDocument(OWLOntologyManagerImpl.java:982)
        at com.example.ontology.OntologyImporter.loadOntology(OntologyImpo
rter.java:52)
        at com.example.ontology.OntologyImporter.parseOntologyObjectHierar
chy(OntologyImporter.java:64)
        at com.example.ontology.OntologyImporter.main(OntologyImporter.jav
a:142)

1条回答
兄弟一词,经得起流年.
2楼-- · 2019-06-11 08:27

in your minimal jar, the META-INF/services folder contains multiple copies of org.semanticweb.owlapi.io.OWLParserFactory - these are likely coming from your merging of OWLAPI dependencies.

Each module declares in this file which parsers can be found in the module (they are interpreted by ServiceLoader to provide instances); owlapi-distribution contains a merged copy of all the files provided by OWLAPI modules. You need to ensure that that's the only file included in your jar.

The same is true for the other files found in this folder.

查看更多
登录 后发表回答