NPE when extending SignalListItemFactory in 1.12.0 #212

Closed
opened 2025-04-23 09:11:16 +02:00 by JFronny · 2 comments
JFronny commented 2025-04-23 09:11:16 +02:00 (Migrated from github.com)

When updating to this new version, java-gi tries to register my custom SignalListItemFactory classes.
However, it fails to find a memory layout (Types.getLayout) for SignalListItemFactory (neither a @Layout method nor a getMemoryLayout method exist for it), which causes the automated registration of my classes to fail.
This then causes any constructor invocation to fail, since these now use newGObject with my extended class.

Stacktrace for the suppressed Exception in Types.getLayout:

java.lang.NoSuchMethodException: org.gnome.gtk.SignalListItemFactory$SignalListItemFactoryClass.getMemoryLayout()
	at java.base/java.lang.Class.getDeclaredMethod(Class.java:2424)
	at io.github.jwharm.javagi.gobject.types.Types.getLayout(Types.java:863)
	at io.github.jwharm.javagi.gobject.types.Types.generateClassLayout(Types.java:762)
	at io.github.jwharm.javagi.gobject.types.Types.register(Types.java:1210)
	at io.github.jwharm.javagi.gobject.types.TypeCache.getType(TypeCache.java:190)
	at io.github.jwharm.javagi.gobject.types.Types.register(Types.java:1204)
	at io.github.jwharm.javagi.gobject.types.TypeCache.getType(TypeCache.java:190)
	at io.github.jwharm.javagi.gobject.InstanceCache.newGObject(InstanceCache.java:362)
	at org.gnome.gtk.SignalListItemFactory.<init>(SignalListItemFactory.java:109)
	at io.gitlab.jfronny.inceptum.gtk.control.KSignalListItemFactory.<init>(KSignalListItemFactory.kt:10)
	at io.gitlab.jfronny.inceptum.gtk.control.InstanceListEntryFactory.<init>(InstanceListEntryFactory.kt:24)
	at io.gitlab.jfronny.inceptum.gtk.window.MainWindow.<init>(MainWindow.kt:74)
	at io.gitlab.jfronny.inceptum.gtk.GtkMain.showGui$lambda$2(GtkMain.kt:44)
	at io.gitlab.jfronny.inceptum.gtk.GtkMain.setupApplication$lambda$4(GtkMain.kt:61)
	at org.gnome.gio.Application$ActivateCallback.upcall(Application.java:2151)
	at org.gnome.gio.Application.run(Application.java:1151)
	at io.gitlab.jfronny.inceptum.gtk.GtkMain.setupApplication(GtkMain.kt:63)
	at io.gitlab.jfronny.inceptum.gtk.GtkMain.showGui(GtkMain.kt:35)
	at io.gitlab.jfronny.inceptum.gtk.GtkMain.main(GtkMain.kt:27)

Stacktrace for the exception this causes in the constructor plus related logs:

09:08:12.279 main java-gi ERROR <unknown>: Cannot register type KSignalListItemFactory: java.lang.NullPointerException: No memory layout for class SignalListItemFactoryClass

09:08:12.280 main java-gi ERROR <unknown>: Cannot register type InstanceListEntryFactory: java.lang.NullPointerException: No TypeClass for class InstanceListEntryFactory

09:08:12.281 main java-gi ERROR <unknown>: Cannot register type KSignalListItemFactory: java.lang.NullPointerException: No memory layout for class SignalListItemFactoryClass

09:08:12.282 main java-gi ERROR <unknown>: Cannot register type InstanceListEntryFactory: java.lang.NullPointerException: No TypeClass for class InstanceListEntryFactory

java.lang.AssertionError: java.lang.NullPointerException: Cannot invoke "org.gnome.glib.Type.getValue()" because "objectType" is null
	at io.github.jwharm.javagi.gobject.InstanceCache.newGObject(InstanceCache.java:372)
	at org.gnome.gtk.SignalListItemFactory.<init>(SignalListItemFactory.java:109)
	at io.gitlab.jfronny.inceptum.gtk.control.KSignalListItemFactory.<init>(KSignalListItemFactory.kt:10)
	at io.gitlab.jfronny.inceptum.gtk.control.InstanceListEntryFactory.<init>(InstanceListEntryFactory.kt:24)
	at io.gitlab.jfronny.inceptum.gtk.window.MainWindow.<init>(MainWindow.kt:74)
	at io.gitlab.jfronny.inceptum.gtk.GtkMain.showGui$lambda$2(GtkMain.kt:44)
	at io.gitlab.jfronny.inceptum.gtk.GtkMain.setupApplication$lambda$4(GtkMain.kt:61)
	at org.gnome.gio.Application$ActivateCallback.upcall(Application.java:2151)
	at org.gnome.gio.Application.run(Application.java:1151)
	at io.gitlab.jfronny.inceptum.gtk.GtkMain.setupApplication(GtkMain.kt:63)
	at io.gitlab.jfronny.inceptum.gtk.GtkMain.showGui(GtkMain.kt:35)
	at io.gitlab.jfronny.inceptum.gtk.GtkMain.main(GtkMain.kt:27)
Caused by: java.lang.NullPointerException: Cannot invoke "org.gnome.glib.Type.getValue()" because "objectType" is null
	at io.github.jwharm.javagi.gobject.InstanceCache.newGObject(InstanceCache.java:365)
	... 11 more
Unrecoverable uncaught exception encountered. The VM will now exit
When updating to this new version, java-gi tries to register my custom `SignalListItemFactory` classes. However, it fails to find a memory layout (`Types.getLayout`) for `SignalListItemFactory` (neither a `@Layout` method nor a `getMemoryLayout` method exist for it), which causes the automated registration of my classes to fail. This then causes any constructor invocation to fail, since these now use `newGObject` with my extended class. Stacktrace for the suppressed Exception in `Types.getLayout`: ``` java.lang.NoSuchMethodException: org.gnome.gtk.SignalListItemFactory$SignalListItemFactoryClass.getMemoryLayout() at java.base/java.lang.Class.getDeclaredMethod(Class.java:2424) at io.github.jwharm.javagi.gobject.types.Types.getLayout(Types.java:863) at io.github.jwharm.javagi.gobject.types.Types.generateClassLayout(Types.java:762) at io.github.jwharm.javagi.gobject.types.Types.register(Types.java:1210) at io.github.jwharm.javagi.gobject.types.TypeCache.getType(TypeCache.java:190) at io.github.jwharm.javagi.gobject.types.Types.register(Types.java:1204) at io.github.jwharm.javagi.gobject.types.TypeCache.getType(TypeCache.java:190) at io.github.jwharm.javagi.gobject.InstanceCache.newGObject(InstanceCache.java:362) at org.gnome.gtk.SignalListItemFactory.<init>(SignalListItemFactory.java:109) at io.gitlab.jfronny.inceptum.gtk.control.KSignalListItemFactory.<init>(KSignalListItemFactory.kt:10) at io.gitlab.jfronny.inceptum.gtk.control.InstanceListEntryFactory.<init>(InstanceListEntryFactory.kt:24) at io.gitlab.jfronny.inceptum.gtk.window.MainWindow.<init>(MainWindow.kt:74) at io.gitlab.jfronny.inceptum.gtk.GtkMain.showGui$lambda$2(GtkMain.kt:44) at io.gitlab.jfronny.inceptum.gtk.GtkMain.setupApplication$lambda$4(GtkMain.kt:61) at org.gnome.gio.Application$ActivateCallback.upcall(Application.java:2151) at org.gnome.gio.Application.run(Application.java:1151) at io.gitlab.jfronny.inceptum.gtk.GtkMain.setupApplication(GtkMain.kt:63) at io.gitlab.jfronny.inceptum.gtk.GtkMain.showGui(GtkMain.kt:35) at io.gitlab.jfronny.inceptum.gtk.GtkMain.main(GtkMain.kt:27) ``` Stacktrace for the exception this causes in the constructor plus related logs: ``` 09:08:12.279 main java-gi ERROR <unknown>: Cannot register type KSignalListItemFactory: java.lang.NullPointerException: No memory layout for class SignalListItemFactoryClass 09:08:12.280 main java-gi ERROR <unknown>: Cannot register type InstanceListEntryFactory: java.lang.NullPointerException: No TypeClass for class InstanceListEntryFactory 09:08:12.281 main java-gi ERROR <unknown>: Cannot register type KSignalListItemFactory: java.lang.NullPointerException: No memory layout for class SignalListItemFactoryClass 09:08:12.282 main java-gi ERROR <unknown>: Cannot register type InstanceListEntryFactory: java.lang.NullPointerException: No TypeClass for class InstanceListEntryFactory java.lang.AssertionError: java.lang.NullPointerException: Cannot invoke "org.gnome.glib.Type.getValue()" because "objectType" is null at io.github.jwharm.javagi.gobject.InstanceCache.newGObject(InstanceCache.java:372) at org.gnome.gtk.SignalListItemFactory.<init>(SignalListItemFactory.java:109) at io.gitlab.jfronny.inceptum.gtk.control.KSignalListItemFactory.<init>(KSignalListItemFactory.kt:10) at io.gitlab.jfronny.inceptum.gtk.control.InstanceListEntryFactory.<init>(InstanceListEntryFactory.kt:24) at io.gitlab.jfronny.inceptum.gtk.window.MainWindow.<init>(MainWindow.kt:74) at io.gitlab.jfronny.inceptum.gtk.GtkMain.showGui$lambda$2(GtkMain.kt:44) at io.gitlab.jfronny.inceptum.gtk.GtkMain.setupApplication$lambda$4(GtkMain.kt:61) at org.gnome.gio.Application$ActivateCallback.upcall(Application.java:2151) at org.gnome.gio.Application.run(Application.java:1151) at io.gitlab.jfronny.inceptum.gtk.GtkMain.setupApplication(GtkMain.kt:63) at io.gitlab.jfronny.inceptum.gtk.GtkMain.showGui(GtkMain.kt:35) at io.gitlab.jfronny.inceptum.gtk.GtkMain.main(GtkMain.kt:27) Caused by: java.lang.NullPointerException: Cannot invoke "org.gnome.glib.Type.getValue()" because "objectType" is null at io.github.jwharm.javagi.gobject.InstanceCache.newGObject(InstanceCache.java:365) ... 11 more Unrecoverable uncaught exception encountered. The VM will now exit ```
jwharm commented 2025-04-23 21:38:07 +02:00 (Migrated from github.com)

Thanks for logging this issue.

In Java-GI 0.12.0, when you create a subclass of a GObject-derived type in Java (or Kotlin), it will automatically try to register the subclass as a new GType. In the past, this was an explicit action (using Types.register(MyClass.class)).

However, defining a new GType is only possible if the parent class can actually be subclassed in native code. The SignalListItemFactory gtype cannot be subclassed (the struct contents are not available in the gir data; it's even defined as a final type). In Java-GI 0.11.2 you could just create a subclass in Java/Kotlin, while native code would regard it as a normal Gtk.SignalListItemFactory.

I hadn't considered this case, so that's why this is now broken. I will add proper error handling for when a native class cannot be subclassed, to still allow it to be subclassed in Java/Kotlin, without automatically defining a new GType.

Thanks for logging this issue. In Java-GI 0.12.0, when you create a subclass of a GObject-derived type in Java (or Kotlin), it will automatically try to register the subclass as a new GType. In the past, this was an explicit action (using `Types.register(MyClass.class)`). However, defining a new GType is only possible if the parent class can actually be subclassed in native code. The SignalListItemFactory gtype cannot be subclassed (the struct contents are not available in the gir data; it's even defined as a final type). In Java-GI 0.11.2 you could just create a subclass in Java/Kotlin, while native code would regard it as a normal Gtk.SignalListItemFactory. I hadn't considered this case, so that's why this is now broken. I will add proper error handling for when a native class cannot be subclassed, to still allow it to be subclassed in Java/Kotlin, without automatically defining a new GType.
JFronny commented 2025-04-24 10:31:19 +02:00 (Migrated from github.com)

It might be cleaner to just make such classes final on the JVM side too.
But thanks for the hint! I can probably design something for my app that doesn't depend on inheritance but is still clean.

It might be cleaner to just make such classes final on the JVM side too. But thanks for the hint! I can probably design something for my app that doesn't depend on inheritance but is still clean.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
java-gi/java-gi#212
No description provided.