Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
LitschiW opened this issue Dec 27, 2023 · 3 comments

Comments

@LitschiW
Copy link

LitschiW commented Dec 27, 2023

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.

@LitschiW
Copy link
Author

After looking into how the groovy metaclass is handled, I found that JaversBuilder#registerIgnoredClass(Path.class) fixes our issue by ignoring Path objects and prevents it from being build into the object graph.

However, it would still be nice to be able to compare Path objects or to have the ignore setting as an explicit option.

bartoszwalacik added a commit that referenced this issue Dec 31, 2023
added PathTypeAdapter for java.nio.file.Path
@bartoszwalacik
Copy link
Member

Hi @LitschiW thanks for reporting, I have added a proper type adapter for Path
#1351

@bartoszwalacik
Copy link
Member

fixed in 7.3.7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants