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. <[EMAIL PROTECTED]> Friedrich Nietzsche -------------------------------------------------------------------- --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]