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 91291

Summary: Project properties are saved on the AWT thread
Product: projects Reporter: Sherold Dev <sherold>
Component: Generic Projects UIAssignee: Milan Kubec <mkubec>
Status: RESOLVED FIXED    
Severity: blocker CC: abadea, issues, jtulach, mmirilovic, pjiricka, rnajman, tmysik
Priority: P2 Keywords: API, PERFORMANCE
Version: 6.x   
Hardware: All   
OS: All   
Issue Type: DEFECT Exception Reporter:
Bug Depends on: 123832    
Bug Blocks: 114345    
Attachments: patch file
context diff
patch file with javadoc fix
j2seproject with new API patch file

Description Sherold Dev 2006-12-19 17:52:30 UTC
If you close the project properties dialog of any project type, you will
experience UI freeze for several seconds. Please note that this will occur even
if you do not change anything. Please move the saving to some other thread and
provide appropriate UI feedback, waiting cursor for example.

Since the project properties dialog is used very often, this issue is highly
visible to all users of the IDE.
Comment 1 Jesse Glick 2006-12-19 20:35:33 UTC
Probably better to just figure out what is so slow and then make it faster.
Comment 2 Sherold Dev 2006-12-20 08:46:31 UTC
yes, this would be also a way to fix that
Comment 3 Milan Kubec 2007-01-11 09:37:33 UTC
I'm not able to reproduce any delay when closing Project Properties of
J2SEProject. Either modified of unmodified. What JDK do you use? What and how
many projects you have opened in IDE? How many files is opened in editor? Is
anything running in the IDE?
Comment 4 Radko Najman 2007-01-11 09:59:42 UTC
I can reproduce it everytime.

1. Start NetBeans
2. No project is opened
3. Create new J2SE project
4. Open project properties
5. Don't change anything and click OK
6. Gray rectangle is shown for 2 seconds in place where properties dialog was
shown. The IDE does not response this time.

Nothing else is running in the IDE. There is open only Main.java file which is
automatically opened when the project is created.

The IDE is not responsive for mentioned time with any JDK, the only difference
is that the gray rectangle is shown only with JDK 1.5 and lower, not with 1.6.
Comment 5 Milan Kubec 2007-01-11 10:16:50 UTC
Yes, I have already seen it, the critical information that was missing is "...
only with JDK 1.5 and lower, not with 1.6.". I was running on JDK 1.6.
Comment 6 Radko Najman 2007-01-11 10:21:46 UTC
To make it clear - it is not responsive on 1.6 as well, it is only not so
visible because the gray rectangle is not shown but the behaviour is the same.
Comment 7 Milan Kubec 2007-01-11 10:22:52 UTC
Of course :-)
Comment 8 _ rkubacki 2007-03-28 12:02:54 UTC
Long description of grey rectangle fix is at
http://weblogs.java.net/blog/chet/archive/2005/04/swing_update_no_1.html

Simple trick is to resize the window and if EDT is occupied by some long running
task it will not be redrawn again.
Comment 9 Milan Kubec 2007-08-05 20:31:10 UTC
Saving project properties is indeed done in AWT, but rescheduling the save outside of AWT would be very risky change
now, given that it can affect any project type. The UI freeze is visible only on JDK 1.5, on JDK 1.6 the gray rectangle
effect is fixed and UI looks responsive, of course the problem is still there but user won't probably notice that. There
was a fix in java/j2seproject which partially improve the behavior when saving project properties, see issue #99747 -
events about classpath change will be fired asynchronously.
Comment 10 Andrei Badea 2007-08-06 12:37:33 UTC
Issue 99747 claims to fix a problem introduced by the classpath exclude mechanism, so it probably doesn't address the
original problem. The 

Why is this being waived without trying the suggestion in desc2 first? Also, what is risky about rescheduling the save
to another thread? It probably needs to be done with a modal progress dialog, and it seems to be each project type would
have to do it explicitly.
Comment 11 Milan Kubec 2007-08-06 13:20:36 UTC
I didn't mean that issue #99747 fixes original problem. It fixed event firing that was done during saving project
properties synchronously, so it might improve performance.

Rescheduling anything in projects is always risky. Threading is also kind of API which others rely upon unknowingly.
Comment 12 Andrei Badea 2007-08-06 14:06:18 UTC
My idea was to let each project type save the customizer in a background worker thread explicitly (while displaying a
progress dialog). Specificall, this would be handled by the ActionListener that implementations of CustomizerProvider
pass to createCustomizerDialog(). It would not change anything in the ProjectCustomizer threading. But it would not work
well for the categories other than those registered by the project type. Also the progress dialog would not include all
the saveProject() calls (one is e.g. in XyzProjectProperties and another in CustomizerDialog). So if a dialog modal
dialog is to be displayed for the whole save operation, it would probably have to be in the customizer.
Comment 13 Milan Kubec 2007-08-21 11:02:00 UTC
I tried to use wait cursor in OptionListener in CustomizerDialog but it didn't work well.

Correct fix of the problem require substantial rewrite of the project customizer API, introducing new API, new threading
model and of course rewrite of all project types customizers. Estimated work seems to be from two weeks to one month
without rewrite needed in all project types. Changing threading in important part of project infrastructure just before
Beta1 is too risky and it can be source of new issues. I was told that this rewrite was already planed around 4.0, but
was deferred because of lack of resources and potential impact of the change. Hence I'm proposing again to waive this
issue for NB 6.0 release.
Comment 14 Jaroslav Tulach 2007-08-21 13:19:46 UTC
If the save inside AWT is really very visible performance problem, then I think we can implement low risk, compatible 
solution even for 6.0:

The general idea is to add new "store" listener - one that is called after the OK button listener, outside of AWT 
thread.

That way the project types can split its logic. In the existing OK button listener, just get the data from the UI 
elements and models. And in the "store" listener (which is called later from a non-AWT thread) really store them and 
do all the expensive processing.

As far as I can tell this means addition of three-four methods:

ProjectCustomizer.createCustomizerDialog(...., ActionListener okButtonListener, ActionListener storeListener, ...)
ProjectCustomizer.Category.setStoreListener(ActionListener l);
ProjectCustomizer.Category.getStoreListener();

plus some unit tests to guarantee that without use of the new methods everything behaves compatibly with 5.x and with 
new methods the store is called after and outside of AWT thread. 

Indeed, each project that wishes to benefit from this enhanced behaviou, has to use the new methods, but that is a 
price for low level impact, compatible implementation.
Comment 15 Milan Kubec 2007-08-24 14:28:44 UTC
Created attachment 47314 [details]
patch file
Comment 16 Milan Kubec 2007-08-24 14:44:51 UTC
I've attached patch file with implementation proposed by Jarda. Special listener can be provided that will do the time
consuming save operation. When the listener is executed IDE is blocked by modal dialog with progress bar. Current
implementation works without any change. The only difference from previous implementation for code that doesn't use new
API is that save of project metadata is now done off AWT EQ (only if the project itself is modified), but blocked by
modal dialog. Project type that would want to take advantage of this change needs to divide the processing of project
customizer into two parts - one that gathers data from components and models and the second that does save operation. It
means that it doesn't fix the original problem, but provides way to all project types to do it. Special store listener
can be also used for any category.
Comment 17 Milan Kubec 2007-08-27 08:16:47 UTC
I forgot to reassign to apireviews.
Comment 18 Milan Kubec 2007-08-27 09:26:01 UTC
Created attachment 47439 [details]
context diff
Comment 19 Jesse Glick 2007-08-27 15:51:32 UTC
Missing word or phrase in Javadoc: "Creates standard which can be used..."
Comment 20 Milos Kleint 2007-08-28 09:36:51 UTC
looks generally ok. Do you have a rewrite of j2seproject as sample reimplementation? Can you attach it to the issue?
Comment 21 Milan Kubec 2007-08-28 14:12:01 UTC
Created attachment 47612 [details]
patch file with javadoc fix
Comment 22 Milan Kubec 2007-08-28 14:14:22 UTC
Created attachment 47614 [details]
j2seproject with new API patch file
Comment 23 Milan Kubec 2007-08-28 14:17:23 UTC
I've attached patch file addressing Jesse's comment and also patch file with change in j2seproject.
Comment 24 Jesse Glick 2007-08-28 14:40:39 UTC
javadoc_fix.patch still seems to have "Creates standard which can be used for implementation...".
Comment 25 Milan Kubec 2007-08-29 07:55:25 UTC
Sorry, then I probably misunderstood your comment. Please explain what's wrong with javadoc and possibly provide some
hint. Thanks
Comment 26 Milan Kubec 2007-08-29 16:06:48 UTC
I will integrate the patch tomorrow (including fixed javadoc).
Comment 27 Jesse Glick 2007-08-29 16:46:02 UTC
"patch file with javadoc fix" still contains one method with a missing word "dialog" or similar:

+    /** Creates standard which can be used for implementation
                        ^^^
+     * of {@link org.netbeans.spi.project.ui.CustomizerProvider}. Use this version if you need 
+     * to run processing of the customizer data partially off AWT Event Queue. You don't need
+     * to call <code>pack()</code> method on the dialog. The resulting dialog will
+     * be non-modal. <br>
+     * Call <code>show()</code> on the dialog to make it visible. If you want the dialog to be
+     * closed after user presses the "OK" button you have to call hide() and dispose() on it.
+     * (Usually in the <code>actionPerformed(...)</code> method of the listener
+     * you provided as a parameter. In case of the click on the "Cancel" button
+     * the dialog will be closed automatically.
+     * @since org.netbeans.modules.projectuiapi/1 1.25
+     * @param categories array of descriptions of categories to be shown in the
+     *        dialog. Note that categories have the <code>valid</code>
+     *        property. If any of the given categories is not valid cusomizer's
+     *        OK button will be disabled until all categories become valid
+     *        again.
+     * @param componentProvider creator of GUI components for categories in the
+     *        customizer dialog.
+     * @param preselectedCategory name of one of the supplied categories or null.
+     *        Category with given name will be selected. If  <code>null</code>
+     *        or if the category of given name does not exist the first category will
+     *        be selected.
+     * @param okOptionListener listener which will be notified when the user presses
+     *        the OK button.
+     * @param storeListener listener which will be notified when the user presses OK button.
+     *        Listener will be executed after okOptionListener outside of AWT EventQueue.
+     *        Usually to be used to save modified files on disk.
+     * @param helpCtx Help context for the dialog, which will be used when the
+     *        panels in the customizer do not specify their own help context.
+     * @return standard project customizer dialog.
+     */
+    public static Dialog createCustomizerDialog( Category[] categories,
+                                                 CategoryComponentProvider componentProvider,
+                                                 String preselectedCategory,
+                                                 ActionListener okOptionListener,
+                                                 ActionListener storeListener,
+                                                 HelpCtx helpCtx ) {
Comment 28 Milan Kubec 2007-08-30 10:23:47 UTC
Fixed by providing new methods in API to allow to run time consuming part of project customizer processing outside of
AWT Event Queue. Project types that want to take advantage of it needs to fix their code.

Checking in src/org/netbeans/modules/project/uiapi/CustomizerDialog.java;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/CustomizerDialog.java,v  <--  CustomizerDialog.java
new revision: 1.13; previous revision: 1.12
done
Checking in src/org/netbeans/modules/project/uiapi/Bundle.properties;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/Bundle.properties,v  <--  Bundle.properties
new revision: 1.17; previous revision: 1.16
done
RCS file: /cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.java,v
done
Checking in src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.java;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.java,v  <-- 
SavingProjectDataPanel.java
initial revision: 1.1
done
RCS file: /cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.form,v
done
Checking in src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.form;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.form,v  <-- 
SavingProjectDataPanel.form
initial revision: 1.1
done
RCS file: /cvs/projects/projectuiapi/test/unit/src/org/netbeans/spi/project/ui/support/ProjectCustomizerListenersTest.java,v
done
Checking in test/unit/src/org/netbeans/spi/project/ui/support/ProjectCustomizerListenersTest.java;
/cvs/projects/projectuiapi/test/unit/src/org/netbeans/spi/project/ui/support/ProjectCustomizerListenersTest.java,v  <--
 ProjectCustomizerListenersTest.java
initial revision: 1.1
done
Checking in apichanges.xml;
/cvs/projects/projectuiapi/apichanges.xml,v  <--  apichanges.xml
new revision: 1.33; previous revision: 1.32
done
Checking in nbproject/project.xml;
/cvs/projects/projectuiapi/nbproject/project.xml,v  <--  project.xml
new revision: 1.21; previous revision: 1.20
done
Checking in src/org/netbeans/spi/project/ui/support/ProjectCustomizer.java;
/cvs/projects/projectuiapi/src/org/netbeans/spi/project/ui/support/ProjectCustomizer.java,v  <--  ProjectCustomizer.java
new revision: 1.16; previous revision: 1.15
done
Comment 29 Milan Kubec 2007-08-30 11:14:46 UTC
Fixed for j2seproject.

Checking in CustomizerProviderImpl.java;
/cvs/java/j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerProviderImpl.java,v  <-- 
CustomizerProviderImpl.java
new revision: 1.13; previous revision: 1.12
done
Comment 30 Milan Kubec 2007-10-04 08:58:40 UTC
Reverting of the API fix for running saving of project properties off AWT EQ. 
API was considered as dangerous with possibility of causing various deadlocks (e.g. issue #114535).

j2seproject fix was already reverted as part of issue #114535 issue fix.
Comment 31 Milan Kubec 2007-10-04 09:01:22 UTC
Revert commit log:

IDE: [10/4/07 9:55 AM] Committing started
Checking in src/org/netbeans/modules/project/uiapi/CustomizerDialog.java;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/CustomizerDialog.java,v  <--  CustomizerDialog.java
new revision: 1.15; previous revision: 1.14
done
Checking in src/org/netbeans/modules/project/uiapi/Bundle.properties;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/Bundle.properties,v  <--  Bundle.properties
new revision: 1.20; previous revision: 1.19
done
Removing src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.java;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.java,v  <-- 
SavingProjectDataPanel.java
new revision: delete; previous revision: 1.2
done
Removing src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.form;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.form,v  <-- 
SavingProjectDataPanel.form
new revision: delete; previous revision: 1.1
done
Removing test/unit/src/org/netbeans/spi/project/ui/support/ProjectCustomizerListenersTest.java;
/cvs/projects/projectuiapi/test/unit/src/org/netbeans/spi/project/ui/support/ProjectCustomizerListenersTest.java,v  <--
 ProjectCustomizerListenersTest.java
new revision: delete; previous revision: 1.2
done
Checking in apichanges.xml;
/cvs/projects/projectuiapi/apichanges.xml,v  <--  apichanges.xml
new revision: 1.35; previous revision: 1.34
done
Checking in nbproject/project.xml;
/cvs/projects/projectuiapi/nbproject/project.xml,v  <--  project.xml
new revision: 1.23; previous revision: 1.22
done
Checking in src/org/netbeans/spi/project/ui/support/ProjectCustomizer.java;
/cvs/projects/projectuiapi/src/org/netbeans/spi/project/ui/support/ProjectCustomizer.java,v  <--  ProjectCustomizer.java
new revision: 1.19; previous revision: 1.18
done
Comment 32 Milan Kubec 2007-10-09 15:31:30 UTC
No objections against waiver - considered as approved.
Comment 33 Milan Kubec 2008-01-09 13:37:11 UTC
Fixed. Commiting back storeListener to allow to save project properties off AWT EQ. Fixed in j2seproject, webproject,
ejbjarproject and clientproject.

Checking in projects/projectuiapi/src/org/netbeans/modules/project/uiapi/Bundle.properties;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/Bundle.properties,v  <--  Bundle.properties
new revision: 1.21; previous revision: 1.20
done
Checking in projects/projectuiapi/src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.form;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.form,v  <-- 
SavingProjectDataPanel.form
new revision: 1.3; previous revision: 1.2
done
Checking in projects/projectuiapi/src/org/netbeans/modules/project/uiapi/CustomizerDialog.java;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/CustomizerDialog.java,v  <--  CustomizerDialog.java
new revision: 1.16; previous revision: 1.15
done
Checking in projects/projectuiapi/src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.java;
/cvs/projects/projectuiapi/src/org/netbeans/modules/project/uiapi/SavingProjectDataPanel.java,v  <-- 
SavingProjectDataPanel.java
new revision: 1.4; previous revision: 1.3
done
Checking in j2ee/ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/customizer/CustomizerProviderImpl.java;
/cvs/j2ee/ejbjarproject/src/org/netbeans/modules/j2ee/ejbjarproject/ui/customizer/CustomizerProviderImpl.java,v  <-- 
CustomizerProviderImpl.java
new revision: 1.20; previous revision: 1.19
done
Checking in projects/projectuiapi/nbproject/project.properties;
/cvs/projects/projectuiapi/nbproject/project.properties,v  <--  project.properties
new revision: 1.35; previous revision: 1.34
done
Checking in projects/projectuiapi/nbproject/project.xml;
/cvs/projects/projectuiapi/nbproject/project.xml,v  <--  project.xml
new revision: 1.24; previous revision: 1.23
done
Checking in java/j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerProviderImpl.java;
/cvs/java/j2seproject/src/org/netbeans/modules/java/j2seproject/ui/customizer/CustomizerProviderImpl.java,v  <-- 
CustomizerProviderImpl.java
new revision: 1.16; previous revision: 1.15
done
Checking in projects/projectapi/src/org/netbeans/api/project/ProjectManager.java;
/cvs/projects/projectapi/src/org/netbeans/api/project/ProjectManager.java,v  <--  ProjectManager.java
new revision: 1.40; previous revision: 1.39
done
Checking in j2ee/clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/customizer/CustomizerProviderImpl.java;
/cvs/j2ee/clientproject/src/org/netbeans/modules/j2ee/clientproject/ui/customizer/CustomizerProviderImpl.java,v  <-- 
CustomizerProviderImpl.java
new revision: 1.11; previous revision: 1.10
done
Checking in projects/projectuiapi/apichanges.xml;
/cvs/projects/projectuiapi/apichanges.xml,v  <--  apichanges.xml
new revision: 1.36; previous revision: 1.35
done
Checking in projects/projectuiapi/test/unit/src/org/netbeans/spi/project/ui/support/ProjectCustomizerListenersTest.java;
/cvs/projects/projectuiapi/test/unit/src/org/netbeans/spi/project/ui/support/ProjectCustomizerListenersTest.java,v  <--
 ProjectCustomizerListenersTest.java
new revision: 1.4; previous revision: 1.3
done
Checking in projects/projectapi/test/unit/src/org/netbeans/api/project/ProjectManagerTest.java;
/cvs/projects/projectapi/test/unit/src/org/netbeans/api/project/ProjectManagerTest.java,v  <--  ProjectManagerTest.java
new revision: 1.17; previous revision: 1.16
done
Checking in web/project/src/org/netbeans/modules/web/project/ui/customizer/CustomizerProviderImpl.java;
/cvs/web/project/src/org/netbeans/modules/web/project/ui/customizer/CustomizerProviderImpl.java,v  <-- 
CustomizerProviderImpl.java
new revision: 1.20; previous revision: 1.19
done
Checking in projects/projectuiapi/src/org/netbeans/spi/project/ui/support/ProjectCustomizer.java;
/cvs/projects/projectuiapi/src/org/netbeans/spi/project/ui/support/ProjectCustomizer.java,v  <--  ProjectCustomizer.java
new revision: 1.20; previous revision: 1.19
done
Comment 34 Tomas Mysik 2008-01-09 15:46:52 UTC
Fixed in EarProject as well. Thanks Milan for fixing this in Java EE area.

Checking in src/org/netbeans/modules/j2ee/earproject/ui/customizer/CustomizerProviderImpl.java;
/cvs/j2ee/earproject/src/org/netbeans/modules/j2ee/earproject/ui/customizer/CustomizerProviderImpl.java,v  <--  
CustomizerProviderImpl.java
new revision: 1.3; previous revision: 1.2
done
Comment 35 Milan Kubec 2008-03-31 14:37:41 UTC
It seems that part of this fix was rollbacked by mkleint by fixing issue #44035 = reopening.
Comment 36 Milan Kubec 2008-04-01 07:41:32 UTC
To make it clear - the only project type that doesn't contain this fix is j2seproject.
Comment 37 Milan Kubec 2008-04-01 08:35:31 UTC
Pushed back again to main:

http://hg.netbeans.org/main/rev/7e9138744004

j2seproject fix won't be available for NetBeans 6.1 because the rollback was discovered late in the release cycle. Other
project types contain the fix.
Comment 38 Quality Engineering 2008-09-20 05:41:14 UTC
Integrated into 'main-golden', will be available in build *200809200201* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main/rev/9839724a6882
User: Milan Kubec <mkubec@netbeans.org>
Log: #146072: reverting runAtomicAction part of the fix for issue #91291; might cause undefined behavior