+1

David W. Van Couvering wrote:

Hi, all, here is the vote for the shared components guidelines following the ASF standard of including the full text of the item being voted for in the email.

These guidelines will be accessible from the Derby Wiki page at

http://wiki.apache.org/db-derby/SharedComponentVersioningGuidelines

The guidelines as shown here reflect version 29 of this Wiki page. Version 29 can be directly viewed at

http://wiki.apache.org/db-derby/SharedComponentVersioningGuidelines?action=recall&rev=29

Changes since the last call for a vote can be seen by looking at

http://wiki.apache.org/db-derby/SharedComponentVersioningGuidelines?action=diff&rev1=29&rev2=22

Thanks,

David

== GUIDELINE TEXT TO BE VOTED ON ===

This document describes our guidelines around shared components in Derby, where a shared component is a collection of one or more packages that is used across multiple subsystems within Derby. Very loosely, I would define a "subsystem" as the code contained in one of the top-level source directories, e.g. engine, client, drda, tools, etc. As of this writing, the only shared component like this is the proposed common code component (see [WWW] DERBY-289). Other components may be defined in the future as needed (for example, perhaps the DRDA networking code should be separated out as an independent shared component).

The guidelines for shared components in Derby are based on the [WWW] Jakarta Runtime Versioning Guidelines. There are some areas that these guidelines do not cover, however, which we will address here:

   1. Mixed Version Support
   2. Guidelines for Forward Compatibility
   3. Deprecation Guidelines
   4. Location and Distribution of Shared Components
   5. Documenting Shared Components
   6. User Visible Impact and Restrictions
   7. Testing Impact
   8. Introducing New Shared Components and Shared Packages


MIXED VERSION SUPPORT
Two applications should be able to use one version of the Derby network client driver and a different version of the Derby embedded driver within the same Java VM without having to resort to creating specialized classloaders. This is enabled by supporting forward compatibility as described below.


GUIDELINES FOR FORWARD COMPATIBILITY
A consumer built against version X.Y of a shared component should work with version X.Y' of a module where Y' < Y. This is called forward compatibility.

If the consumer uses new functionality added in version X.Y of the module, it should degrade to X.Y' level functionality. In the rare cases where this is not achievable, the consumer should throw an exception explaining that it requires version X.Y or greater of the shared component (rather than an obtuse Java exception like NoSuchMethodException).

Forward compatibility must be guaranteed between patch revisions (from X.Y.Z to X.Y.Z') and minor revisions (from X.Y to X.Y'). We should strive for forward compatibility between major releases, but it is not a guarantee.

The consumer decides it can work with a given version of a shared component not by looking up its version number and then extrapolating what features are available, but instead by directly querying the component to see if the shared component provides the feature or features it is looking for.

A shared component must provide a class called <ComponentName>Info that provides a static method called hasFeature. This class should be at the top level of the package for that component, e.g. the info class for the common component should be org.apache.derby.common.CommonInfo.

This method takes a single parameter which is a feature identifier. If the shared component implementation recognizes the feature identifier, it returns true, otherwise it returns false. Here is an example definition and usage using the common component. Assume that a consumer is making use of a new whizbang feature in the message utilities in a newer version of the common component which is not available in older versions.

Here is the old version of the CommonInfo class:

   1
   2 public static class CommonInfo
   3 {
   4   public static final int COOL_FEATURE = 1;
   5   private static final int MAX_FEATURE = COOL_FEATURE;
   6
   7   public static boolean hasFeature(int featureId)
   8   {
   9       return featureID <= MAX_FEATURE;
  10   }
  11 }
  12

Here is the new definition of the CommonInfo class:

   1
   2 public static class CommonInfo
   3 {
   4   public static final int COOL_FEATURE = 1;
   5   public static final int WHIZBANG_FEATURE = 2;
   6   private static final int MAX_FEATURE = WHIZBANG_FEATURE;
   7
   8   public static boolean hasFeature(int featureId)
   9   {
  10       return featureID <= MAX_FEATURE;
  11   }
  12 }
  13

The consumer is then built with the new common component and uses the new CommonInfo class definition:

   1
   2 if ( CommonInfo.hasFeature(CommonInfo.WHIZBANG_FEATURE) )
   3 {
   4   // use whizbang feature
   5 }
   6 else
   7 {
   8   // use older mechanism
   9 }
  10

Note that the constant CommonInfo.WHIZBANG_FEATURE is compiled down to a constant integer, so there will not be runtime errors if the older version of the component has been loaded.

DEPRECATION GUIDELINES
A method or an interface may be deprecated. This is done using the @deprecated tag in the method or interface Javadoc. A method or interface must be available for 2 major releases after it is deprecated. For example, if it is deprecated in version 8.2, it can be removed in version 10.0 or greater. An exception to this rule may occur if it becomes clear that there is still heavy use of this interface.

LOCATION AND DISTRIBUTION OF SHARED COMPONENTS
All shared components should comprise of one or more packages under the package org.apache.derby.common (stored in the source tree under java/common/org/apache/derby/common).

Although it would be conceptually nice to have a separate JAR file for each shared component, it is a priority for us to keep a very simple user experience. For this reason, the classes of a shared components will be merged into the appropriate subset of the existing jar files.

DOCUMENTING SHARED COMPONENTS
We will provide a top-level package.html javadoc under java/org/apache/derby/common that describes the shared components guidelines (once they are approved) and lists the available components. For each shared component we will provide:

    * Name of component
    * Description of component (its role or intent)
    * Packages contained within the component
    * The name of the Info class that provides the hasFeature() method


USER VISIBLE IMPACT AND RESTRICTIONS
With these guidelines in place, there will be no visible impact or restrictions for Derby users.

No visible impact implies the following checkin requirements for any common code.

* Derby jar files of the same major version can continue to be mixed within the same JVM classpath without any difference in behavior from loading these jars in separate classloaders.
    * Jar file growth is commensurate with functionality improvement.
* Replacing any jar with a jar of the same major version will not require any user classpath changes.

The only exception is if for some reason (and this is to be avoided) a change is made between major revisions that is not compatible, then if the user is running in a mixed version environment in the same VM, he or she should attempt to ensure that the jar files from the newer version are loaded first. If for some reason this is not possible, the user will need to separate the two versions by using separate classloaders within the same VM.


TESTING IMPACT
In the first new release after common components are introduced, we will want to test for compatibility between patch and minor releases in the following ways:

* Build common component unit tests against the new release and test against jar files from old releases (backward compatibility tests) * Build common component unit tests from old releases and test against jar files from the new release (forward compatibility tests)

Any incompatibilities introduced between patch and minor releases should be considered a regression. Any incompatibilities between major releases should be documented.


INTRODUCING NEW SHARED COMPONENTS AND SHARED PACKAGES
When a developer wishes to introduce a new shared component or a new package within an existing shared component, this should be put up for a vote. This is to help ensure that what we are sharing makes sense and does not accidentally paint us into some kind of architectural corner. Adding new classes or methods to an existing shared package does not need to be put up for a vote but should be reviewed using the standard patch review mechanism.


Reply via email to