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 202818 - API review: Introduced WebModuleExtender.save() method
Summary: API review: Introduced WebModuleExtender.save() method
Status: RESOLVED FIXED
Alias: None
Product: javaee
Classification: Unclassified
Component: Web Project (show other bugs)
Version: 7.1
Hardware: PC Linux
: P3 normal (vote)
Assignee: Martin Fousek
URL:
Keywords: API_REVIEW_FAST
Depends on:
Blocks: 200096 202807
  Show dependency tree
 
Reported: 2011-09-29 12:08 UTC by Martin Fousek
Modified: 2011-10-07 14:38 UTC (History)
3 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
apichange patch (3.90 KB, patch)
2011-09-29 12:08 UTC, Martin Fousek
Details | Diff
usage patch (18.85 KB, patch)
2011-09-29 12:23 UTC, Martin Fousek
Details | Diff
apichange patch v2 (4.14 KB, patch)
2011-09-30 08:09 UTC, Martin Fousek
Details | Diff
usage patch v2 (20.96 KB, patch)
2011-09-30 08:10 UTC, Martin Fousek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Fousek 2011-09-29 12:08:47 UTC
Created attachment 111307 [details]
apichange patch

I would like to add new method to the WebModuleExtender that would allow to save settings of WebModuleExtender which is already included into the project (after project customizer confirmation).

Use cases: changed preferred page language of JSF framework, added/removed JSF component library etc.

API stability: stable
Comment 1 Martin Fousek 2011-09-29 12:23:37 UTC
Created attachment 111308 [details]
usage patch 

Usage in web.project, web.jsf modules.
Comment 2 David Konecny 2011-09-29 23:14:15 UTC
DK01 - adding WebModuleExtender.save() method with empty body into abstract public API class is not 100% backward compatible because there can exist a client which already extended WebModuleExtender and defined a method with signature which may clash with the one you are adding, eg. with different return type; or a private one. There are few ways to make this change backward compatible, for example you could add

    public abstract class SavableWebModuleExtender extends WebModuleExtender {
        abstract void save();
    }

and in the JSF module check implementation class and based on that cast it to either WebModuleExtender or SavableWebModuleExtender. Or you could add inner class to WebModuleExtender:

    public interface Savable {
        void save();
    }

Using interface is better I think as it gives you more flexibility in future when you need to add other methods to WebModuleExtender. With abstract classes you may in long term end up with eg. SavablePrintableUpdatableXxxableWebModuleProvider.
Comment 3 Martin Fousek 2011-09-30 08:09:04 UTC
Created attachment 111344 [details]
apichange patch v2

DK01: fixed - I preferred interface as well, thanks
Comment 4 Martin Fousek 2011-09-30 08:10:51 UTC
Created attachment 111346 [details]
usage patch v2

Usage patch with few improvements.
Comment 5 Jesse Glick 2011-09-30 13:07:12 UTC
DK01 - it is binary compatible. It might not be source compatible, but an implementor affected by that could simply rename their preexisting method. Demo: create

---%<--- AbstractClassTest.java
public class AbstractClassTest {
    public static void main(String[] args) {
        A a = new I();
        a.run();
    }
}
---%<--- A.java
public abstract class A {
    public abstract void run();
}
---%<--- I.java
public class I extends A {
    @Override public void run() {
        System.err.println(save());
    }
    private String save() {
        return "I.save";
    }
}
---%<---

and run. Now add to AbstractClassTest.java:

        a.save();

and to A.java:

    public void save() {
        System.err.println("A.save");
    }

and run again (without recompiling I.class). You get

I.save
A.save

as expected.

Anyway, if you do want to introduce a new method and do not want to add it to the existing SPI class, adding a nested interface suffers from the potential problem that it is not well discoverable. In this case it may not matter - e.g. if most impls will not in fact be savable, and you are adding the method only for one or two special cases - but in general it does, in which case you would just create WebModuleProvider2. While this could _extend_ WebModuleProvider, that still does not make it clear that you ought to be extending the new interface; so it would be recommended to make a fresh interface (not abstract class) and simply deprecate the old one. Then it is clear to all existing implementors that they are using an older version of the API and should migrate; and the lookup code need not do instanceof checks, but merely find all WMP2's and then secondarily all WMP's.
Comment 6 David Konecny 2011-10-02 21:11:31 UTC
Savable interface is reasonable comprise I think. Doing it properly and introducing WebModuleProvider2 interface would also require changing WebFrameworkProvider (another abstract SPI class producing WebModuleProvider*) which is too much work not worth it.
Comment 7 Martin Fousek 2011-10-03 09:33:10 UTC
Although Jesse's solution is smoother, my best opinion is to choose nested interface too. Its usage will be probably quite rare because nobody missed the save() method for about 7 years of existence of this API. So since it would require a lot of rewrite in that API, the discoverability has not the biggest priority in this case, I mean.
Comment 8 Martin Fousek 2011-10-04 17:44:16 UTC
I'm going to integrate patch v2 tomorrow if no additional comments appear.
Comment 9 Martin Fousek 2011-10-06 07:15:17 UTC
Jesse, David, thanks for your review.

Integrated in web-main #549cabbebb4b.
Comment 10 Quality Engineering 2011-10-07 14:38:26 UTC
Integrated into 'main-golden'
Changeset: http://hg.netbeans.org/main-golden/rev/549cabbebb4b
User: Martin Fousek <marfous@netbeans.org>
Log: #202818 - API review: Introduced WebModuleExtender.save() method