[xwiki-devs] [Brainstorming] Handling "young" APIs for backward compatibility
Hi devs, We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s). This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR. However I've seen that we have added some CLIRR excludes after the vote was passed. I believe that the main issue we have is for "young" APIs that are not considered stable. Proposal 1: Internal package ========= * Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy. * If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle. The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR. Proposal 2: Experimental package ========= Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental. Proposal 3: Experimental Annotation ========= Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental". Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months). WDYT? Any other idea? Thanks -Vincent
On 05/03/2012 03:47 AM, Vincent Massol wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy. * If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
I like this. I have a number of APIs in /internal/ because they just haven't been through their write,use,feedback,refactor cycles. I think there should be a little bit of leniency on application of the rules since there are clear cases where what is technically API is almost certainly not used by anyone (Usually these are things which were should have been placed in /internal/ but were places in the main space by mistake.) In these cases, it seems that a regular proposal on the list would be fair. Caleb
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
WDYT? Any other idea?
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
On Thu, May 3, 2012 at 10:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy.
* If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle.
It's not clear for me how we can keep backward compatibility when adding a new method to an interface. What do you put in legacy?
* We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
+1 Thanks, Marius
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
WDYT? Any other idea?
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
On May 3, 2012, at 2:47 PM, Marius Dumitru Florea wrote:
On Thu, May 3, 2012 at 10:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy.
* If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle.
It's not clear for me how we can keep backward compatibility when adding a new method to an interface. What do you put in legacy?
Yep, I have no solution for this except adding a new interface that extends the old one and adds new APIs which means doing an instanceof in code requiring access to the new methods… The other idea but this is a bit science-fiction would to make the xwiki runtime a "polymorphic runtime" (™) ;) This means: * At runtime, use Byteman or a tool that can change bytecode and when loading a Class inject behavior. For example if a Job class had a new method MMM added, loading a class implementing Job would add a default implementation for MMM if such a method doesn't already exist. In short this means bringing our compile time aspects to runtime. That's probably not very easy to do. Ideas anyone? Thanks -Vincent
* We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
+1
Thanks, Marius
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
WDYT? Any other idea?
Thanks -Vincent
On Thu, May 3, 2012 at 9:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy.
This is not always so easy. It really depends on what we are working on. If this is a small, or minor addition, this should works, but for really new experimental features, this does not fit (ie: security component). First, you will mixup internal and experimental, which will not shows the intends and not helps collaborating on the new feature. Second, this will also influence the place for tests, which will need to be moved later as well. Third, you will not see potential access issue (package access), since you will mix packages that will be later split.
* If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
This should solve most of the above inconvenient, but I am not sure we really need that for new feature. Declaring the feature as experimental in the RN should be enough IMO.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
But you have titled Annotation, which is confusing !
WDYT? Any other idea?
I would be +0 for a mix of 1) and 2) depending on the situation, since 3) does not really help. I am not sure that cases motivating 2) really need it and that it is not overkill since recent major features are always known to be subject to some early deprecation and that we already list all deprecation in the RN so you may adapt your code rather quickly.
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO
On Thu, May 3, 2012 at 3:24 PM, Denis Gervalle <[email protected]> wrote:
On Thu, May 3, 2012 at 9:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy.
This is not always so easy. It really depends on what we are working on. If this is a small, or minor addition, this should works, but for really new experimental features, this does not fit (ie: security component). First, you will mixup internal and experimental, which will not shows the intends and not helps collaborating on the new feature. Second, this will also influence the place for tests, which will need to be moved later as well. Third, you will not see potential access issue (package access), since you will mix packages that will be later split.
* If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
This should solve most of the above inconvenient, but I am not sure we really need that for new feature. Declaring the feature as experimental in the RN should be enough IMO.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
But you have titled Annotation, which is confusing !
WDYT? Any other idea?
I would be +0 for a mix of 1) and 2) depending on the situation, since 3) does not really help. I am not sure that cases motivating 2) really need it and that it is not overkill since recent major features are always known to be subject to some early deprecation and that we already list all deprecation in the RN so you may adapt your code rather quickly.
Pretty much the same concerns than Denis: it's not as easy as you think to change package of a big project like rights or extension manager all the sudden. But I would vote -1 for 1) and -0 for 2) which is a bit better. IMO 3) is enough even if not perfect either. Also about adding new methods, that's really not the main issue of an experimental API in which we can potentially rename a bunch of methods because of a design change and an old API has the exact same issue so none of the proposal help in any way for this.
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne
On May 3, 2012, at 3:40 PM, Thomas Mortagne wrote:
On Thu, May 3, 2012 at 3:24 PM, Denis Gervalle <[email protected]> wrote:
On Thu, May 3, 2012 at 9:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy.
This is not always so easy. It really depends on what we are working on. If this is a small, or minor addition, this should works, but for really new experimental features, this does not fit (ie: security component). First, you will mixup internal and experimental, which will not shows the intends and not helps collaborating on the new feature. Second, this will also influence the place for tests, which will need to be moved later as well. Third, you will not see potential access issue (package access), since you will mix packages that will be later split.
* If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
This should solve most of the above inconvenient, but I am not sure we really need that for new feature. Declaring the feature as experimental in the RN should be enough IMO.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
But you have titled Annotation, which is confusing !
Actually we can have an annotation, since we can pass a description string :) So using an annotation is better than a javadoc tag. It also allows to relatively easily list all experimental apis with a tool that finds annotations statically. We're going to need this to put in the RN the list of experimental APIs.
WDYT? Any other idea?
I would be +0 for a mix of 1) and 2) depending on the situation, since 3) does not really help. I am not sure that cases motivating 2) really need it and that it is not overkill since recent major features are always known to be subject to some early deprecation and that we already list all deprecation in the RN so you may adapt your code rather quickly.
Pretty much the same concerns than Denis: it's not as easy as you think to change package of a big project like rights or extension manager all the sudden.
But I would vote -1 for 1) and -0 for 2) which is a bit better.
IMO 3) is enough even if not perfect either.
Also about adding new methods, that's really not the main issue of an experimental API in which we can potentially rename a bunch of methods because of a design change and an old API has the exact same issue so none of the proposal help in any way for this.
There's no issue with adding new methods with proposals 1 and 2 since clirr will not even check them :) With 3) it's harder since you'll need to manually add CLIRR excludes. The problem with CLIRR excludes is that you can only exclude a full file thus potentially hiding breakages. The other issue is that we'll need to review all CLIRR excludes one by one to verify if they're valid (ie code tagged experimental) or not (in which case deprecation+legacy should be used instead). I'm fine with strategy 3) but it's really important to have a limit as to how long an api remains experimental because otherwise we're going to have a lot of experimental apis that will never make it user-public and users are going to start using them and then be broken. Thanks -Vincent
Hi, I am +1 for option 3), but I would actually prefer it that, instead of adding a new annotation by ourselves (@Experimental), we reuse java's deprecation mechanism [1] (@Deprecated annotation + @deprecated javadoc). This way: - users will be warned directly in the IDE to stay away from those APIs - the compiler and other existing tools will warn about using the APIs - we can specify additional details and explanations in the @deprecated javadoc - the APIs can be public so we don`t need to move them around afterwards and we can avoid possible problems related to this; we just remove the @Deprecated annotation (as already mentioned in the @Experimental case). - we avoid complexity and headaches by not letting the deprecation/legacy process get in the way of the development of the new feature Now the only problem I see with the above is that it would be hard to programatically generate a list of young APIs, since there is no clear differentiation between deprecated and young API (other than the comment in the @deprecated javadoc). I don`t know if this is such a big problem, since the main goal is to keep users from using the APIs (for a while at least), or, if they do, to make them aware that they will need to refactor in the coming future. Thanks, Eduard ---------- [1] http://docs.oracle.com/javase/1.5.0/docs/guide/javadoc/deprecation/deprecati... On Thu, May 3, 2012 at 4:48 PM, Vincent Massol <[email protected]> wrote:
On May 3, 2012, at 3:40 PM, Thomas Mortagne wrote:
On Thu, May 3, 2012 at 3:24 PM, Denis Gervalle <[email protected]> wrote:
On Thu, May 3, 2012 at 9:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy.
This is not always so easy. It really depends on what we are working on. If this is a small, or minor addition, this should works, but for really new experimental features, this does not fit (ie: security component). First, you will mixup internal and experimental, which will not shows the intends and not helps collaborating on the new feature. Second, this will also influence the place for tests, which will need to be moved later as well. Third, you will not see potential access issue (package access), since you will mix packages that will be later split.
* If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
This should solve most of the above inconvenient, but I am not sure we really need that for new feature. Declaring the feature as experimental in the RN should be enough IMO.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
But you have titled Annotation, which is confusing !
Actually we can have an annotation, since we can pass a description string :) So using an annotation is better than a javadoc tag.
It also allows to relatively easily list all experimental apis with a tool that finds annotations statically. We're going to need this to put in the RN the list of experimental APIs.
does not really help. I am not sure that cases motivating 2) really need it and that it is not overkill since recent major features are always known to be subject to some early deprecation and that we already list all deprecation in the RN so you may adapt your code rather quickly.
Pretty much the same concerns than Denis: it's not as easy as you think to change package of a big project like rights or extension manager all the sudden.
But I would vote -1 for 1) and -0 for 2) which is a bit better.
IMO 3) is enough even if not perfect either.
Also about adding new methods, that's really not the main issue of an experimental API in which we can potentially rename a bunch of methods because of a design change and an old API has the exact same issue so none of the proposal help in any way for this.
WDYT? Any other idea?
I would be +0 for a mix of 1) and 2) depending on the situation, since
There's no issue with adding new methods with proposals 1 and 2 since clirr will not even check them :) With 3) it's harder since you'll need to manually add CLIRR excludes. The problem with CLIRR excludes is that you can only exclude a full file thus potentially hiding breakages. The other issue is that we'll need to review all CLIRR excludes one by one to verify if they're valid (ie code tagged experimental) or not (in which case deprecation+legacy should be used instead).
I'm fine with strategy 3) but it's really important to have a limit as to how long an api remains experimental because otherwise we're going to have a lot of experimental apis that will never make it user-public and users are going to start using them and then be broken.
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
Hi Edy, Thanks for joining in! :) See below On Oct 23, 2012, at 12:52 PM, Eduard Moraru <[email protected]> wrote:
Hi,
I am +1 for option 3), but I would actually prefer it that, instead of adding a new annotation by ourselves (@Experimental), we reuse java's deprecation mechanism [1] (@Deprecated annotation + @deprecated javadoc).
That's different. This is not about deprecated code, it's about new code, i.e. the exact opposite :)
This way: - users will be warned directly in the IDE to stay away from those APIs
- the compiler and other existing tools will warn about using the APIs - we can specify additional details and explanations in the @deprecated javadoc - the APIs can be public so we don`t need to move them around afterwards and we can avoid possible problems related to this; we just remove the @Deprecated annotation (as already mentioned in the @Experimental case). - we avoid complexity and headaches by not letting the deprecation/legacy process get in the way of the development of the new feature
Yes of course now personally I don't like 3 at all because it's very very maintenance-oriented (clirr excludes for example) and is going to cause a big mess: As I said in my original email the problem is that there's no rule to remove @Experimental so what will happen is that you'll find @Experimental code that stays in this state forever, 5 years after it's been started because there are always stuff to improve (it's the "1.0 syndrome"). I'm personally very very close to -1 solution 3 because it's almost the same as not doing anything. For me the only real answer is to do what Eclipse used to do (I don't know if they still do it) which is to: - code defensively, i.e. always put new code in the internal package (FTR I took this notion of internal from them, see http://jakarta.apache.org/cactus/participating/apis.html) - open up APIs based on need. This means that whenever someone (a user) needs an API he reports it and we then open it (if we consider the API is stable at the time and it's a valid need) - once it's opened go through the deprecation strategy Note that we've done that in a few places where we have component interfaces that are internal ATM. It's a good strategy to stabilize an API. What we would need to do is in the Developer guide on xwiki.org make it more visible that devs should not use internal package and if they miss an API to ask at such place for one (we could even have a jira issue type for that). Thomas and Denis argued that it's hard to do so for new domains like the new rights implementation. I still don't understand why. Could you guys explain what would have been difficult with the strategy above?
Now the only problem I see with the above is that it would be hard to
oh it's far from being the "only" problem ;) Just to cite 3 issues: - clirr excludes are very hard to manage/maintain and a pain - when to move out of "young api" is not defined - wrong semantic of deprecated Thanks -Vincent
programatically generate a list of young APIs, since there is no clear differentiation between deprecated and young API (other than the comment in the @deprecated javadoc). I don`t know if this is such a big problem, since the main goal is to keep users from using the APIs (for a while at least), or, if they do, to make them aware that they will need to refactor in the coming future.
Thanks, Eduard ---------- [1] http://docs.oracle.com/javase/1.5.0/docs/guide/javadoc/deprecation/deprecati...
On Thu, May 3, 2012 at 4:48 PM, Vincent Massol <[email protected]> wrote:
On May 3, 2012, at 3:40 PM, Thomas Mortagne wrote:
On Thu, May 3, 2012 at 3:24 PM, Denis Gervalle <[email protected]> wrote:
On Thu, May 3, 2012 at 9:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy.
This is not always so easy. It really depends on what we are working on. If this is a small, or minor addition, this should works, but for really new experimental features, this does not fit (ie: security component). First, you will mixup internal and experimental, which will not shows the intends and not helps collaborating on the new feature. Second, this will also influence the place for tests, which will need to be moved later as well. Third, you will not see potential access issue (package access), since you will mix packages that will be later split.
* If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
This should solve most of the above inconvenient, but I am not sure we really need that for new feature. Declaring the feature as experimental in the RN should be enough IMO.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
But you have titled Annotation, which is confusing !
Actually we can have an annotation, since we can pass a description string :) So using an annotation is better than a javadoc tag.
It also allows to relatively easily list all experimental apis with a tool that finds annotations statically. We're going to need this to put in the RN the list of experimental APIs.
does not really help. I am not sure that cases motivating 2) really need it and that it is not overkill since recent major features are always known to be subject to some early deprecation and that we already list all deprecation in the RN so you may adapt your code rather quickly.
Pretty much the same concerns than Denis: it's not as easy as you think to change package of a big project like rights or extension manager all the sudden.
But I would vote -1 for 1) and -0 for 2) which is a bit better.
IMO 3) is enough even if not perfect either.
Also about adding new methods, that's really not the main issue of an experimental API in which we can potentially rename a bunch of methods because of a design change and an old API has the exact same issue so none of the proposal help in any way for this.
WDYT? Any other idea?
I would be +0 for a mix of 1) and 2) depending on the situation, since
There's no issue with adding new methods with proposals 1 and 2 since clirr will not even check them :) With 3) it's harder since you'll need to manually add CLIRR excludes. The problem with CLIRR excludes is that you can only exclude a full file thus potentially hiding breakages. The other issue is that we'll need to review all CLIRR excludes one by one to verify if they're valid (ie code tagged experimental) or not (in which case deprecation+legacy should be used instead).
I'm fine with strategy 3) but it's really important to have a limit as to how long an api remains experimental because otherwise we're going to have a lot of experimental apis that will never make it user-public and users are going to start using them and then be broken.
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
On Tue, Oct 23, 2012 at 2:17 PM, Vincent Massol <[email protected]> wrote:
Hi Edy,
Thanks for joining in! :)
See below
On Oct 23, 2012, at 12:52 PM, Eduard Moraru <[email protected]> wrote:
Hi,
I am +1 for option 3), but I would actually prefer it that, instead of adding a new annotation by ourselves (@Experimental), we reuse java's deprecation mechanism [1] (@Deprecated annotation + @deprecated javadoc).
That's different. This is not about deprecated code, it's about new code, i.e. the exact opposite :)
This way: - users will be warned directly in the IDE to stay away from those APIs
- the compiler and other existing tools will warn about using the APIs - we can specify additional details and explanations in the @deprecated javadoc - the APIs can be public so we don`t need to move them around afterwards and we can avoid possible problems related to this; we just remove the @Deprecated annotation (as already mentioned in the @Experimental case). - we avoid complexity and headaches by not letting the deprecation/legacy process get in the way of the development of the new feature
Yes of course now personally I don't like 3 at all because it's very very maintenance-oriented (clirr excludes for example) and is going to cause a big mess: As I said in my original email the problem is that there's no rule to remove @Experimental so what will happen is that you'll find @Experimental code that stays in this state forever, 5 years after it's been started because there are always stuff to improve (it's the "1.0 syndrome").
I'm personally very very close to -1 solution 3 because it's almost the same as not doing anything.
For me the only real answer is to do what Eclipse used to do (I don't know if they still do it) which is to:
- code defensively, i.e. always put new code in the internal package (FTR I took this notion of internal from them, see http://jakarta.apache.org/cactus/participating/apis.html) - open up APIs based on need. This means that whenever someone (a user) needs an API he reports it and we then open it (if we consider the API is stable at the time and it's a valid need) - once it's opened go through the deprecation strategy
+1 On this topic we should decide what we do with script services. Do we apply the same strategy (keep internal until someone asks for it)? If not then, as Jerome pointed out in a different thread, we need to distinguish between script service interfaces and the rest of the component roles (APIs). Thanks, Marius
Note that we've done that in a few places where we have component interfaces that are internal ATM. It's a good strategy to stabilize an API.
What we would need to do is in the Developer guide on xwiki.org make it more visible that devs should not use internal package and if they miss an API to ask at such place for one (we could even have a jira issue type for that).
Thomas and Denis argued that it's hard to do so for new domains like the new rights implementation. I still don't understand why. Could you guys explain what would have been difficult with the strategy above?
Now the only problem I see with the above is that it would be hard to
oh it's far from being the "only" problem ;) Just to cite 3 issues:
- clirr excludes are very hard to manage/maintain and a pain - when to move out of "young api" is not defined - wrong semantic of deprecated
Thanks -Vincent
programatically generate a list of young APIs, since there is no clear differentiation between deprecated and young API (other than the comment in the @deprecated javadoc). I don`t know if this is such a big problem, since the main goal is to keep users from using the APIs (for a while at least), or, if they do, to make them aware that they will need to refactor in the coming future.
Thanks, Eduard ---------- [1] http://docs.oracle.com/javase/1.5.0/docs/guide/javadoc/deprecation/deprecati...
On Thu, May 3, 2012 at 4:48 PM, Vincent Massol <[email protected]> wrote:
On May 3, 2012, at 3:40 PM, Thomas Mortagne wrote:
On Thu, May 3, 2012 at 3:24 PM, Denis Gervalle <[email protected]> wrote:
On Thu, May 3, 2012 at 9:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy.
This is not always so easy. It really depends on what we are working on. If this is a small, or minor addition, this should works, but for really new experimental features, this does not fit (ie: security component). First, you will mixup internal and experimental, which will not shows the intends and not helps collaborating on the new feature. Second, this will also influence the place for tests, which will need to be moved later as well. Third, you will not see potential access issue (package access), since you will mix packages that will be later split.
* If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
This should solve most of the above inconvenient, but I am not sure we really need that for new feature. Declaring the feature as experimental in the RN should be enough IMO.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
But you have titled Annotation, which is confusing !
Actually we can have an annotation, since we can pass a description string :) So using an annotation is better than a javadoc tag.
It also allows to relatively easily list all experimental apis with a tool that finds annotations statically. We're going to need this to put in the RN the list of experimental APIs.
does not really help. I am not sure that cases motivating 2) really need it and that it is not overkill since recent major features are always known to be subject to some early deprecation and that we already list all deprecation in the RN so you may adapt your code rather quickly.
Pretty much the same concerns than Denis: it's not as easy as you think to change package of a big project like rights or extension manager all the sudden.
But I would vote -1 for 1) and -0 for 2) which is a bit better.
IMO 3) is enough even if not perfect either.
Also about adding new methods, that's really not the main issue of an experimental API in which we can potentially rename a bunch of methods because of a design change and an old API has the exact same issue so none of the proposal help in any way for this.
WDYT? Any other idea?
I would be +0 for a mix of 1) and 2) depending on the situation, since
There's no issue with adding new methods with proposals 1 and 2 since clirr will not even check them :) With 3) it's harder since you'll need to manually add CLIRR excludes. The problem with CLIRR excludes is that you can only exclude a full file thus potentially hiding breakages. The other issue is that we'll need to review all CLIRR excludes one by one to verify if they're valid (ie code tagged experimental) or not (in which case deprecation+legacy should be used instead).
I'm fine with strategy 3) but it's really important to have a limit as to how long an api remains experimental because otherwise we're going to have a lot of experimental apis that will never make it user-public and users are going to start using them and then be broken.
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
FWIW Guava is using a @Beta annotation: http://code.google.com/p/guava-libraries/ Extract: " APIs marked with the @Beta annotation at the class or method level are subject to change. They can be modified in any way, or even removed, in any major release. If your code is a library itself (i.e. it is used on the CLASSPATH of users outside your own control), you should not use beta APIs, unless you repackage them (e.g. using ProGuard). Here is a current list of all the beta APIs. Serialized forms of ALL objects are subject to change. Do not persist these and assume they can be read by a future version of the library. Deprecated non-beta APIs will be removed eighteen months after the release in which they are first deprecated. You must fix your usages before this time. If you don't, any manner of breakage might result (you are not guaranteed a compilation error). " Thanks -Vincent On May 3, 2012, at 9:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy. * If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
WDYT? Any other idea?
Thanks -Vincent
On Feb 7, 2013, at 5:52 PM, Vincent Massol <[email protected]> wrote:
FWIW Guava is using a @Beta annotation: http://code.google.com/p/guava-libraries/
Extract:
" APIs marked with the @Beta annotation at the class or method level are subject to change. They can be modified in any way, or even removed, in any major release. If your code is a library itself (i.e. it is used on the CLASSPATH of users outside your own control), you should not use beta APIs, unless you repackage them (e.g. using ProGuard). Here is a current list of all the beta APIs.
Serialized forms of ALL objects are subject to change. Do not persist these and assume they can be read by a future version of the library.
Deprecated non-beta APIs will be removed eighteen months after the release in which they are first deprecated. You must fix your usages before this time. If you don't, any manner of breakage might result (you are not guaranteed a compilation error). "
Interestingly a user points out the issue I had with using an annotation, see the comments in http://code.google.com/p/guava-libraries/wiki/Release10: Extract: " My understandig of @Beta is, that these are the higly unstable parts of guava, so I don't want to use them (and I guess most developers don't want to because why should anybody make his lives more difficult when moving to the next version). But how do I do that? I don't want to look all the time at the source code when programming to make sure I didn't use the beta parts. Code completion knows nothing about @Beta (and it shouldn't!). Hence I have to remove all the beta parts. But why should the user handle the repackaging thing when you can simple release two versions: a beta / instable version and a stable / release version. Simple as that. Anybody can use the version he likes. Other OSS projects handle this much better. The same goes vor versioning, naming, packaging, downloading, etc. E. g. I never had such fruitless discussions with Apache software (and in case Apache commons collection ever releases a "generified" version, I'll most certainly switch back to that). " Thanks -Vincent
Thanks -Vincent
On May 3, 2012, at 9:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy. * If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
WDYT? Any other idea?
Thanks -Vincent
On Feb 8, 2013, at 11:18 AM, Vincent Massol <[email protected]> wrote:
On Feb 7, 2013, at 5:52 PM, Vincent Massol <[email protected]> wrote:
FWIW Guava is using a @Beta annotation: http://code.google.com/p/guava-libraries/
Extract:
" APIs marked with the @Beta annotation at the class or method level are subject to change. They can be modified in any way, or even removed, in any major release. If your code is a library itself (i.e. it is used on the CLASSPATH of users outside your own control), you should not use beta APIs, unless you repackage them (e.g. using ProGuard). Here is a current list of all the beta APIs.
Serialized forms of ALL objects are subject to change. Do not persist these and assume they can be read by a future version of the library.
Deprecated non-beta APIs will be removed eighteen months after the release in which they are first deprecated. You must fix your usages before this time. If you don't, any manner of breakage might result (you are not guaranteed a compilation error). "
Interestingly a user points out the issue I had with using an annotation, see the comments in http://code.google.com/p/guava-libraries/wiki/Release10:
Extract:
" My understandig of @Beta is, that these are the higly unstable parts of guava, so I don't want to use them (and I guess most developers don't want to because why should anybody make his lives more difficult when moving to the next version).
But how do I do that? I don't want to look all the time at the source code when programming to make sure I didn't use the beta parts. Code completion knows nothing about @Beta (and it shouldn't!). Hence I have to remove all the beta parts. But why should the user handle the repackaging thing when you can simple release two versions: a beta / instable version and a stable / release version. Simple as that. Anybody can use the version he likes.
Other OSS projects handle this much better. The same goes vor versioning, naming, packaging, downloading, etc. E. g. I never had such fruitless discussions with Apache software (and in case Apache commons collection ever releases a "generified" version, I'll most certainly switch back to that). "
Actually, reading further it seems only one user has an issue with the @Beta annotation and others find it acceptable. ok so here's the summary of the brainstorming so far: * Proposal 1 (internal package): - Vincent - Marius * Proposal 2 (experimental package) - Caleb * Proposal 3 (@Beta/@Experimental annotation) - Thomas - Edy * Other proposal - Denis (use 1) for small changes and only use RN to mark new module as experimental) Note that with proposal 3 we also need to remember 2 things: - we'll need to add CLIRR excludes but that can be done globally using the global exclude so not too painful - we'll need to detail how long is the @Beta annotation supposed to stay. If it stays forever it's the same syndrome as never releasing a 1.0 version which doesn't help because people will use it in production anyway if it's too long to be 1.0. So proposal 3 needs to have a max timeframe. IMO a full cycle would be a good max time to remain @Beta annotations. So if you add the @Beta in version N.P we have to remove it before N+2.0 (in practice that's a max time of 1.5 years). We could also say N+1.P but it's harder to remember since it means verifying at each release whereas N+1.P means verifying only once. Personally I'm ok to try option 3 since I'd like to make progress on this. WDYT? Thanks -Vincent
Thanks -Vincent
Thanks -Vincent
On May 3, 2012, at 9:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy. * If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
WDYT? Any other idea?
Thanks -Vincent
On Fri, Feb 8, 2013 at 11:42 AM, Vincent Massol <[email protected]> wrote:
On Feb 8, 2013, at 11:18 AM, Vincent Massol <[email protected]> wrote:
On Feb 7, 2013, at 5:52 PM, Vincent Massol <[email protected]> wrote:
FWIW Guava is using a @Beta annotation: http://code.google.com/p/guava-libraries/
Extract:
" APIs marked with the @Beta annotation at the class or method level are subject to change. They can be modified in any way, or even removed, in any major release. If your code is a library itself (i.e. it is used on the CLASSPATH of users outside your own control), you should not use beta APIs, unless you repackage them (e.g. using ProGuard). Here is a current list of all the beta APIs.
Serialized forms of ALL objects are subject to change. Do not persist these and assume they can be read by a future version of the library.
Deprecated non-beta APIs will be removed eighteen months after the release in which they are first deprecated. You must fix your usages before this time. If you don't, any manner of breakage might result (you are not guaranteed a compilation error). "
Interestingly a user points out the issue I had with using an annotation, see the comments in http://code.google.com/p/guava-libraries/wiki/Release10:
Extract:
" My understandig of @Beta is, that these are the higly unstable parts of guava, so I don't want to use them (and I guess most developers don't want to because why should anybody make his lives more difficult when moving to the next version).
But how do I do that? I don't want to look all the time at the source code when programming to make sure I didn't use the beta parts. Code completion knows nothing about @Beta (and it shouldn't!). Hence I have to remove all the beta parts. But why should the user handle the repackaging thing when you can simple release two versions: a beta / instable version and a stable / release version. Simple as that. Anybody can use the version he likes.
Other OSS projects handle this much better. The same goes vor versioning, naming, packaging, downloading, etc. E. g. I never had such fruitless discussions with Apache software (and in case Apache commons collection ever releases a "generified" version, I'll most certainly switch back to that). "
Actually, reading further it seems only one user has an issue with the @Beta annotation and others find it acceptable.
ok so here's the summary of the brainstorming so far:
* Proposal 1 (internal package): - Vincent - Marius
* Proposal 2 (experimental package) - Caleb
* Proposal 3 (@Beta/@Experimental annotation) - Thomas - Edy
* Other proposal - Denis (use 1) for small changes and only use RN to mark new module as experimental)
Note that with proposal 3 we also need to remember 2 things: - we'll need to add CLIRR excludes but that can be done globally using the global exclude so not too painful - we'll need to detail how long is the @Beta annotation supposed to stay. If it stays forever it's the same syndrome as never releasing a 1.0 version which doesn't help because people will use it in production anyway if it's too long to be 1.0. So proposal 3 needs to have a max timeframe. IMO a full cycle would be a good max time to remain @Beta annotations. So if you add the @Beta in version N.P we have to remove it before N+2.0 (in practice that's a max time of 1.5 years). We could also say N+1.P but it's harder to remember since it means verifying at each release whereas N+1.P means verifying only once.
Personally I'm ok to try option 3 since I'd like to make progress on this.
WDYT?
Ok for me.
Thanks -Vincent
Thanks -Vincent
Thanks -Vincent
On May 3, 2012, at 9:47 AM, Vincent Massol <[email protected]> wrote:
Hi devs,
We have recently voted a rule where we said that we will do the following: * Always deprecate APIs * Always move them to Legacy modules * And when there's a technical issue to moving stuff to the Legacy module, only then, send a VOTE to remove an API (see http://markmail.org/message/tino4ngttflc5i3s).
This means that from now on (starting on 26th of April 2012) we're not allowed to put excludes in CLIRR.
However I've seen that we have added some CLIRR excludes after the vote was passed.
I believe that the main issue we have is for "young" APIs that are not considered stable.
Proposal 1: Internal package =========
* Young APIs must be located in the "internal" package till they become stable. I propose "internal" to reuse an existing package that we filter when testing for CLIRR. "internal" means that users should not use this API because it's considered unstable and can change at any time. * When a Young API is considered stable enough and we want to open it to public consumption then we move it from "internal" to its target package (that's easy to with IDEs). From that point forward any changes to them goes through the standard mechanism of deprecation/legacy. * If we want to add a new method to an existing public API then this should not be considered a "young" API. It's just an addition to an existing API and thus goes directly to the deprecation/legacy cycle. * We need to be careful to isolate "young" APIs from public API so that users don't inadvertently use "young" unstable APIs by mistake. If not possible then directly go through the deprecation/legacy cycle.
The advantage of this proposal is that it doesn't change our current practices and is very easy to verify through CLIRR.
Proposal 2: Experimental package =========
Another possibility I can think of is to introduce a new "experimental" package instead of reusing the "internal" one. It has the advantage of being able to follow "young" APIs and ensure they don't stay in that state indefinitely, while still allowing the user who uses it to notice it's experimental.
Proposal 3: Experimental Annotation =========
Another idea is to just use an @Experimental javadoc tag for experimental code. It has the advantage of using the target package but it has drawbacks: * It's impossible for users to notice that they're using Experimental APIs since when they import a class they won't see anything that'll tell them they're using a "young" API * It's almost impossible to tell CLIRR to exclude those APIs from its checks. The only way to do this is to modify the source code of the CLIRR plugin AFAIK. Thus we would need to exclude those manually using CLIRR excludes and thus before we release we would need to go over the full list of CLIRR excludes to ensure the excludes listed are only for "young" APIs marked "experimental".
Note that I mentioned javadoc tag and not annotation because I believe we need to add information about when the Experimental API was first introduced so that we eventually move it as a proper API by removing the Experimental tag. Maybe we would need a rule such as: keep that tag for less or equal to 3 full minor releases (i.e. 6 months).
WDYT? Any other idea?
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne
Doesn't the @deprecated annotation actually does exactly the job? (except it has to be interpreted as meaning something else than "old code", but "do not use code"). paul On 8 févr. 2013, at 12:45, Thomas Mortagne wrote:
* Proposal 1 (internal package): - Vincent - Marius
* Proposal 2 (experimental package) - Caleb
* Proposal 3 (@Beta/@Experimental annotation) - Thomas - Edy
* Other proposal - Denis (use 1) for small changes and only use RN to mark new module as experimental)
Hi Paul, On Feb 8, 2013, at 1:22 PM, Paul Libbrecht <[email protected]> wrote:
Doesn't the @deprecated annotation actually does exactly the job? (except it has to be interpreted as meaning something else than "old code", but "do not use code").
@Deprecated means something different. It's about some code that you shouldn't use because we no longer think it's good to use and it's going to be removed in the future. This is not what a @beta or @experimental annotation would mean. They would mean "this is a new api that you can use but it's not stable yet and may change in the future so be prepared to update your code if that happens". Thanks -Vincent
paul
On 8 févr. 2013, at 12:45, Thomas Mortagne wrote:
* Proposal 1 (internal package): - Vincent - Marius
* Proposal 2 (experimental package) - Caleb
* Proposal 3 (@Beta/@Experimental annotation) - Thomas - Edy
* Other proposal - Denis (use 1) for small changes and only use RN to mark new module as experimental)
On Fri, Feb 8, 2013 at 2:40 PM, Vincent Massol <[email protected]> wrote:
Hi Paul,
On Feb 8, 2013, at 1:22 PM, Paul Libbrecht <[email protected]> wrote:
Doesn't the @deprecated annotation actually does exactly the job? (except it has to be interpreted as meaning something else than "old code", but "do not use code").
@Deprecated means something different. It's about some code that you shouldn't use because we no longer think it's good to use and it's going to be removed in the future.
This is not what a @beta or @experimental annotation would mean. They would mean "this is a new api that you can use but it's not stable yet and may change in the future so be prepared to update your code if that happens".
Plus @deprecated is technically pretty stable API while @beta can be broken anytime.
Thanks -Vincent
paul
On 8 févr. 2013, at 12:45, Thomas Mortagne wrote:
* Proposal 1 (internal package): - Vincent - Marius
* Proposal 2 (experimental package) - Caleb
* Proposal 3 (@Beta/@Experimental annotation) - Thomas - Edy
* Other proposal - Denis (use 1) for small changes and only use RN to mark new module as experimental)
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne
+1, but I have the impression that @unstable would be more meaningful On Fri, Feb 8, 2013 at 2:49 PM, Thomas Mortagne <[email protected]>wrote:
On Fri, Feb 8, 2013 at 2:40 PM, Vincent Massol <[email protected]> wrote:
Hi Paul,
On Feb 8, 2013, at 1:22 PM, Paul Libbrecht <[email protected]> wrote:
Doesn't the @deprecated annotation actually does exactly the job? (except it has to be interpreted as meaning something else than "old code", but "do not use code").
@Deprecated means something different. It's about some code that you shouldn't use because we no longer think it's good to use and it's going to be removed in the future.
This is not what a @beta or @experimental annotation would mean. They would mean "this is a new api that you can use but it's not stable yet and may change in the future so be prepared to update your code if that happens".
Plus @deprecated is technically pretty stable API while @beta can be broken anytime.
Thanks -Vincent
paul
On 8 févr. 2013, at 12:45, Thomas Mortagne wrote:
* Proposal 1 (internal package): - Vincent - Marius
* Proposal 2 (experimental package) - Caleb
* Proposal 3 (@Beta/@Experimental annotation) - Thomas - Edy
* Other proposal - Denis (use 1) for small changes and only use RN to mark new module
as experimental)
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO
Yes it's more clear than "beta". On Fri, Feb 8, 2013 at 3:28 PM, Denis Gervalle <[email protected]> wrote:
+1, but I have the impression that @unstable would be more meaningful
On Fri, Feb 8, 2013 at 2:49 PM, Thomas Mortagne <[email protected]>wrote:
On Fri, Feb 8, 2013 at 2:40 PM, Vincent Massol <[email protected]> wrote:
Hi Paul,
On Feb 8, 2013, at 1:22 PM, Paul Libbrecht <[email protected]> wrote:
Doesn't the @deprecated annotation actually does exactly the job? (except it has to be interpreted as meaning something else than "old code", but "do not use code").
@Deprecated means something different. It's about some code that you shouldn't use because we no longer think it's good to use and it's going to be removed in the future.
This is not what a @beta or @experimental annotation would mean. They would mean "this is a new api that you can use but it's not stable yet and may change in the future so be prepared to update your code if that happens".
Plus @deprecated is technically pretty stable API while @beta can be broken anytime.
Thanks -Vincent
paul
On 8 févr. 2013, at 12:45, Thomas Mortagne wrote:
* Proposal 1 (internal package): - Vincent - Marius
* Proposal 2 (experimental package) - Caleb
* Proposal 3 (@Beta/@Experimental annotation) - Thomas - Edy
* Other proposal - Denis (use 1) for small changes and only use RN to mark new module
as experimental)
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne
By the way, if we agree on @unstable, I also think having another annotation for marking stable API that are not considered to be stable SPI. Why not something like @onlyAPI or @unstableSPI on an interface ? On Fri, Feb 8, 2013 at 3:30 PM, Thomas Mortagne <[email protected]>wrote:
Yes it's more clear than "beta".
On Fri, Feb 8, 2013 at 3:28 PM, Denis Gervalle <[email protected]> wrote:
+1, but I have the impression that @unstable would be more meaningful
On Fri, Feb 8, 2013 at 2:49 PM, Thomas Mortagne <[email protected]>wrote:
On Fri, Feb 8, 2013 at 2:40 PM, Vincent Massol <[email protected]> wrote:
Hi Paul,
On Feb 8, 2013, at 1:22 PM, Paul Libbrecht <[email protected]> wrote:
Doesn't the @deprecated annotation actually does exactly the job? (except it has to be interpreted as meaning something else than "old code", but "do not use code").
@Deprecated means something different. It's about some code that you shouldn't use because we no longer think it's good to use and it's going to be removed in the future.
This is not what a @beta or @experimental annotation would mean. They would mean "this is a new api that you can use but it's not stable yet and may change in the future so be prepared to update your code if that happens".
Plus @deprecated is technically pretty stable API while @beta can be broken anytime.
Thanks -Vincent
paul
On 8 févr. 2013, at 12:45, Thomas Mortagne wrote:
> * Proposal 1 (internal package): > - Vincent > - Marius > > * Proposal 2 (experimental package) > - Caleb > > * Proposal 3 (@Beta/@Experimental annotation) > - Thomas > - Edy > > * Other proposal > - Denis (use 1) for small changes and only use RN to mark new
module as experimental)
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO
On Feb 8, 2013, at 3:42 PM, Denis Gervalle <[email protected]> wrote:
By the way, if we agree on @unstable, I also think having another annotation for marking stable API that are not considered to be stable SPI. Why not something like @onlyAPI or @unstableSPI on an interface ?
I think first we need to define what is an SPI and what is an API first. ATM I don't think I understand clearly the difference in the context of XWiki. Is it clear for you? Thanks -Vincent
On Fri, Feb 8, 2013 at 3:30 PM, Thomas Mortagne <[email protected]>wrote:
Yes it's more clear than "beta".
On Fri, Feb 8, 2013 at 3:28 PM, Denis Gervalle <[email protected]> wrote:
+1, but I have the impression that @unstable would be more meaningful
On Fri, Feb 8, 2013 at 2:49 PM, Thomas Mortagne <[email protected]>wrote:
On Fri, Feb 8, 2013 at 2:40 PM, Vincent Massol <[email protected]> wrote:
Hi Paul,
On Feb 8, 2013, at 1:22 PM, Paul Libbrecht <[email protected]> wrote:
Doesn't the @deprecated annotation actually does exactly the job? (except it has to be interpreted as meaning something else than "old code", but "do not use code").
@Deprecated means something different. It's about some code that you shouldn't use because we no longer think it's good to use and it's going to be removed in the future.
This is not what a @beta or @experimental annotation would mean. They would mean "this is a new api that you can use but it's not stable yet and may change in the future so be prepared to update your code if that happens".
Plus @deprecated is technically pretty stable API while @beta can be broken anytime.
Thanks -Vincent
paul
On 8 févr. 2013, at 12:45, Thomas Mortagne wrote:
>> * Proposal 1 (internal package): >> - Vincent >> - Marius >> >> * Proposal 2 (experimental package) >> - Caleb >> >> * Proposal 3 (@Beta/@Experimental annotation) >> - Thomas >> - Edy >> >> * Other proposal >> - Denis (use 1) for small changes and only use RN to mark new
module as experimental)
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
On Fri, Feb 8, 2013 at 3:58 PM, Vincent Massol <[email protected]> wrote:
On Feb 8, 2013, at 3:42 PM, Denis Gervalle <[email protected]> wrote:
By the way, if we agree on @unstable, I also think having another annotation for marking stable API that are not considered to be stable SPI. Why not something like @onlyAPI or @unstableSPI on an interface ?
I think first we need to define what is an SPI and what is an API first. ATM I don't think I understand clearly the difference in the context of XWiki. Is it clear for you?
I do not really understand your question. The general definition is rather clear: "Service Provider Interface (SPI) is an API intended to be implemented or extended by a third party". What I would like to be annotated is API that we do not consider stable SPI at the moment. It is less restrictive than @unstable, but more than not saying anything. Is that answering your question ?
Thanks -Vincent
On Fri, Feb 8, 2013 at 3:30 PM, Thomas Mortagne <[email protected]>wrote:
Yes it's more clear than "beta".
On Fri, Feb 8, 2013 at 3:28 PM, Denis Gervalle <[email protected]> wrote:
+1, but I have the impression that @unstable would be more meaningful
On Fri, Feb 8, 2013 at 2:49 PM, Thomas Mortagne <[email protected]>wrote:
On Fri, Feb 8, 2013 at 2:40 PM, Vincent Massol <[email protected]> wrote:
Hi Paul,
On Feb 8, 2013, at 1:22 PM, Paul Libbrecht <[email protected]> wrote:
> Doesn't the @deprecated annotation actually does exactly the job? > (except it has to be interpreted as meaning something else than "old code", but "do not use code").
@Deprecated means something different. It's about some code that you shouldn't use because we no longer think it's good to use and it's going to be removed in the future.
This is not what a @beta or @experimental annotation would mean. They would mean "this is a new api that you can use but it's not stable yet and may change in the future so be prepared to update your code if that happens".
Plus @deprecated is technically pretty stable API while @beta can be broken anytime.
Thanks -Vincent
> paul > > > On 8 févr. 2013, at 12:45, Thomas Mortagne wrote: > >>> * Proposal 1 (internal package): >>> - Vincent >>> - Marius >>> >>> * Proposal 2 (experimental package) >>> - Caleb >>> >>> * Proposal 3 (@Beta/@Experimental annotation) >>> - Thomas >>> - Edy >>> >>> * Other proposal >>> - Denis (use 1) for small changes and only use RN to mark new
module as experimental)
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Thomas Mortagne _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO
On Feb 8, 2013, at 7:09 PM, Denis Gervalle <[email protected]> wrote:
On Fri, Feb 8, 2013 at 3:58 PM, Vincent Massol <[email protected]> wrote:
On Feb 8, 2013, at 3:42 PM, Denis Gervalle <[email protected]> wrote:
By the way, if we agree on @unstable, I also think having another annotation for marking stable API that are not considered to be stable SPI. Why not something like @onlyAPI or @unstableSPI on an interface ?
I think first we need to define what is an SPI and what is an API first. ATM I don't think I understand clearly the difference in the context of XWiki. Is it clear for you?
I do not really understand your question. The general definition is rather clear: "Service Provider Interface (SPI) is an API intended to be implemented or extended by a third party".
All our component interfaces are meant to be implemented by 3rd parties to override default behaviors. Are they SPI?
What I would like to be annotated is API that we do not consider stable SPI at the moment. It is less restrictive than @unstable, but more than not saying anything. Is that answering your question ?
That seems complex. Why not use @unstable on "SPI" classes/methods? Thanks -Vincent
Thanks -Vincent
On Fri, Feb 8, 2013 at 3:30 PM, Thomas Mortagne <[email protected]>wrote:
Yes it's more clear than "beta".
On Fri, Feb 8, 2013 at 3:28 PM, Denis Gervalle <[email protected]> wrote:
+1, but I have the impression that @unstable would be more meaningful
On Fri, Feb 8, 2013 at 2:49 PM, Thomas Mortagne <[email protected]>wrote:
On Fri, Feb 8, 2013 at 2:40 PM, Vincent Massol <[email protected]> wrote: > Hi Paul, > > On Feb 8, 2013, at 1:22 PM, Paul Libbrecht <[email protected]> wrote: > >> Doesn't the @deprecated annotation actually does exactly the job? >> (except it has to be interpreted as meaning something else than "old code", but "do not use code"). > > @Deprecated means something different. It's about some code that you shouldn't use because we no longer think it's good to use and it's going to be removed in the future. > > This is not what a @beta or @experimental annotation would mean. They would mean "this is a new api that you can use but it's not stable yet and may change in the future so be prepared to update your code if that happens".
Plus @deprecated is technically pretty stable API while @beta can be broken anytime.
> > Thanks > -Vincent > >> paul >> >> >> On 8 févr. 2013, at 12:45, Thomas Mortagne wrote: >> >>>> * Proposal 1 (internal package): >>>> - Vincent >>>> - Marius >>>> >>>> * Proposal 2 (experimental package) >>>> - Caleb >>>> >>>> * Proposal 3 (@Beta/@Experimental annotation) >>>> - Thomas >>>> - Edy >>>> >>>> * Other proposal >>>> - Denis (use 1) for small changes and only use RN to mark new module as experimental)
On Fri, Feb 8, 2013 at 7:15 PM, Vincent Massol <[email protected]> wrote:
On Feb 8, 2013, at 7:09 PM, Denis Gervalle <[email protected]> wrote:
On Fri, Feb 8, 2013 at 3:58 PM, Vincent Massol <[email protected]> wrote:
On Feb 8, 2013, at 3:42 PM, Denis Gervalle <[email protected]> wrote:
By the way, if we agree on @unstable, I also think having another annotation for marking stable API that are not considered to be stable SPI. Why not something like @onlyAPI or @unstableSPI on an interface ?
I think first we need to define what is an SPI and what is an API first. ATM I don't think I understand clearly the difference in the context of XWiki. Is it clear for you?
I do not really understand your question. The general definition is rather clear: "Service Provider Interface (SPI) is an API intended to be implemented or extended by a third party".
All our component interfaces are meant to be implemented by 3rd parties to override default behaviors. Are they SPI?
If you consider them stable enough, these could be. The distinction is clearly based of what we think of it. Let me take an example: interface DataMigrationManager (do not mixup with DataMigration which is an SPI for sure). Currently, I consider this one as an API, but I do not imagine any serious usage of it as an SPI for a third party. Marking it API only, would clearly state this point of view. It means that adding a new method to this interface is not considered a breakage. Anyone which would implement it, knows it could have his code broken later.
What I would like to be annotated is API that we do not consider stable SPI at the moment. It is less restrictive than @unstable, but more than not saying anything. Is that answering your question ?
That seems complex. Why not use @unstable on "SPI" classes/methods?
Because the status is about the interface as a whole. It is particularly about adding new methods (or signatures of existing methods), while existing methods are stable. I do not want to add something new, but to state clearly what we think of our interfaces. This is already the case, while we do not really state it. Considering anything an SPI is not an option IMO, since it will create more complexity over time, for a very low benefit, since the chances of a third party to implement an interface like the DataMigrationManager is near zero. And if any, this third party will surely agree to apply some minor changes to its implementation when needed. All that said, I wonder if it wouldn't be better to annotate SPI interface in place of non-SPI one, with a @SPI annotation. Which will favor API only and limit complexity. A user really interested in implementing a not annotated interface could easily open an issue explaining his use case, so we may open the interface as an SPI.
Thanks -Vincent
Thanks -Vincent
On Fri, Feb 8, 2013 at 3:30 PM, Thomas Mortagne <[email protected]>wrote:
Yes it's more clear than "beta".
On Fri, Feb 8, 2013 at 3:28 PM, Denis Gervalle <[email protected]> wrote:
+1, but I have the impression that @unstable would be more meaningful
On Fri, Feb 8, 2013 at 2:49 PM, Thomas Mortagne <[email protected]>wrote:
> On Fri, Feb 8, 2013 at 2:40 PM, Vincent Massol <[email protected]> wrote: >> Hi Paul, >> >> On Feb 8, 2013, at 1:22 PM, Paul Libbrecht <[email protected]> wrote: >> >>> Doesn't the @deprecated annotation actually does exactly the job? >>> (except it has to be interpreted as meaning something else than "old > code", but "do not use code"). >> >> @Deprecated means something different. It's about some code that you > shouldn't use because we no longer think it's good to use and it's going to > be removed in the future. >> >> This is not what a @beta or @experimental annotation would mean. They > would mean "this is a new api that you can use but it's not stable yet and > may change in the future so be prepared to update your code if that > happens". > > Plus @deprecated is technically pretty stable API while @beta can be > broken anytime. > >> >> Thanks >> -Vincent >> >>> paul >>> >>> >>> On 8 févr. 2013, at 12:45, Thomas Mortagne wrote: >>> >>>>> * Proposal 1 (internal package): >>>>> - Vincent >>>>> - Marius >>>>> >>>>> * Proposal 2 (experimental package) >>>>> - Caleb >>>>> >>>>> * Proposal 3 (@Beta/@Experimental annotation) >>>>> - Thomas >>>>> - Edy >>>>> >>>>> * Other proposal >>>>> - Denis (use 1) for small changes and only use RN to mark new module > as experimental)
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO
On 02/08/2013 01:36 PM, Denis Gervalle wrote:
On Fri, Feb 8, 2013 at 7:15 PM, Vincent Massol <[email protected]> wrote:
On Feb 8, 2013, at 7:09 PM, Denis Gervalle <[email protected]> wrote:
On Fri, Feb 8, 2013 at 3:58 PM, Vincent Massol <[email protected]> wrote:
On Feb 8, 2013, at 3:42 PM, Denis Gervalle <[email protected]> wrote:
By the way, if we agree on @unstable, I also think having another annotation for marking stable API that are not considered to be stable SPI. Why not something like @onlyAPI or @unstableSPI on an interface ?
I think first we need to define what is an SPI and what is an API first. ATM I don't think I understand clearly the difference in the context of XWiki. Is it clear for you?
I do not really understand your question. The general definition is rather clear: "Service Provider Interface (SPI) is an API intended to be implemented or extended by a third party".
All our component interfaces are meant to be implemented by 3rd parties to override default behaviors. Are they SPI?
If you consider them stable enough, these could be. The distinction is clearly based of what we think of it. Let me take an example: interface DataMigrationManager (do not mixup with DataMigration which is an SPI for sure). Currently, I consider this one as an API, but I do not imagine any serious usage of it as an SPI for a third party. Marking it API only, would clearly state this point of view. It means that adding a new method to this interface is not considered a breakage. Anyone which would implement it, knows it could have his code broken later.
How about when Hibernate isn't used? The current implementation is marked with the "hibernate" hint, so it suggests that it is valid only in a Hibernate environment. It is a SPI, but one that can't easily be implemented, since it requires a new storage engine, a new query manager, plus rewriting all the $xwiki.search* instances, and so on.
What I would like to be annotated is API that we do not consider stable SPI at the moment. It is less restrictive than @unstable, but more than not saying anything. Is that answering your question ?
That seems complex. Why not use @unstable on "SPI" classes/methods?
Because the status is about the interface as a whole. It is particularly about adding new methods (or signatures of existing methods), while existing methods are stable. I do not want to add something new, but to state clearly what we think of our interfaces. This is already the case, while we do not really state it. Considering anything an SPI is not an option IMO, since it will create more complexity over time, for a very low benefit, since the chances of a third party to implement an interface like the DataMigrationManager is near zero. And if any, this third party will surely agree to apply some minor changes to its implementation when needed.
All that said, I wonder if it wouldn't be better to annotate SPI interface in place of non-SPI one, with a @SPI annotation. Which will favor API only and limit complexity. A user really interested in implementing a not annotated interface could easily open an issue explaining his use case, so we may open the interface as an SPI.
-- Sergiu Dumitriu http://purl.org/net/sergiu
On Mon, Feb 11, 2013 at 5:15 PM, Sergiu Dumitriu <[email protected]> wrote:
On 02/08/2013 01:36 PM, Denis Gervalle wrote:
On Fri, Feb 8, 2013 at 7:15 PM, Vincent Massol <[email protected]> wrote:
On Feb 8, 2013, at 7:09 PM, Denis Gervalle <[email protected]> wrote:
On Fri, Feb 8, 2013 at 3:58 PM, Vincent Massol <[email protected]> wrote:
On Feb 8, 2013, at 3:42 PM, Denis Gervalle <[email protected]> wrote:
By the way, if we agree on @unstable, I also think having another annotation for marking stable API that are not considered to be
stable
SPI.
Why not something like @onlyAPI or @unstableSPI on an interface ?
I think first we need to define what is an SPI and what is an API first. ATM I don't think I understand clearly the difference in the context of XWiki. Is it clear for you?
I do not really understand your question. The general definition is rather clear: "Service Provider Interface (SPI) is an API intended to be implemented or extended by a third party".
All our component interfaces are meant to be implemented by 3rd parties to override default behaviors. Are they SPI?
If you consider them stable enough, these could be. The distinction is clearly based of what we think of it. Let me take an example: interface DataMigrationManager (do not mixup with DataMigration which is an SPI for sure). Currently, I consider this one as an API, but I do not imagine any serious usage of it as an SPI for a third party. Marking it API only, would clearly state this point of view. It means that adding a new method to this interface is not considered a breakage. Anyone which would implement it, knows it could have his code broken later.
How about when Hibernate isn't used? The current implementation is marked with the "hibernate" hint, so it suggests that it is valid only in a Hibernate environment. It is a SPI, but one that can't easily be implemented, since it requires a new storage engine, a new query manager, plus rewriting all the $xwiki.search* instances, and so on.
Surely, but the key here, is that an SPI is an interface that is intended to be implemented *by a third party*. In that sens, IMO it is currently not. This is want I would like to make clear for third parties. If it was, it would means that my recent breakage in that interface would have cause a far more important complexity increase. This is why IMO, we should not intend to have every API supported as SPI.
What I would like to be annotated is API that we do not consider stable SPI at the moment. It is less restrictive than @unstable, but more than not saying anything. Is that answering your question ?
That seems complex. Why not use @unstable on "SPI" classes/methods?
Because the status is about the interface as a whole. It is particularly about adding new methods (or signatures of existing methods), while existing methods are stable. I do not want to add something new, but to state clearly what we think of our interfaces. This is already the case, while we do not really state it. Considering anything an SPI is not an option IMO, since it will create more complexity over time, for a very low benefit, since the chances of a third party to implement an interface like the DataMigrationManager is near zero. And if any, this third party will surely agree to apply some minor changes to its implementation when needed.
All that said, I wonder if it wouldn't be better to annotate SPI interface in place of non-SPI one, with a @SPI annotation. Which will favor API only and limit complexity. A user really interested in implementing a not annotated interface could easily open an issue explaining his use case, so we may open the interface as an SPI.
-- Sergiu Dumitriu http://purl.org/net/sergiu _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Denis Gervalle SOFTEC sa - CEO eGuilde sarl - CTO
participants (8)
-
Caleb James DeLisle -
Denis Gervalle -
Eduard Moraru -
Marius Dumitru Florea -
Paul Libbrecht -
Sergiu Dumitriu -
Thomas Mortagne -
Vincent Massol