matthiasblaesing commented on issue #5774:
URL: https://github.com/apache/netbeans/issues/5774#issuecomment-1507539540
I think, that you are seeing a bug in the Introspector in the JDK, that just
showed up now by "luck".
<details>
<summary>Stacktrace</summary>
```
[exec] INFO: Cannot invoke "java.beans.PropertyDescriptor.getName()"
because "pd" is null
[exec] java.lang.NullPointerException: Cannot invoke
"java.beans.PropertyDescriptor.getName()" because "pd" is null
[exec] at
java.desktop/java.beans.Introspector.addPropertyDescriptor(Introspector.java:533)
[exec] at
java.desktop/java.beans.Introspector.addPropertyDescriptors(Introspector.java:570)
[exec] at
java.desktop/java.beans.Introspector.getTargetPropertyInfo(Introspector.java:496)
[exec] at
java.desktop/java.beans.Introspector.getBeanInfo(Introspector.java:448)
[exec] at
java.desktop/java.beans.Introspector.getBeanInfo(Introspector.java:195)
[exec] at org.openide.util.Utilities.getBeanInfo(Utilities.java:312)
[exec] [catch] at
org.netbeans.modules.form.FormUtils.getBeanInfo(FormUtils.java:1907)
[exec] at
org.netbeans.modules.form.RADComponent.createBeanInfo(RADComponent.java:456)
[exec] at
org.netbeans.modules.form.RADComponent.getBeanInfo(RADComponent.java:436)
[exec] at
org.netbeans.modules.form.RADComponent.initInstance(RADComponent.java:167)
[exec] at
org.netbeans.modules.form.GandalfPersistenceManager.restoreComponent(GandalfPersistenceManager.java:761)
[exec] at
org.netbeans.modules.form.GandalfPersistenceManager.loadComponent(GandalfPersistenceManager.java:949)
[exec] at
org.netbeans.modules.form.GandalfPersistenceManager.loadForm(GandalfPersistenceManager.java:484)
[exec] at
org.netbeans.modules.form.GandalfPersistenceManager.loadForm(GandalfPersistenceManager.java:260)
[exec] at
org.netbeans.modules.form.FormEditor$2.run(FormEditor.java:327)
[exec] at org.netbeans.modules.form.FormLAF$2.run(FormLAF.java:268)
[exec] at
org.netbeans.modules.openide.util.NbMutexEventProvider$Event.doEventAccess(NbMutexEventProvider.java:123)
[exec] at
org.netbeans.modules.openide.util.NbMutexEventProvider$Event.readAccess(NbMutexEventProvider.java:77)
[exec] at
org.netbeans.modules.openide.util.LazyMutexImplementation.readAccess(LazyMutexImplementation.java:71)
[exec] at org.openide.util.Mutex.readAccess(Mutex.java:232)
[exec] at
org.netbeans.modules.form.FormLAF.executeWithLookAndFeel(FormLAF.java:251)
[exec] at
org.netbeans.modules.form.FormEditor.loadFormData(FormEditor.java:324)
[exec] at
org.netbeans.modules.nbform.FormEditorSupport.loadOpeningForm(FormEditorSupport.java:436)
[exec] at
org.netbeans.modules.nbform.FormDesignerTC.loadForm(FormDesignerTC.java:256)
[exec] at
org.netbeans.modules.nbform.FormDesignerTC.access$300(FormDesignerTC.java:64)
[exec] at
org.netbeans.modules.nbform.FormDesignerTC$PreLoadTask$1.run(FormDesignerTC.java:245)
[exec] at
java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
[exec] at
java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
[exec] at
java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
[exec] at
java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
[exec] at
java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
[exec] at
java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
[exec] at
java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
[exec] at
org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:136)
[exec] at
java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
[exec] at
java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
[exec] at
java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
[exec] at
java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
[exec] at
java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
[exec] at
java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
[exec] java.beans.IntrospectionException: Method not found: setUI
[exec] at
java.desktop/java.beans.PropertyDescriptor.<init>(PropertyDescriptor.java:114)
[exec] at
com.mycompany.dummy.SectionPanelBeanInfo.getPdescriptor(SectionPanelBeanInfo.java:226)
[exec] at
com.mycompany.dummy.SectionPanelBeanInfo.getPropertyDescriptors(SectionPanelBeanInfo.java:779)
[exec] at
java.desktop/java.beans.Introspector.getPropertyDescriptors(Introspector.java:576)
[exec] at
java.desktop/java.beans.Introspector.getTargetPropertyInfo(Introspector.java:482)
[exec] at
java.desktop/java.beans.Introspector.getBeanInfo(Introspector.java:448)
[exec] at
java.desktop/java.beans.Introspector.getBeanInfo(Introspector.java:195)
[exec] at org.openide.util.Utilities.getBeanInfo(Utilities.java:312)
[exec] at
org.netbeans.modules.form.FormUtils.getBeanInfo(FormUtils.java:1907)
[exec] at
org.netbeans.modules.form.RADComponent.createBeanInfo(RADComponent.java:456)
[exec] at
org.netbeans.modules.form.RADComponent.getBeanInfo(RADComponent.java:436)
[exec] at
org.netbeans.modules.form.RADComponent.initInstance(RADComponent.java:167)
[exec] at
org.netbeans.modules.form.GandalfPersistenceManager.restoreComponent(GandalfPersistenceManager.java:761)
[exec] at
org.netbeans.modules.form.GandalfPersistenceManager.loadComponent(GandalfPersistenceManager.java:949)
[exec] at
org.netbeans.modules.form.GandalfPersistenceManager.loadForm(GandalfPersistenceManager.java:484)
[exec] at
org.netbeans.modules.form.GandalfPersistenceManager.loadForm(GandalfPersistenceManager.java:260)
[exec] at
org.netbeans.modules.form.FormEditor$2.run(FormEditor.java:327)
[exec] at org.netbeans.modules.form.FormLAF$2.run(FormLAF.java:268)
[exec] at
org.netbeans.modules.openide.util.NbMutexEventProvider$Event.doEventAccess(NbMutexEventProvider.java:123)
[exec] at
org.netbeans.modules.openide.util.NbMutexEventProvider$Event.readAccess(NbMutexEventProvider.java:77)
[exec] at
org.netbeans.modules.openide.util.LazyMutexImplementation.readAccess(LazyMutexImplementation.java:71)
[exec] at org.openide.util.Mutex.readAccess(Mutex.java:232)
[exec] at
org.netbeans.modules.form.FormLAF.executeWithLookAndFeel(FormLAF.java:251)
[exec] at
org.netbeans.modules.form.FormEditor.loadFormData(FormEditor.java:324)
[exec] at
org.netbeans.modules.nbform.FormEditorSupport.loadOpeningForm(FormEditorSupport.java:436)
[exec] at
org.netbeans.modules.nbform.FormDesignerTC.loadForm(FormDesignerTC.java:256)
[exec] at
org.netbeans.modules.nbform.FormDesignerTC.access$300(FormDesignerTC.java:64)
[exec] at
org.netbeans.modules.nbform.FormDesignerTC$PreLoadTask$1.run(FormDesignerTC.java:245)
[exec] at
java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
[exec] at
java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
[exec] at
java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
[exec] at
java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
[exec] at
java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
[exec] at
java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
[exec] at
java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
[exec] at
org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:136)
[exec] at
java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
[exec] at
java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
[exec] at
java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
[exec] at
java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
[exec] at
java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
[exec] at
java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
```
</details>
I traced it into the `com.sun.beans.introspect.ClassInfo`. See this:
```
matthias@enterprise:~/src/netbeans$ ~/bin/jdk-17/bin/jshell --add-exports
java.desktop/com.sun.beans.introspect=ALL-UNNAMED
| Welcome to JShell -- Version 17.0.4.1
| For an introduction type: /help intro
jshell>
com.sun.beans.introspect.ClassInfo.get(javax.swing.JPanel.class).getMethods().forEach(System.out::println)
public javax.accessibility.AccessibleContext
javax.swing.JPanel.getAccessibleContext()
public javax.swing.plaf.PanelUI javax.swing.JPanel.getUI()
public javax.swing.plaf.ComponentUI javax.swing.JPanel.getUI()
public java.lang.String javax.swing.JPanel.getUIClassID()
public void javax.swing.JPanel.setUI(javax.swing.plaf.PanelUI)
public void javax.swing.JPanel.updateUI()
jshell>
matthias@enterprise:~/src/netbeans$ ~/bin/jdk-19/bin/jshell --add-exports
java.desktop/com.sun.beans.introspect=ALL-UNNAMED
| Willkommen bei JShell - Version 19
| Geben Sie für eine Einführung Folgendes ein: /help intro
jshell>
com.sun.beans.introspect.ClassInfo.get(javax.swing.JPanel.class).getMethods().forEach(System.out::println)
public javax.accessibility.AccessibleContext
javax.swing.JPanel.getAccessibleContext()
public javax.swing.plaf.ComponentUI javax.swing.JPanel.getUI()
public javax.swing.plaf.PanelUI javax.swing.JPanel.getUI()
public java.lang.String javax.swing.JPanel.getUIClassID()
public void javax.swing.JPanel.setUI(javax.swing.plaf.PanelUI)
public void javax.swing.JPanel.updateUI()
jshell>
```
In `java.beans.PropertyDescriptor#getReadMethod` is this comment:
> // Since there can be multiple write methods but only one getter
> // method, find the getter method first so that you know what
the
> // property type is. For booleans, there can be "is" and "get"
> // methods. If an "is" method exists, this is the official
> // reader method so look for this one first.
The first sentence is not true (as visible above). The claim overlooks, that
java supports covariant returns, which is implemented by synthesized bridge
methods, that are added by the compiler.
`ClassInfo` iterates the methods and uses the first matching method. Then
the return type of that method is assumed to find the setter. The problem on
JDK 19 `public javax.swing.plaf.ComponentUI javax.swing.JPanel.getUI()` is
used, but there is no `public void
javax.swing.JPanel.setUI(javax.swing.plaf.ComponentUI)`.
I think the JDK introspector needs to improved to first consider
non-synthesized methods and non-bridge methods.
Please consider to report this upstream against OpenJDK.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists