Skip to content

InaccessibleObjectException when accessing node properties #265

@ptziegler

Description

@ptziegler

This is an issue that started to pop up after updating our product to the Eclipse 2025-12. Trying to access some properties of a GEF edit part is no longer possible (both during recording and during replay) and instead fails with an InaccesibleObjectException.

Below the error we get during recording:

Contains: Failed to get property nodes for path "getTargetConnections()".
java.lang.reflect.InaccessibleObjectException: Unable to make public int java.util.Collections$EmptyList.size() accessible: module java.base does not "opens java.util" to unnamed module @58c48311
	at java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:391)
	at java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:367)
	at java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:315)
	at java.lang.reflect.Method.checkCanSetAccessible(Method.java:203)
	at java.lang.reflect.Method.setAccessible(Method.java:197)
	at org.eclipse.rcptt.tesla.swt.reflection.JavaMembersHelper.collectMembers(JavaMembersHelper.java:308)
	at org.eclipse.rcptt.tesla.swt.reflection.JavaMembersHelper.collectObjectMembers(JavaMembersHelper.java:295)
	at org.eclipse.rcptt.tesla.swt.reflection.JavaMembersHelper.fillProperties(JavaMembersHelper.java:121)
	at org.eclipse.rcptt.tesla.swt.reflection.JavaMembersHelper.fillProperties(JavaMembersHelper.java:94)
	at org.eclipse.rcptt.tesla.gef.GefModelMapper.getPropertyNodes(GefModelMapper.java:163)
	at org.eclipse.rcptt.tesla.recording.core.gef.GefFigureLocator.getNodeProperties(GefFigureLocator.java:657)
	at org.eclipse.rcptt.tesla.recording.core.gef.GefRecordingHelper.getNodeProperties(GefRecordingHelper.java:140)
	at org.eclipse.rcptt.tesla.ecl.internal.impl.commands.GetPropertyNodesService$1.run(GetPropertyNodesService.java:50)
	at org.eclipse.ui.internal.PendingSyncExec.run(PendingSyncExec.java:68)
	at org.eclipse.ui.internal.UILockListener.doPendingWork(UILockListener.java:166)
	at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40)
	at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:132)
	at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4137)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3753)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1147)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1038)
	at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
	at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:677)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:583)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:173)
	at de.dsa.prodis.automation.AutomationApplication.start(AutomationApplication.java:321)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:219)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:149)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:115)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:467)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:298)
	at jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.lang.reflect.Method.invoke(Method.java:580)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:615)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:563)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1415)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1387)

Under the idea of "integrity by default", the Java team is trying their hardest to make the method setAccessible(...) as unusable as possible, which then causes problems when RCPTT tries to load those properties.

private static void collectMembers(Class<?> clazz, MembersContainer acc) {
for (Field field : clazz.getDeclaredFields()) {
if (checkField(field)) {
field.setAccessible(true);
acc.addField(field);
}
}
for (Method method : clazz.getDeclaredMethods()) {
if (checkMethod(method)) {
method.setAccessible(true);
acc.addMethod(method);
}
}
Class<?> parent = clazz.getSuperclass();
if (parent != null) {
collectMembers(parent, acc);
}
}

In this specific case, the problem is caused by calling size() on a List. Which is a public method, so the call to setAccessible(...) should not be needed here. Perhaps it is already enough to only call this method for protected methods and/or fields?

If I understand this correctly, RCPTT also only accesses public members, unless enable.protected.members is enabled. Perhaps the call could also be guarded by that?

The reason why it shows up for us now is likely because one of the projects we include uses BurningWave to break Java encapsulation. This behavior is now disabled by default with the version we updated to.

Metadata

Metadata

Assignees

Labels

breakingBackward incompatible change

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions