Closed jannvck closed 5 years ago
Maybe it's helpful to see also the higher level code. I tried an implementation in Scala which failed, so I also tried Java which also fails:
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.swrlapi.core.SWRLRuleEngine;
import org.swrlapi.factory.SWRLAPIFactory;
public class SWRLRunner {
public static void main(String[] args) throws OWLOntologyCreationException {
OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
OWLOntology ontology = manager.loadOntologyFromOntologyDocument(new File("data/dev-example.rdf"));
Map<String, String> map = new HashMap<String, String>();
map.put("custom:", "http://localhost/builtin/testJava.owl#");
manager.getOntologyFormat(ontology).asPrefixOWLOntologyFormat().copyPrefixesFrom(map);
SWRLRuleEngine ruleEngine = SWRLAPIFactory.createSWRLRuleEngine(ontology);
ruleEngine.loadExternalSWRLBuiltInLibraries(new File("path-to/swrl-builtins"));
}
}
Exception and stack trace:
Exception in thread "main" org.swrlapi.exceptions.IncompatibleSWRLBuiltInClassException: incompatible Java built-in class org.swrlapi.builtins.custom.SWRLBuiltInLibraryImpl: Class org.swrlapi.builtins.SWRLBuiltInLibraryManager can not access a member of class org.swrlapi.builtins.custom.SWRLBuiltInLibraryImpl with modifiers "protected"
at org.swrlapi.builtins.SWRLBuiltInLibraryManager.instantiateSWRLBuiltInLibraryImplementation(SWRLBuiltInLibraryManager.java:371)
at org.swrlapi.builtins.SWRLBuiltInLibraryManager.loadExternalSWRLBuiltInLibraries(SWRLBuiltInLibraryManager.java:84)
at org.swrlapi.factory.DefaultSWRLRuleAndQueryEngine.loadExternalSWRLBuiltInLibraries(DefaultSWRLRuleAndQueryEngine.java:344)
at SWRLRunner.main(SWRLRunner.java:21)
Caused by: java.lang.IllegalAccessException: Class org.swrlapi.builtins.SWRLBuiltInLibraryManager can not access a member of class org.swrlapi.builtins.custom.SWRLBuiltInLibraryImpl with modifiers "protected"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.Class.newInstance(Class.java:436)
at org.swrlapi.builtins.SWRLBuiltInLibraryManager.instantiateSWRLBuiltInLibraryImplementation(SWRLBuiltInLibraryManager.java:368)
... 3 more
Have you tried:
public class SWRLBuiltInLibraryImpl extends AbstractSWRLBuiltInLibrary {
instead of:
public class SWRLBuiltInLibraryImpl extends AbstractSWRLBuiltInLibrary implements SWRLBuiltInLibrary {
Yes, I tried that in the first place. It was redundant anyway, as AbstractSWRLBuiltInLibraray implements this interface. You are right that this could be left out. Currently, I'm investigating on whether the issue might be related to some Java security restrictions.
The constructor of the custom SWRLBuiltInLibraryImpl class is public. Using reflection I found that the constructor access modifier is set to protected at runtime:
Constructor<?>[] constructors = swrlBuiltInLibraryImplementationClass.getDeclaredConstructors();
System.out.println(constructors[0]);
console output:
constructor: protected org.swrlapi.builtins.custom.SWRLBuiltInLibraryImpl()
I found that the ProtectionDomain of the SWRLBuiltInLibraryImpl class does not have read permission for the directory containing the Built-in jar. You can check the permissions using the following code:
System.out.println("protection domain: "+swrlBuiltInLibraryImplementationClass.getProtectionDomain());
Which prints in my case:
protection domain: ProtectionDomain (file:/path-to/builtin-runnner/bin/ <no signer certificates>)
sun.misc.Launcher$AppClassLoader@73d16e93
<no principals>
java.security.Permissions@7f5e9949 (
("java.lang.RuntimePermission" "exitVM")
("java.io.FilePermission" "/path-to/builtin-runner/bin/-" "read")
)
The Built-in jar resides not in this path or subdirectories of it. I also tried putting the jar into a subdirectory of this read-permitted path - without any difference.
The problem was caused by my IDE (Eclipse). For some reason it did not use new compiled .class files. Removing the bin/ folder containing these, cleaning the project and recompiling solved the issue.
Three minor remarks:
ruleEngine.loadExternalSWRLBuiltInLibraries()
. The SWRLBuiltInLibraryImpl class cannot be resolved, then. A simple solution for this is to add the JAR archive also to the classpath.SWRLBuiltInLibraryManager.java
in method loadExternalSWRLBuiltInLibraries(...), lines 82 and 83.Glad you got this working.
Thanks for the feedback. I will update the documentation and kill the unused variables.
Martin
Hello,
I'm trying to implement a custom Built-in following these instructions. The version of the SWRLAPI I'm using is 2.0.6 from maven.
Please find the implementation of the SWRLBuiltInLibraryImpl class below:
I have created a JAR file from it and put it in swrl-builtins/custom/ which seems to work (but is not documented anywhere!). Then I passed the path to the root directory containing the swrl-builtins folder as an argument to SWRLRuleEngine.loadExternalBuiltInLibraries():
The Built-in JAR seems to be found but the loading process fails with the following exception:
I have checked the source of SWRLBuiltInLibraryManager for this, you can find the corresponding line in the source.
I have also tried creating public methods for each protected method in AbstractSWRLBuiltInLibrary without any difference in the result...