ontop: InaccessibleObjectException on Java 16
Description
ontop requires Java 8. As Java is largely backwards compatible, this should allow it to run on Java 16, however it throws a java.lang.reflect.InaccessibleObjectException.
Steps to Reproduce
ontop materialize -m r2rml/citation.r2rml.ttl -o output/citation.ontop.nt -f ntriples -p hito.properties
Expected behavior: A program developed for Java 8 should also run under Java 16. Alternatively it should be mentioned that it only works with exactly Java 8.
Actual behavior:
Java 16 throws a java.lang.reflect.InaccessibleObjectException, see below.
Java 11 gives the following warning:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.inject.internal.cglib.core.$ReflectUtils$1 (file:/home/konrad/opt/ontop/lib/guice-4.1.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of com.google.inject.internal.cglib.core.$ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Reproduces how often: Every time.
Workaround
Change the line ONTOP_JAVA_ARGS="-Xmx512m" to ONTOP_JAVA_ARGS="-Xmx512m --illegal-access=permit" in the ontop script.
However that is discouraged and may not work in Java 17.
Attached material
$ ontop materialize -m r2rml/citation.r2rml.ttl -o output/citation.ontop.nt -f ntriples -p hito.properties
Exception in thread "main" com.google.common.util.concurrent.ExecutionError: com.google.common.util.concurrent.ExecutionError: java.lang.ExceptionInInitializerError
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2201)
at com.google.common.cache.LocalCache.get(LocalCache.java:3937)
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3941)
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4824)
at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4830)
at com.google.inject.internal.FailableCache.get(FailableCache.java:48)
at com.google.inject.internal.ConstructorInjectorStore.get(ConstructorInjectorStore.java:50)
at com.google.inject.internal.ConstructorBindingImpl.initialize(ConstructorBindingImpl.java:138)
at com.google.inject.internal.InjectorImpl.initializeJitBinding(InjectorImpl.java:550)
at com.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:887)
at com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:808)
at com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:285)
at com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:217)
at com.google.inject.internal.InjectorImpl.getInternalFactory(InjectorImpl.java:893)
at com.google.inject.internal.FactoryProxy.notify(FactoryProxy.java:46)
at com.google.inject.internal.ProcessedBindingData.runCreationListeners(ProcessedBindingData.java:50)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:134)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
at com.google.inject.Guice.createInjector(Guice.java:99)
at com.google.inject.Guice.createInjector(Guice.java:73)
at it.unibz.inf.ontop.injection.impl.OntopModelConfigurationImpl.getInjector(OntopModelConfigurationImpl.java:95)
at it.unibz.inf.ontop.materialization.impl.DefaultOntopRDFMaterializer.<init>(DefaultOntopRDFMaterializer.java:45)
at it.unibz.inf.ontop.rdf4j.materialization.impl.DefaultRDF4JMaterializer.<init>(DefaultRDF4JMaterializer.java:59)
at it.unibz.inf.ontop.rdf4j.materialization.RDF4JMaterializer.defaultMaterializer(RDF4JMaterializer.java:34)
at it.unibz.inf.ontop.cli.OntopMaterialize.createMaterializer(OntopMaterialize.java:121)
at it.unibz.inf.ontop.cli.OntopMaterialize.run(OntopMaterialize.java:102)
at it.unibz.inf.ontop.cli.Ontop.main(Ontop.java:20)
Caused by: com.google.common.util.concurrent.ExecutionError: java.lang.ExceptionInInitializerError
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2201)
at com.google.common.cache.LocalCache.get(LocalCache.java:3937)
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3941)
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4824)
at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4830)
at com.google.inject.internal.FailableCache.get(FailableCache.java:48)
at com.google.inject.internal.MembersInjectorStore.get(MembersInjectorStore.java:68)
at com.google.inject.internal.ConstructorInjectorStore.createConstructor(ConstructorInjectorStore.java:75)
at com.google.inject.internal.ConstructorInjectorStore.access$000(ConstructorInjectorStore.java:29)
at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:37)
at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:33)
at com.google.inject.internal.FailableCache$1.load(FailableCache.java:37)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2319)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2282)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2197)
... 26 more
Caused by: java.lang.ExceptionInInitializerError
at com.google.inject.internal.cglib.reflect.$FastClass$Generator.getProtectionDomain(FastClass.java:73)
at com.google.inject.internal.cglib.core.$AbstractClassGenerator.create(AbstractClassGenerator.java:206)
at com.google.inject.internal.cglib.reflect.$FastClass$Generator.create(FastClass.java:65)
at com.google.inject.internal.BytecodeGen.newFastClassForMember(BytecodeGen.java:252)
at com.google.inject.internal.BytecodeGen.newFastClassForMember(BytecodeGen.java:203)
at com.google.inject.internal.SingleMethodInjector.createMethodInvoker(SingleMethodInjector.java:47)
at com.google.inject.internal.SingleMethodInjector.<init>(SingleMethodInjector.java:38)
at com.google.inject.internal.MembersInjectorStore.getInjectors(MembersInjectorStore.java:131)
at com.google.inject.internal.MembersInjectorStore.createWithListeners(MembersInjectorStore.java:98)
at com.google.inject.internal.MembersInjectorStore.access$000(MembersInjectorStore.java:37)
at com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:45)
at com.google.inject.internal.MembersInjectorStore$1.create(MembersInjectorStore.java:42)
at com.google.inject.internal.FailableCache$1.load(FailableCache.java:37)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2319)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2282)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2197)
... 41 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @51cdd8a
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at com.google.inject.internal.cglib.core.$ReflectUtils$1.run(ReflectUtils.java:52)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:312)
at com.google.inject.internal.cglib.core.$ReflectUtils.<clinit>(ReflectUtils.java:42)
... 58 more
Versions
Ontop 4.1 openjdk 16.0.2 2021-07-20 OpenJDK Runtime Environment (build 16.0.2+7) OpenJDK 64-Bit Server VM (build 16.0.2+7, mixed mode)
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 37 (35 by maintainers)
@bcogrel: dependency removed, I forgot it sorry. I also revised all changes w.r.t. version4 branch and revised an imprecise import (shaded guava class vs correct guava class) and some formatting (tab/spaces). Also repeated the testing of all Java 8 / Java 17 combinations for compiling and running Ontop endpoint and Ontop Protégé plugin (note: only Java 8 can be used to run Protégé), and they all work.
In the meanwhile a decision is taken on the adapter class (see discussion), I changed branch protege-refactoring-reflection as follows:
OntopEndpointcommand, changed lineSystem.setProperty("logback.configurationFile", "")intoSystem.clearProperty("logback.configurationFile")As a result:
In branch feature/protege-refactoring-reflection there’s a new simpler solution – let’s call it (D) – that does not require neither an extra module nor the use of shading, but instead leverages Java reflection to address the only clash we have on Guava classes.
Briefly, in this solution (D):
we setup the Ontop Protégé plugin bundle not to import Guava from Protégé (v. 18.0), but instead to use its own internal & newer version of Guava (v. 30.1.1-jre)
to avoid
NoMethodDefFounderrors (at class load/resolution time) when Ontop Protégé classes refer to Protégé / OWL API methods that have Guava classes (e.g.,Optional) as parameters or return types, we perform those calls via reflection, leveraging the fact that (after analysis) there is only one Ontop Protégé class affected:OntologyPrefixManager.to simplify development, there is a new
Adapterclass exposing public static method that wrap calls via reflection of all (I hope so) problematic public Protégé / OWL API methods involving Guava classes (currently, we use onlygetOntologyIRI)besides, I did some cleanup in Ontop Protégé
pom.xml, in particular enabling embedding of transitive dependencies in the generated OSGI bundle, rather than listing them explicitly that is prone to errors (as we have to update the list every time some new transitive dependency is added to used Ontop modules)I kept the previous solution (A) in its own branch feature/protege-refactoring-shade (renamed adding
-shade).New solution (D) pros, compared to (A):
ontop-protege-dependenciesontop-protegeto depend on shaded moduleontop-protege-dependenciesthat may be problematic in IDEsPrevious solution (A) pros, compared to (D):
NoMethodDefFoundAdapterOverall and considering the current situation (and particularly in light of unclear issues with IDEs), my two cents are for going with new solution (D) and keep (A) in its own branch for future reference, in case we would need to reconsider the decision.
Let me know what you think, and consider I still have some work to do in order to finalize both solutions, namely:
Adapterclass, for solution (D)Merged with https://github.com/ontop/ontop/pull/479 . The issue should be now be fixed. Thanks again!