Java OWLAPI:如果从Jar运行,则找不到解析器

Java OWLAPI:如果从Jar运行,则找不到解析器,java,gradle,rdf,owl,owl-api,Java,Gradle,Rdf,Owl,Owl Api,我用Java编写了一个本体导入程序,将RDF格式的.owl文件解析为JSON格式的字符串。更具体地说,静态方法parseOntologyObjectHierarchy将本体中定义的类层次结构解析为JSON。如果我从JUnit测试调用该方法或类的main方法(JUnit和类main是从IntelliJ IDEA Professional 2017调用的),那么一切都可以正常工作。但是,如果我使用gradle(包括所有依赖项)将类打包为一个jar,我会得到一个org.semanticweb.owla

我用Java编写了一个本体导入程序,将RDF格式的.owl文件解析为JSON格式的字符串。更具体地说,静态方法
parseOntologyObjectHierarchy
将本体中定义的类层次结构解析为JSON。如果我从JUnit测试调用该方法或类的
main
方法(JUnit和类main是从IntelliJ IDEA Professional 2017调用的),那么一切都可以正常工作。但是,如果我使用gradle(包括所有依赖项)将类打包为一个jar,我会得到一个
org.semanticweb.owlapi.io.UnparsableOntologyException
。jar实际上包含所需的
RDFXMLParser
。jar中的类路径设置是否不正确

以下是IntelliJ IDEA项目的一个简单示例:

下面是对应的最小jar:

代码如下:

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);
}
这是我的身材。格雷德尔:

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
}
以下是例外文本:

$ 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)

在最小的jar中,
META-INF/services
文件夹包含
org.semanticweb.owlapi.io.OWLParserFactory
的多个副本-这些副本可能来自您对owlapi依赖项的合并

每个模块在此文件中声明可以在模块中找到哪些解析器(它们由
ServiceLoader
解释以提供实例)
owlapi发行版
包含owlapi模块提供的所有文件的合并副本。您需要确保这是jar中包含的唯一文件


此文件夹中的其他文件也是如此。

如何加载/发现解析器?它似乎找到了一个解析器(OWLOBO12),但这不是您想要的解析器。对吗?也可能有助于了解如何运行单元测试和main。也就是说,您使用的是IDE还是命令行。这可能有助于调试类路径问题。@cmonkey,我编辑了描述:我从IntelliJ IDEA启动类main和JUnit测试。对于jar,无论我是从命令行还是从IntelliJ运行它,都会引发相同的异常。我真的不在乎使用哪个解析器,我只需要一个能够解析RDF XML的解析器。@cmonkey,我还添加了到一个最小IntelliJ IDEA项目的链接,以及我用IDEA项目构建的jar。多亏了您的帮助,我发现一旦我使用
owlapi osgidistribution
而不是
owlapi distribution
,它就可以工作了(对于MWE)。在进行MWE之前,我的错误是我将
owlapi发行版
owlapi-osgidistribution
都作为Gradle依赖项,而我只需要
owlapi-osgidistribution
(并且使用这两个版本会破坏某些东西)。