修复 OWLOntologyStorageException

Fix OWLOntologyStorageException

我正在使用 owl-api 开发 Java 应用程序。对于测试,我想使用 TestDataProvider 为单元测试提供测试数据。

我使用的是 5.0.0 版本,因为我阅读的教程也是使用这个版本。打算晚点更新。

<dependency>
            <groupId>net.sourceforge.owlapi</groupId>
            <artifactId>owlapi-distribution</artifactId>
            <version>5.0.0</version>
</dependency>

但是我运行在下面的异常

org.semanticweb.owlapi.model.OWLOntologyStorageException: java.net.ProtocolException: cannot write to a URLConnection if doOutput=false - call setDoOutput(true)
    at org.semanticweb.owlapi.util.AbstractOWLStorer.storeOntology(AbstractOWLStorer.java:49)
    at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.saveOntology(OWLOntologyManagerImpl.java:1160)
    at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.saveOntology(OWLOntologyManagerImpl.java:1134)
    at uk.ac.manchester.cs.owl.owlapi.OWLOntologyManagerImpl.saveOntology(OWLOntologyManagerImpl.java:1122)
    at de.abk.wiwiservice.OntologyTestDataProvider.addOWLIndividualToOWLOntology(OntologyTestDataProvider.java:58)
    at de.abk.wiwiservice.OntologyTestDataProvider.<init>(OntologyTestDataProvider.java:32)
    at de.abk.wiwiservice.owlindividual.OWLIndividualRepositoryImplTest.setup(OWLIndividualRepositoryImplTest.java:40)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptLifecycleMethod(TimeoutExtension.java:126)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptBeforeAllMethod(TimeoutExtension.java:68)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod[=11=](ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke[=11=](ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllMethods(ClassBasedTestDescriptor.java:397)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllMethods(ClassBasedTestDescriptor.java:395)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:209)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:80)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:148)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute[=11=](EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.net.ProtocolException: cannot write to a URLConnection if doOutput=false - call setDoOutput(true)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1349)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1342)
    at org.semanticweb.owlapi.util.AbstractOWLStorer.prepareActualOutput(AbstractOWLStorer.java:64)
    at org.semanticweb.owlapi.util.AbstractOWLStorer.storeOntology(AbstractOWLStorer.java:46)
    ... 65 more

addOWLIndividualToOWLOntology() 的最后一行

public class OntologyTestDataProvider {

    private OWLOntology owlOntology;

    private IRI baseIRI;

    private List<OWLClass> owlClasses;

    private List<OWLIndividual> owlIndividuals;

    private List<OWLDeclarationAxiom> owlDeclarationAxioms;

    public OntologyTestDataProvider() throws OWLOntologyCreationException, OWLOntologyStorageException {
        owlClasses = new ArrayList<>();
        owlDeclarationAxioms = new ArrayList<>();
        owlIndividuals = new ArrayList<>();
        baseIRI = IRI.create("http://www.semanticweb.org/andreas.b/ontologies/2022/1/test-ontology");
        OWLOntologyManager owlOntologyManager = OWLManager.createOWLOntologyManager();
        owlOntology = owlOntologyManager.createOntology(baseIRI);
        addOWLClassesToOWLOntology();
        addOWLIndividualToOWLOntology();
    }

    private void addOWLClassesToOWLOntology() {
        final OWLClass person = owlOntology.getOWLOntologyManager().getOWLDataFactory().getOWLClass(baseIRI + "#Person");
        final OWLClass role = owlOntology.getOWLOntologyManager().getOWLDataFactory().getOWLClass(baseIRI + "#Role");

        owlClasses.add(person);
        owlClasses.add(role);

        OWLDeclarationAxiom owlDeclarationAxiomPerson = owlOntology.getOWLOntologyManager().getOWLDataFactory().getOWLDeclarationAxiom(person);
        OWLDeclarationAxiom owlDeclarationAxiomRolle = owlOntology.getOWLOntologyManager().getOWLDataFactory().getOWLDeclarationAxiom(role);

        owlDeclarationAxioms.add(owlDeclarationAxiomPerson);
        owlDeclarationAxioms.add(owlDeclarationAxiomRolle);

        owlOntology.add(owlDeclarationAxiomPerson);
        owlOntology.add(owlDeclarationAxiomRolle);
    }

    private void addOWLIndividualToOWLOntology() throws OWLOntologyStorageException {
        final OWLIndividual andy = owlOntology.getOWLOntologyManager().getOWLDataFactory().getOWLNamedIndividual( baseIRI + "#Andy");
        owlIndividuals.add(andy);
        OWLClassAssertionAxiom andyClassAssertion = owlOntology.getOWLOntologyManager().getOWLDataFactory().getOWLClassAssertionAxiom(owlClasses.get(0), andy);
        owlOntology.getOWLOntologyManager().addAxiom(owlOntology, andyClassAssertion);
        owlOntology.add(andyClassAssertion);
        owlOntology.getOWLOntologyManager().saveOntology(owlOntology);
    }

}

我已经读到我每次都必须从 ontology 中检索一个新的 OWLOntologyManager 并相应地更改我的代码,但这并没有起到作用。希望大家指点一下。

默认情况下,ontology 保存在它加载的相同位置 - 在这种情况下,它是从远程 IRI 加载的,目前不支持直接保存 ontology到远程 URL.

您可以通过为 saveOntology() 调用指定目标来解决此问题,例如,

StringDocumentTarget target = new StringDocumentTarget();
ontology.saveOntology(target); // calling the method on the ontology object redirects to the method on its manager, so you don't have to worry about having picked the right manager.

a StringDocumentTarget 将数据写入内存,您可以检查其内容,例如,出于测试目的(例如,在 OWLAPI 单元测试中也会发生同样的事情)。

请注意,教程中显示的方法不太可能在整个 5.x.x 系列中发生变化,因此您可以立即转移到最新的 OWLAPI 版本,而不会影响您正在做的事情。