This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 32815 - Visual editing fails and corrupts the code if constractor or property get method throws an Exception
Summary: Visual editing fails and corrupts the code if constractor or property get met...
Status: RESOLVED WORKSFORME
Alias: None
Product: guibuilder
Classification: Unclassified
Component: Code (show other bugs)
Version: -S1S-
Hardware: PC Windows 3.1/NT
: P3 blocker (vote)
Assignee: issues@guibuilder
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-04-11 00:41 UTC by greenbee
Modified: 2003-04-16 16:28 UTC (History)
0 users

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
Form file for the test case (1.49 KB, text/plain)
2003-04-11 00:44 UTC, greenbee
Details
Code for the test case (1.21 KB, text/plain)
2003-04-11 00:45 UTC, greenbee
Details
second form file for the test case (549 bytes, text/plain)
2003-04-11 00:46 UTC, greenbee
Details
second java file (792 bytes, text/plain)
2003-04-11 00:47 UTC, greenbee
Details

Note You need to log in before you can comment on or make changes to this bug.
Description greenbee 2003-04-11 00:41:30 UTC
I am developing a complex database application
where one of my components connects to the
database within a constructor to fill up some
values. Database URL and driver it receives from
system properties that are placed there by the
main method of the top frame. The component itself
is JPanel descendant. I have edited this component
and when I tried to integrate it to the main
container IDE threw an exception refering to my
class. After that java code for the component was
corrupted, i.e. several JButtons and some other
fields of the top container appeared in my
component code (in the guarded section) but not in
the form file. I.e. they did not appear on the
form itself or component inspector. I could not
delete them using IDE browser or Java editor. I
had to resort to vim to fix the code.
In addition to that, index of the JTabbedPane in
the top frame got corrupted such that visual
editors showed 3 tabs when property inspector
showed 4 subcomponents. Mouse click on the fourth
subcomponent caused IndexOutOfBoundException in
the IDE:
Wed Apr 09 11:50:16 PDT 2003:
java.lang.IndexOutOfBoundsException: Index: 3, Tab
count: 3
java.lang.IndexOutOfBoundsException: Index: 3, Tab
count: 3
	at
javax.swing.JTabbedPane.checkIndex(JTabbedPane.java:1514)
	at
javax.swing.JTabbedPane.setSelectedIndex(JTabbedPane.java:458)
	at
org.netbeans.modules.form.layoutsupport.delegates.JTabbedPaneSupport.arrangeContainer(JTabbedPaneSupport.java:251)
	at
org.netbeans.modules.form.layoutsupport.LayoutSupportManager.arrangeContainer(LayoutSupportManager.java:603)
	at
org.netbeans.modules.form.FormDesigner.ensureComponentIsShown(FormDesigner.java:439)
	at
org.netbeans.modules.form.FormDesigner.addComponentToSelectionImpl(FormDesigner.java:376)
	at
org.netbeans.modules.form.ComponentInspector$NodeSelectedListener.propertyChange(ComponentInspector.java:158)
	at
java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:252)
	at
org.openide.explorer.ExplorerManager.setSelectedNodes(ExplorerManager.java:204)
	at
org.openide.explorer.ExplorerManager.setSelectedNodes1(ExplorerManager.java:316)
	at
org.openide.explorer.ExplorerManager.setExploredContextAndSelection(ExplorerManager.java:287)
	at
org.openide.explorer.view.BeanTreeView.selectionChanged(BeanTreeView.java:89)
	at
org.openide.explorer.view.TreeView.callSelectionChanged(TreeView.java:539)
	at
org.openide.explorer.view.TreeView$TreePropertyListener.run(TreeView.java:743)
	at org.openide.util.Mutex.postRequest(Mutex.java:860)
	at
org.openide.util.Mutex.postReadRequest(Mutex.java:346)
	at
org.openide.explorer.view.TreeView$TreePropertyListener.valueChanged(TreeView.java:713)
	at
javax.swing.tree.DefaultTreeSelectionModel.fireValueChanged(DefaultTreeSelectionModel.java:629)
	at
javax.swing.tree.DefaultTreeSelectionModel.notifyPathChange(DefaultTreeSelectionModel.java:1071)
	at
javax.swing.tree.DefaultTreeSelectionModel.setSelectionPaths(DefaultTreeSelectionModel.java:287)
	at
javax.swing.tree.DefaultTreeSelectionModel.setSelectionPath(DefaultTreeSelectionModel.java:170)
	at
javax.swing.JTree.setSelectionPath(JTree.java:1178)
	at
javax.swing.plaf.basic.BasicTreeUI.selectPathForEvent(BasicTreeUI.java:2190)
	at
javax.swing.plaf.basic.BasicTreeUI$MouseHandler.handleSelection(BasicTreeUI.java:2818)
	at
javax.swing.plaf.basic.BasicTreeUI$MouseHandler.mousePressed(BasicTreeUI.java:2779)
	at
java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:218)
	at
java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:217)
	at
java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:217)
	at
java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:217)
	at
java.awt.Component.processMouseEvent(Component.java:5018)
	at
java.awt.Component.processEvent(Component.java:4818)
	at
java.awt.Container.processEvent(Container.java:1380)
	at
java.awt.Component.dispatchEventImpl(Component.java:3526)
	at
java.awt.Container.dispatchEventImpl(Container.java:1437)
	at
java.awt.Component.dispatchEvent(Component.java:3367)
	at
java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3214)
	at
java.awt.LightweightDispatcher.processMouseEvent(Container.java:2926)
	at
java.awt.LightweightDispatcher.dispatchEvent(Container.java:2859)
	at
java.awt.Container.dispatchEventImpl(Container.java:1423)
	at
java.awt.Window.dispatchEventImpl(Window.java:1566)
	at
java.awt.Component.dispatchEvent(Component.java:3367)
	at
java.awt.EventQueue.dispatchEvent(EventQueue.java:445)
[catch] at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:190)
	at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:144)
	at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
	at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:130)
	at
java.awt.EventDispatchThread.run(EventDispatchThread.java:98)

Attemts to delete and add subcomponents cause
another exception in the IDE:

Wed Apr 09 12:22:44 PDT 2003:
java.lang.NullPointerException: <no message>
Annotation: Invalid value. The property
tabRunCount could not be set. Reason:
null
java.lang.reflect.InvocationTargetException
	at
sun.reflect.GeneratedMethodAccessor189.invoke(Unknown
Source)
	at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:324)
	at
org.netbeans.modules.form.RADProperty.getTargetValue(RADProperty.java:75)
	at
org.netbeans.modules.form.FormProperty.checkCurrentValue(FormProperty.java:660)
	at
org.netbeans.modules.form.FormProperty.getValue(FormProperty.java:162)
	at
org.openide.explorer.propertysheet.PropertyPanel$SimpleModel.getValue(PropertyPanel.java:1356)
	at
org.openide.explorer.propertysheet.PropertyPanel.updateEditor(PropertyPanel.java:622)
	at
org.openide.explorer.propertysheet.PropertyPanel.<init>(PropertyPanel.java:259)
	at
org.openide.explorer.propertysheet.PropertyPanel.<init>(PropertyPanel.java:265)
	at
org.openide.explorer.propertysheet.PropertySheetTab.fillProperties(PropertySheetTab.java:359)
	at
org.openide.explorer.propertysheet.PropertySheetTab.createPane(PropertySheetTab.java:310)
	at
org.openide.explorer.propertysheet.PropertySheetTab.<init>(PropertySheetTab.java:175)
	at
org.openide.explorer.propertysheet.PropertySheet.refreshPropertySheet(PropertySheet.java:463)
	at
org.openide.explorer.propertysheet.PropertySheet.access$1100(PropertySheet.java:52)
	at
org.openide.explorer.propertysheet.PropertySheet$3.run(PropertySheet.java:638)
	at
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:178)
	at
java.awt.EventQueue.dispatchEvent(EventQueue.java:443)
	at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:190)
	at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:144)
	at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
	at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:130)
	at
java.awt.EventDispatchThread.run(EventDispatchThread.java:98)
Caused by: java.lang.NullPointerException
	at
javax.swing.plaf.basic.BasicTableUI.getPreferredSize(BasicTableUI.java:908)
	at
javax.swing.JComponent.getPreferredSize(JComponent.java:1262)
	at
javax.swing.ScrollPaneLayout.layoutContainer(ScrollPaneLayout.java:767)
	at java.awt.Container.layout(Container.java:835)
	at java.awt.Container.doLayout(Container.java:825)
	at
java.awt.Container.validateTree(Container.java:903)
	at
java.awt.Container.validateTree(Container.java:910)
	at
java.awt.Container.validateTree(Container.java:910)
	at java.awt.Container.validate(Container.java:878)
	at
javax.swing.plaf.basic.BasicTabbedPaneUI.ensureCurrentLayout(BasicTabbedPaneUI.java:1145)
	at
javax.swing.plaf.basic.BasicTabbedPaneUI.getTabRunCount(BasicTabbedPaneUI.java:1171)
	at
javax.swing.JTabbedPane.getTabRunCount(JTabbedPane.java:892)
[catch] ... 23 more


The only solution was to remove the whole
JTabbedPane and recreate it. 

Similar situation appears with one of my other
subcomponents which does not have database access
within a constructor but it has method
getXXXList(). There is no corresponding XXXList
attribute. This method goes to the database and
retrieves some data and returns them in the
instance of java.util.List.
IDE consider it as readonly property (It shows
under bean properties in the browser) and tries to
invoke this method.
It threw SQLException and similarly corrupted the
code.

I spent 3 days investigating the problem and came
up with a simple, 100% reproduceable case. Here is
the scenario:
1. Create a class based on JFrame;
2. Create another class based on JPanel;
3. Edit second class constructor: add following
statement:
    throw new Exception("My test exception");
   after the initComponets() call;
4. compile second class;
5. In the browser select it and copy (Ctrl/C or
Right-Click/Copy);
6. Paste it to the first class (JFrame).

Here you are. You'll get an exception:

java.lang.Exception: My test exception
    at test1.<init>(test1.java:32)
    at
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)
    at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at
java.lang.reflect.Constructor.newInstance(Constructor.java:274)
    at java.lang.Class.newInstance0(Class.java:296)
    at java.lang.Class.newInstance(Class.java:249)
    at
org.openide.loaders.InstanceSupport.instanceCreate(InstanceSupport.java:208)
[catch] at
org.netbeans.modules.form.MetaComponentCreator.initComponentInstance(MetaComponentCreator.java:837)
    at
org.netbeans.modules.form.MetaComponentCreator.addVisualComponent(MetaComponentCreator.java:486)
    at
org.netbeans.modules.form.MetaComponentCreator.createAndAddComponent(MetaComponentCreator.java:227)
    at
org.netbeans.modules.form.MetaComponentCreator.createComponent(MetaComponentCreator.java:96)
    at
org.netbeans.modules.form.CopySupport$InstancePaste.paste(CopySupport.java:224)
    at
org.openide.actions.PasteAction.performAction(PasteAction.java:100)
    at
org.openide.util.actions.CallableSystemAction.actionPerformed(CallableSystemAction.java:69)
    at
org.netbeans.core.ModuleActions$1.run(ModuleActions.java:105)
    at org.openide.util.Task.run(Task.java:152)
    at
org.openide.util.RequestProcessor$ProcessorThread.run(RequestProcessor.java:622)


This test case does not corrupt the code, probably
because there are not much code there and no
additional components.

I consider this behavior as a major bug (showstopper).
I do not see workaround it other then rehauling
the whole design of my application.
In general I do not understand why IDE should
instantiate a class or invoke a method during the
graphic design.
I hope for the speedy resolution.
Comment 1 greenbee 2003-04-11 00:44:16 UTC
Created attachment 9855 [details]
Form file for the test case
Comment 2 greenbee 2003-04-11 00:45:27 UTC
Created attachment 9856 [details]
Code for the test case
Comment 3 greenbee 2003-04-11 00:46:41 UTC
Created attachment 9857 [details]
second form file for the test case
Comment 4 greenbee 2003-04-11 00:47:27 UTC
Created attachment 9858 [details]
second java file
Comment 5 Jaromir Uhrik 2003-04-11 12:49:42 UTC
Could you please try to reproduce it in the NB3.5. I am not able to
reproduce this issue in the last NB3.5 Beta build - decreasing the
priority to P3 for now.
Comment 6 Jaromir Uhrik 2003-04-11 12:53:02 UTC
Reassign to responsible developer.
Comment 7 Tomas Pavek 2003-04-14 10:52:10 UTC
> In general I do not understand why IDE should instantiate
> a class or invoke a method during the graphic design.

How do you expect the IDE can show you something in the designer if it
can't create an instance? The IDE works that way it tries to
instantiate exactly the components you give it so the design
corresponds to real application as much as possible. So the IDE *must*
create instances of your classes and call their methods. Throwing
exceptions from constructor or property getter methods violates the
JavaBeans spec. What do you suppose the IDE can do if you add a
component to the designed form, but the component cannot be
instantiated due to an exception? The only thing the IDE can do is to
notify you about the problem: the instance cannot be created. It's
generally bad design of the component in such case, not the IDE.

But I agree it definitely should not corrupt generated code or break
integrity of internal metadata (so making the whole form editor
unusable). That's what this bug report is about: the IDE must be
robust enough and handle exceptions from user components well.

I see you report this against S1S 4.1, that's based on NetBeans 3.3.x.
I think the problem with reporting and robustness are solved now
(NetBeans 3.5) - at least I don't see any problem with the attached
sample - the instantiation error is correctly reported. Could you
verify it? (You can download NetBeans 3.5 Beta at this time; or wait
for S1S 5 release alternatively too.)


Note: if you need your component(s) to behave that way (potentially
throwing exceptions) and it is not possible to set up correct
environment during graphics design (so the exceptions are unavoidable)
- and you still want to be able to use the components in the designer
- then you should make your components behave different when they are
used in designer environment. You can check the "design time" using
java.beans.Beans.isDesignTime() method, or by implementing
java.beans.DesignMode.

As for getXXXList(), it is recognized as a property automatically by
java.beans.Introspector. The IDE just tries to get value of each
property, so that's why the method is called. If you don't want the
method to be recognized as property, then write your own BeanInfo
class specifying exactly those properties that are relevant (writing
BeanInfo is always recommended). That's the standard JavaBeans' way...
Comment 8 Tomas Pavek 2003-04-16 16:28:23 UTC
I think NetBeans 3.5 reports the exceptions correctly (at least for
the attached test case) and does not currupt code. I'm not 100% sure
about the exception from getter method, but anyway, it just reveals
problems in user component.
I don't see what we could do more in NetBeans.