Skip to content

InaccessibleObject Unable to make field private final sun.nio.fs.UnixFileSystem sun.nio.fs.UnixPath.fs accessible #1350

Closed
@LitschiW

Description

@LitschiW

Clear description of my expectations versus reality

Comparing java.nio.file.Path objects fails with an java.lang.reflect.InaccessibleObjectException when building the object graph when trying to make the classes sun.nio.fs.UnixFileSystem (or respectively sun.nio.fs.WindowsFileSystem) accessible.

We tried the following to get around the Problem:

  • JaversBuilder#registerIgnoredClass(Path.class) does not help
  • Building a CustomPropertyComparator for the wrapping type could be a solution, but is not feasible for us, since the type is rather complicated.
  • Neither can we use the @DiffIgnore annotation as we do not have control over the compared type

However, I think all these solutions would trigger the Graph build anyway, and to not prevent the exception.

I would expect Javers to:

  1. have an option to compare Path objects as their toString interpretation
  2. be able to compare Objects of the type Path
  3. have an option to ignore Path objects (which it might have already once the reflection exception is fixed)

Additionally, if a field is marked as ignored, it may not be necessary to be included in the graph building process.

The issue appears analogue on Windows with WindowsFileSystem and WindowsPath.fs.
Here is a full stack trace:

java.lang.reflect.InaccessibleObjectException: Unable to make field private final sun.nio.fs.WindowsFileSystem sun.nio.fs.WindowsPath.fs accessible: module java.base does not "opens sun.nio.fs" to unnamed module @63e2203c

	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
	at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
	at org.javers.common.reflection.JaversMember.setAccessibleIfNecessary(JaversMember.java:95)
	at org.javers.common.reflection.JaversMember.<init>(JaversMember.java:47)
	at org.javers.common.reflection.JaversMember.<init>(JaversMember.java:39)
	at org.javers.common.reflection.JaversField.<init>(JaversField.java:17)
	at org.javers.common.reflection.JaversFieldFactory.createJField(JaversFieldFactory.java:43)
	at org.javers.common.reflection.JaversFieldFactory.getAllFields(JaversFieldFactory.java:31)
	at org.javers.common.reflection.ReflectionUtil.getAllFields(ReflectionUtil.java:125)
	at org.javers.common.reflection.ReflectionUtil.getAllPersistentFields(ReflectionUtil.java:110)
	at org.javers.core.metamodel.scanner.FieldBasedPropertyScanner.getMembers(FieldBasedPropertyScanner.java:19)
	at org.javers.core.metamodel.scanner.PropertyScanner.scan(PropertyScanner.java:27)
	at org.javers.core.metamodel.scanner.ClassScanner.scan(ClassScanner.java:19)
	at org.javers.core.metamodel.type.TypeFactory$JavaRichType.lambda$new$0(TypeFactory.java:196)
	at org.javers.core.metamodel.type.TypeFactory$JavaRichType.getScan(TypeFactory.java:209)
	at org.javers.core.metamodel.type.TypeFactory.inferFromAnnotations(TypeFactory.java:164)
	at org.javers.core.metamodel.type.TypeFactory.lambda$infer$4(TypeFactory.java:107)
	at java.base/java.util.Optional.orElseGet(Optional.java:364)
	at org.javers.core.metamodel.type.TypeFactory.infer(TypeFactory.java:107)
	at org.javers.core.metamodel.type.TypeMapper.lambda$getJaversType$0(TypeMapper.java:110)
	at org.javers.core.metamodel.type.TypeMapperEngine.computeIfAbsent(TypeMapperEngine.java:111)
	at org.javers.core.metamodel.type.TypeMapper.getJaversType(TypeMapper.java:110)
	at org.javers.core.metamodel.type.TypeMapper.getJaversManagedType(TypeMapper.java:170)
	at org.javers.core.metamodel.type.TypeMapper.getJaversManagedType(TypeMapper.java:161)
	at org.javers.core.metamodel.object.GlobalIdFactory.createId(GlobalIdFactory.java:45)
	at org.javers.core.graph.LiveCdoFactory.create(LiveCdoFactory.java:37)
	at org.javers.core.graph.EdgeBuilder.buildSingleEdge(EdgeBuilder.java:33)
	at org.javers.core.graph.ObjectGraphBuilder.buildSingleEdges(ObjectGraphBuilder.java:107)
	at org.javers.core.graph.ObjectGraphBuilder.buildEdges(ObjectGraphBuilder.java:97)
	at org.javers.core.graph.ObjectGraphBuilder.buildGraphFromCdo(ObjectGraphBuilder.java:65)
	at org.javers.core.graph.ObjectGraphBuilder.buildGraph(ObjectGraphBuilder.java:54)
	at org.javers.core.graph.LiveGraphFactory.createLiveGraph(LiveGraphFactory.java:38)
	at org.javers.core.diff.DiffFactory.buildGraph(DiffFactory.java:102)
	at org.javers.core.diff.DiffFactory.compare(DiffFactory.java:55)
	at org.javers.core.JaversCore.compare(JaversCore.java:176)

Steps To Reproduce
This issue can be reproduced by a simple test:

@Test
void testJaversBuilder() {
    var javers = JaversBuilder.javers().build()
    javers.compare(Path.of("foo"), Path.of("bar"))
}

A more elaborate test with a wrapping value-object class can be found here:
https://gist.github.com/LitschiW/ec39565305cf2fc911ddd4ad3f708f39

Javers' Version
7.3.6
also fails on 6.14.0

Additional context

According to microsoft/playwright-java#423 this issue might be related to google/gson#1875 which is unfortunately already marked fixed. Apparently, sun.nio.fs.UnixFileSystem and sun.nio.fs.WindowsFileSystem are package internal classes and therefore cannot be accessed via refection anymore in Java >=16 requiring an additional adapter.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions