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.
Summary: | pushing Next button on first New Wizard panel fails | ||
---|---|---|---|
Product: | qa | Reporter: | Mikhail Romanov <mromanov> |
Component: | Jellytools | Assignee: | issues@qa <issues> |
Status: | CLOSED INVALID | ||
Severity: | blocker | ||
Priority: | P1 | ||
Version: | 3.x | ||
Hardware: | PC | ||
OS: | Windows ME/2000 | ||
Issue Type: | DEFECT | Exception Reporter: |
Description
Mikhail Romanov
2002-12-19 20:57:19 UTC
I cannot reproduce it on our machines. I need more info about the failure. Could you attach stack trace of exception, screenshot or test log? What JDK version do you use? It happens for me almost each time. However the following code works fine for me (it's a Shura's recomendation): public static NewWizardOperator invoke(Node node, String templatePath) { if(node == null || templatePath == null || templatePath.equals("")) { throw new JemmyException("Cannot accept null parameters."); } new NewTemplateAction().perform(node); ChooseTemplateStepOperator ctso = new ChooseTemplateStepOperator(); ctso.verify(); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ctso.selectTemplate(templatePath); ctso.next(); We can add verify() method into NewWizardOperator. But I don't know why it fails without it. It shouldn't fail because jemmy should wait until Next button is enabled before it tries to click on it. Please, could you attach or send me stack trace of exception and jemmy log file. I want to investigate why it fails. The problem is that one can never know for sure that once button is added to the panel, it already has all required listeners registered for it for proper work. Here is the possible scenario which will fail: - create JButton - add it to JPanel ---> at this moment Jemmy finds the button and posts event to event queue; however no listeners are added to the button yet, so the event is just ignored - add listeners to JButton ---> this is the correct time to post the event ... Calling verify won't solve the problem, but it'll increase the probability, that all required listeners are added to the components (so actually it's a kind of "smart" timeout in this case). All right, it's not that simple. I've done some research through openide and core sources: listener is always added prior to adding of a button on container: //from NbPresenter.java for (int i = 0; i < currentPrimaryButtons.length; i++) { modifyListener(currentPrimaryButtons[i], buttonListener, true); // add button listener panelForPrimary.add(currentPrimaryButtons[i]); } Listener itself can not add any problem either: //from WizardDescriptor.Listener public void actionPerformed (ActionEvent ev) { if (ev.getSource () == nextButton) { panels.nextPanel (); ... } ... } However there is a possibility that next panel has not been created yet //from WizardDescriptor.ArrayIterator public synchronized void nextPanel () { if (index + 1 == panels.length) throw new java.util.NoSuchElementException (); index++; } But, in this case, some exception should be visible somewhere, shouldn't it? Misha, do you see anything like that? Generally, in order to understand if "verify()" invocation is a full solution (or just a "smart timeout") we need to understand what's going on. I'm afraid that could be done only by source code analysis. Today, after some experiments around this problem, I've got the following exception in the output (probably it can help you in searching the root of the problem): org.netbeans.jemmy.JemmyException: Exception in java.awt.event.MouseEvent event dispatching at org.netbeans.jemmy.QueueTool.invokeAndWait(Unknown Source) at org.netbeans.jemmy.QueueTool.invokeSmoothly(Unknown Source) at org.netbeans.jemmy.drivers.input.EventDriver.dispatchEvent(Unknown Source) at org.netbeans.jemmy.drivers.input.MouseEventDriver.dispatchEvent(Unknown Source) at org.netbeans.jemmy.drivers.input.MouseEventDriver.clickMouse(Unknown Source) at org.netbeans.jemmy.drivers.buttons.ButtonMouseDriver.push(Unknown Source) at org.netbeans.jemmy.operators.AbstractButtonOperator.push(Unknown Source) at org.netbeans.jellytools.WizardOperator.next(Unknown Source) at org.netbeans.jellytools.NewWizardOperator.invoke(Unknown Source) at util.gui.dialogs.NewWizardCommonDialog.<init>(NewWizardCommonDialog.java:33) at util.gui.dialogs.ejb.NewWizardCommonEJB.<init>(NewWizardCommonEJB.java:29) at util.gui.dialogs.ejb.NewWizardEntityBean.<init>(NewWizardEntityBean.java:29) at util.gui.toolkits.ejb.EJBToolkit.createEntityEJB(EJBToolkit.java:70) at util.gui.toolkits.ejb.EJBToolkit.createEJB(EJBToolkit.java:54) at util.j2ee.assembly.J2EEAssembler.assemble(J2EEAssembler.java:93) at util.j2ee.J2EEApplication.assemble(J2EEApplication.java:63) at common.SITest.assemble(SITest.java:94) at ri.deployment.RIDeploymentTest.start_test(RIDeploymentTest.java:38) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at util.TestExecutor.run(TestExecutor.java:134) at ri.deployment.RIDeploymentXTestFS.testRIDeploymentAccountFS(RIDeploymentXTestFS.java:24) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at junit.framework.TestCase.runTest(TestCase.java:166) at junit.framework.TestCase.runBare(TestCase.java:140) at org.netbeans.jellytools.JellyTestCase.runBare(Unknown Source) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:131) at org.netbeans.junit.NbTestCase.run(NbTestCase.java:76) at junit.framework.TestSuite.runTest(TestSuite.java:173) at junit.framework.TestSuite.run(TestSuite.java:168) at org.netbeans.xtest.junit.JUnitTestRunnerExt.run(JUnitTestRunnerExt.java:249) at org.netbeans.xtest.junit.JUnitTaskExt.executeInVM(JUnitTaskExt.java:482) at org.netbeans.xtest.junit.JUnitTaskExt.execute(JUnitTaskExt.java:304) at org.netbeans.xtest.junit.JUnitTaskExt.execute(JUnitTaskExt.java:280) at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:166) at org.apache.tools.ant.Task.perform(Task.java:319) at org.apache.tools.ant.Target.execute(Target.java:309) at org.apache.tools.ant.Target.performTasks(Target.java:336) at org.apache.tools.ant.Project.executeTarget(Project.java:1306) at org.netbeans.xtest.AntRunner.run(AntRunner.java:76) at org.netbeans.xtest.AntRunner.main(AntRunner.java:27) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:324) at org.openide.execution.ThreadExecutor.executeClass(ThreadExecutor.java:116) at org.openide.execution.ThreadExecutor$TERunnable.run(ThreadExecutor.java:183) at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:118) Inner exception: java.lang.NullPointerException at com.sun.forte4j.j2ee.ejb.wizard.CreateSessionEJBWizard.current(CreateSessionEJBWizard.java:74) at com.sun.forte4j.j2ee.ejb.wizard.GenericEJBWizard.removeChangeListener(GenericEJBWizard.java:49) at org.openide.loaders.TemplateWizardIterImpl.setIterator(TemplateWizardIterImpl.java:65) at org.openide.loaders.TemplateWizard.setTemplateImpl(TemplateWizard.java:165) at org.openide.loaders.TemplateWizard1.implStoreSettings(TemplateWizard1.java:492) at org.openide.loaders.TemplateWizardPanel1.storeSettings(TemplateWizardPanel1.java:112) at org.openide.WizardDescriptor.updateState(WizardDescriptor.java:450) at org.openide.loaders.TemplateWizard.updateState(TemplateWizard.java:571) at org.openide.WizardDescriptor$Listener.actionPerformed(WizardDescriptor.java:991) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1764) at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(AbstractButton.java:1817) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:419) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:257) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:245) at java.awt.Component.processMouseEvent(Component.java:5093) at java.awt.Component.processEvent(Component.java:4890) at java.awt.Container.processEvent(Container.java:1566) at java.awt.Component.dispatchEventImpl(Component.java:3598) at java.awt.Container.dispatchEventImpl(Container.java:1623) at java.awt.Component.dispatchEvent(Component.java:3439) at org.netbeans.jemmy.drivers.input.EventDriver$Dispatcher.launch(Unknown Source) at org.netbeans.jemmy.QueueTool$QueueAction.run(Unknown Source) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:171) at java.awt.EventQueue.dispatchEvent(EventQueue.java:448) at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:197) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:140) at java.awt.Dialog.show(Dialog.java:538) at org.netbeans.core.NbPresenter.superShow(NbPresenter.java:685) at org.netbeans.core.NbPresenter.run(NbPresenter.java:718) at org.openide.util.Mutex$1.run(Mutex.java:930) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:171) at java.awt.EventQueue.dispatchEvent(EventQueue.java:448) at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:197) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:144) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:136) at java.awt.EventDispatchThread.run(EventDispatchThread.java:99) Please have a look at the inner exception. I'm getting it very consistently on the recent Nevada FFJ build and I belive it points on the real cause of the problem. From the exception it seems that wizardPanels array in CreateSessionEJBWizard.java is null at line 74. But it is a question for responsible developer why. Are you able to reproduce similar failure creating a different object from template than EBJ (e.g. Java Classes|Main)? If not, please file a bug againts EJB module with appropriate description. We've performed a brainstorm with Misha, here is what's, probably, happening. Exception happens on this line: //from CreateSessionEJBWizard public WizardDescriptor.Panel current () { if (wizardPanels[getCurrentPanelIndex()] == null) { //this one (I) wizardPanels[getCurrentPanelIndex()] = createWizardPanel (wizardPanelClasses [getCurrentPanelIndex()]); } ... } It can only means that wizardPanels is null. wizardPanels is initialized here: //from CreateSessionEJBWizard protected void initialize () { wizState = new CreateEJBWizardState (CreateEJBWizardHelper.SESSION, "Session"); //NOI18N wizState.setCurrentHelper (wizState.getHelper (CMT)); wizardPanels = new WizardDescriptor.Panel [wizardPanelClasses.length]; //here (II) wizardPanels[0] = new CreateEJBPropsPanel (wizState); } So, as we can see, by the time the button is pressed, CreateSessionEJBWizard.initialize() method has not performed yet. This method is invoked during CreateSessionEJBWizard creation: //from TemplateWizard private TemplateWizard (TemplateWizardIterImpl it) { super (it); //(III) we'll talk about it later this.iterator = it; // pass this to iterator iterator.initialize(this); //(IV) here! ... } Buttons are added on panel here: //from NbPresenter: protected final void initializeButtons() { ... panelForPrimary.add(currentPrimaryButtons[i]); //here (V) ... panelForSecondary.add(currentSecondaryButtons[i]); //or here (V) ... currentButtonsPanel.add(currentPrimaryButtons[i], gbc); //or here (V) ... currentButtonsPanel.add(currentSecondaryButtons[i], gbc); //or here (V) ... } initializeButtons() method is invoked as a result of PropertyChangeEvent processing: //from NbPresenter: public void propertyChange(final java.beans.PropertyChangeEvent evt) { ... if (DialogDescriptor.PROP_OPTIONS.equals(evt.getPropertyName())) { initializeButtons(); //here (VI) update = true; } else if (DialogDescriptor.PROP_OPTION_TYPE.equals(evt.getPropertyName())) { ... } The event is posted by PropertyChangeSupport class instance during creating of WizardDescriptor: //from NotifyDescriptor: protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { if (changeSupport != null) { //changeSupport is an instance of PropertyChangeSupport changeSupport.firePropertyChange(propertyName, oldValue, newValue); //here (VII) } } //from NotifyDescriptor public void setOptions(Object[] newOptions) { Object[] oldOptions = options; options = newOptions; firePropertyChange(PROP_OPTIONS, oldOptions, newOptions); //here (VIII) } //from WizardDescriptor: public WizardDescriptor (Iterator panels, Object settings) { ... nextButton.addActionListener (listener); previousButton.addActionListener (listener); finishButton.addActionListener (listener); cancelButton.addActionListener (listener); super.setOptions (new Object[] { previousButton, nextButton, finishButton, cancelButton }); //here (IX) ... } One important thing is that PropertyChangeSupport passes event to listeners directly - not through the EventQueue. Finally, WizardDescriptor constructor is invoked from TemplateWizard cunstructor at (III) line. Thus, buttons are displayed _before_ the array initialization, and though it seems most unlikely, during the time between (III) and (IV) lines (more exactly between (I) and (V) lines) Jemmy is able to find the button and even push it. Well, at least it is the only explanation we have. This might be caused by using two-processor machine - I do not know about that. So that's what's happening. Let's take a look on verify() method using. Verify simply checks existing of all known subcomponents, and, particularly, the templates tree. Now, if NewWizardOperator pushes button, it means that it has already found a template tree and selected a template in it. Which means that tree has already been displayed anyway. So, although I do not know why verify() makes tests more stable, it's just a workaround. Full solution would be to wait for the array to be initialized. May be it's possible, may be not - I am not aware if there are such public interface. Anyway it is not a good solutions since we tie the implementation to internal API. Another solution whould be to implement a timeout: "NewWizardOperator.AfterWizardTimeout" or something like that, so tester can set this timeout to nonzero value whenever he executes tests on dual-processor machines. I, personally, vote for this one, if anything. Finally, we need to create a bug. It will have low priority, bacause it is hardly reproducible, but it needs to be created, because, theoretically, user can push the button very fast (or, vise versa, NB will work very slow). I even can propose a fix: actions performed in CreateSessionEJBWizard.initialize() need to be moved to constructor. From where I sit, TemplateWizard.Iterator.initialize(TemplateWizard) method is designed for the purposes of an Iterator initialization, when intialization needs to be done with knowledges about the TemplateWizard. In GenericEJBWizard class (superclass of CreateSessionEJBWizard), initialize(TemplateWizard) simply invokes initialize() which is wrong using of the design idea. It is a great investigation. We should definitely create a bug. In Issuzila such bugs have keyword T9Y (testability) and priority can be from medium to high because automated tests are important. If they fix the bug quickly, we don't need to do anything. If they not, I would add a timeout as Shura suggested. Misha, could you please tell us what's going on with that bug you opened against EJB? Looks like this bug was caused by improper initialization sequence in S1S EJB wizards (bugs # 4797676 and 4799932). Now, when wizard bug is fixed and integrated, I can not reproduce this bug anymore. My suggestion is to close it as invalid (as it is S1S bug rather than Jellytools bug). It's a bug in S1S. |