You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Berin Loritsch <bl...@apache.org> on 2001/12/13 15:49:09 UTC

[Proposal] Deprecation Policy

It has become painfully clear to me that the Cocoon team does not practice
proper API migration techniques.  This is evident in the fact that some
classes were missing that used to be in Cocoon as recently as a couple
months ago.

This is _very_ frustrating, because a project that I left that long ago
no longer works with the current Cocoon.  Now I have to go through and
see what needs to change to make it work again.  This should not be.

As Release Manager for the Avalon team, I have learned alot about providing
a stable API.  This means that not only do you need to provide deprecation
warnings, but you have to maintain functionality as long as possible for
the deprecated function.  Giving any team less than six *months* is simply
not an option.  In fact, we discovered that we had to place some classes
back in LogKit when we hit the six month mark.  It turns out that six months
is not even enough time.

So, for the Cocoon team, I propose that we adopt a deprecation practice
here and now, before we alienate users due to backward incompatible changes.
In fact, as soon as the project was in Beta, we *should* have been using
proper deprecation techniques.

The types of changes that are _not_ backwards compatible include: changing
method signatures, adding new methods to an interface or abstract class,
changing the name of a Class, and changing the core behavior of a class.

Here is a list of actions for the different deprecation types:

* Changing Method Signatures.  The vast majority of these are simply altering
   the number of parameters passed.  In those cases, merely add the "@deprecated"
   flag to the javadoc comment area (yes, the compiler reads these).  The
   implementation should merely call the new function with any default values
   that are needed.

* Adding new methods to an interface or abstract class.  This is only an issue
   when there is no implementation of that method.  If you add a method to an
   abstract class that has an implementation to it, you will be ok.  However,
   interfaces never allow an implementation.  If at all possible, *do*not*do*it.
   Look for other ways to provide the functionality you need.  The Avalon team
   ran accross a situation where this was simply not possible: adding the Logger
   abstraction to Framework.  In this case, we deprecated the old Loggable interface,
   pointing users to the new LogEnabled interface.

* Changing the name of a class.  Sometimes this is done because the class was
   mispelled (like the DijkstraSemaphore class in Excalibur).  In these cases,
   we changed the name of the class, and created a new class with the old name
   that merely extended the new class.

   class DijkstraSemaphore { /* implementation */ }
   /** @deprecated use DijkstraSemaphore instead */
   class DjikstraSemaphore extends DijkstraSemaphore {}

   This works wonderfully in most cases as the old class name still gets bug
   fixes but we only have to maintain the correct class.

   Sometimes this is done because the class is being repurposed.  I am sorry, but
   in this case you are going to have to maintain two different classes.  Do deprecate
   the old one, but you still have to maintain it for as long as it remains part
   of Cocoon.

* Changing the behavior of a class.  An example of this would be the added namespace
   support for Configurations.  The previous version of Framework only allowed the
   Configuration name to be keyed off of the raw name for an element.  In other words,
   if the configuration had namespaces declared for a component, you would see
   "map:parameter" as the name of the Configuration element.  With added namespace
   support, there is a new method called "getNamespace()" which returns the string
   representation of the namespace.  The name of the Configuration element is now
   simply "parameter" with a namespace that "map:" was mapped to.  In the end this
   is more correct--but what about all those applications that would break because
   the name of the Configuration has changed?

   The Avalon team fixed this by providing a different Configuration reader.  There
   is the SAXConfigurationBuilder, and the NamespacedSAXConfigurationBuilder.  The
   difference between the two are names of the Configuration element built.  At this
   time, neither implementation is deprecated--but as needs change that may change.

   In this case you have to think long and hard about the consequences of such a move.
   You want to minimize the impact--but if it is best in the long run, do provide a
   deprecation warning.

Lastly I also want to have a note about the minimal set of Components that are
required to make Cocoon run.  I am not against adding functionality.  However,
if the required set of Components changes from release to release, you are going
to make a lot of enemies.  Stick with a core set, and if it changes, you have to
provide meaningful messages in the log files, as well as announce it in the release.
The *exact* changes to the cocoon.xconf should be documented.  If at all possible,
please provide a kind of deprecation in your config files.  You may not be able to
declare them programatically, but you can declare them in the logs.  This is the
approach I used for the DataSourceComponent.  The JdbcDataSource has had it's
configuration change slightly, but still supports the old method.  It does send
a deprecation warning to the logs so that you know it is not the correct way of
configuring it.

-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


Re: [Proposal] Deprecation Policy

Posted by Berin Loritsch <bl...@apache.org>.
Stefano Mazzocchi wrote:

> Berin Loritsch wrote:
>



> 
> big +1 on this all. How about making this part of the documentation for
> development guidelines?


+1, any takers!?!




-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org


Re: [Proposal] Deprecation Policy

Posted by Stefano Mazzocchi <st...@apache.org>.
Berin Loritsch wrote:
> 
> It has become painfully clear to me that the Cocoon team does not practice
> proper API migration techniques.  This is evident in the fact that some
> classes were missing that used to be in Cocoon as recently as a couple
> months ago.
> 
> This is _very_ frustrating, because a project that I left that long ago
> no longer works with the current Cocoon.  Now I have to go through and
> see what needs to change to make it work again.  This should not be.
> 
> As Release Manager for the Avalon team, I have learned alot about providing
> a stable API.  This means that not only do you need to provide deprecation
> warnings, but you have to maintain functionality as long as possible for
> the deprecated function.  Giving any team less than six *months* is simply
> not an option.  In fact, we discovered that we had to place some classes
> back in LogKit when we hit the six month mark.  It turns out that six months
> is not even enough time.

Yes, this is correct.

> So, for the Cocoon team, I propose that we adopt a deprecation practice
> here and now, before we alienate users due to backward incompatible changes.

Absolutely +1

> In fact, as soon as the project was in Beta, we *should* have been using
> proper deprecation techniques.

Correct. That's was beta should have meant.

> The types of changes that are _not_ backwards compatible include: changing
> method signatures, adding new methods to an interface or abstract class,
> changing the name of a Class, and changing the core behavior of a class.
> 
> Here is a list of actions for the different deprecation types:
> 
> * Changing Method Signatures.  The vast majority of these are simply altering
>    the number of parameters passed.  In those cases, merely add the "@deprecated"
>    flag to the javadoc comment area (yes, the compiler reads these).  The
>    implementation should merely call the new function with any default values
>    that are needed.
> 
> * Adding new methods to an interface or abstract class.  This is only an issue
>    when there is no implementation of that method.  If you add a method to an
>    abstract class that has an implementation to it, you will be ok.  However,
>    interfaces never allow an implementation.  If at all possible, *do*not*do*it.
>    Look for other ways to provide the functionality you need.  The Avalon team
>    ran accross a situation where this was simply not possible: adding the Logger
>    abstraction to Framework.  In this case, we deprecated the old Loggable interface,
>    pointing users to the new LogEnabled interface.
> 
> * Changing the name of a class.  Sometimes this is done because the class was
>    mispelled (like the DijkstraSemaphore class in Excalibur).  In these cases,
>    we changed the name of the class, and created a new class with the old name
>    that merely extended the new class.
> 
>    class DijkstraSemaphore { /* implementation */ }
>    /** @deprecated use DijkstraSemaphore instead */
>    class DjikstraSemaphore extends DijkstraSemaphore {}
> 
>    This works wonderfully in most cases as the old class name still gets bug
>    fixes but we only have to maintain the correct class.
> 
>    Sometimes this is done because the class is being repurposed.  I am sorry, but
>    in this case you are going to have to maintain two different classes.  Do deprecate
>    the old one, but you still have to maintain it for as long as it remains part
>    of Cocoon.
> 
> * Changing the behavior of a class.  An example of this would be the added namespace
>    support for Configurations.  The previous version of Framework only allowed the
>    Configuration name to be keyed off of the raw name for an element.  In other words,
>    if the configuration had namespaces declared for a component, you would see
>    "map:parameter" as the name of the Configuration element.  With added namespace
>    support, there is a new method called "getNamespace()" which returns the string
>    representation of the namespace.  The name of the Configuration element is now
>    simply "parameter" with a namespace that "map:" was mapped to.  In the end this
>    is more correct--but what about all those applications that would break because
>    the name of the Configuration has changed?
> 
>    The Avalon team fixed this by providing a different Configuration reader.  There
>    is the SAXConfigurationBuilder, and the NamespacedSAXConfigurationBuilder.  The
>    difference between the two are names of the Configuration element built.  At this
>    time, neither implementation is deprecated--but as needs change that may change.
> 
>    In this case you have to think long and hard about the consequences of such a move.
>    You want to minimize the impact--but if it is best in the long run, do provide a
>    deprecation warning.
> 
> Lastly I also want to have a note about the minimal set of Components that are
> required to make Cocoon run.  I am not against adding functionality.  However,
> if the required set of Components changes from release to release, you are going
> to make a lot of enemies. 

Great point.

> Stick with a core set, and if it changes, you have to
> provide meaningful messages in the log files, as well as announce it in the release.
> The *exact* changes to the cocoon.xconf should be documented.  If at all possible,
> please provide a kind of deprecation in your config files.  You may not be able to
> declare them programatically, but you can declare them in the logs.  This is the
> approach I used for the DataSourceComponent.  The JdbcDataSource has had it's
> configuration change slightly, but still supports the old method.  It does send
> a deprecation warning to the logs so that you know it is not the correct way of
> configuring it.

big +1 on this all. How about making this part of the documentation for
development guidelines?

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------



---------------------------------------------------------------------
To unsubscribe, e-mail: cocoon-dev-unsubscribe@xml.apache.org
For additional commands, email: cocoon-dev-help@xml.apache.org