Why should anything in commons be regarded as a public API?

I think javadoc could be added to commons to simply state that *all*
classes in that library are subject to API changes in any release [1].
These are helper classes. People who are writing "portable" JSF
components will not be using these APIs anyway as they only exist for
MyFaces.

The only people this will bother are those who subclass existing
components. Yes this is a reasonable thing to do (I've done it myself)
and maybe in the future effort could be put into separating "stable"
from "unstable" APIs in commons to help this but I think it's premature
to do this. The pain of determining what the "public" apis are, then of
maintaining binary compatibility with them is not worth the gain right
now.

I think maintaining compatibility for the component APIs *is* important;
JSP tags (or facelets tags) should not suddenly change their attributes,
and component properties should not disappear or change meaning. However
none of this is defined in commons classes.

[1] Actually, I've proposed not ever releasing commons at all; when a
component (core/tomahawk/tobago/etc) is tagged/branched, just tag/branch
commons at the same time and then use a tool to rename the classes into
the core/tomahawk/etc packages.

Cheers,

Simon

On Tue, 2006-02-21 at 11:35 -0800, John Fallows wrote:
> Folks,
> 
> There seems to be increasing discussion lately regarding MyFaces
> Commons and how it relates to both MyFaces Core and MyFaces
> Tomahawk.  
> 
> Adding Tobago and ADF Faces to the discussion makes it even more
> critical that we come up with a useful way to share reusable code
> between the various projects.  So, I thought it might be helpful to
> the current discussion if I shared my thoughts about this for the
> future. 
> 
> Right now, we tend to think of MyFaces Commons as a dumping ground for
> common utility code that is reused between the Core and Tomahawk, and
> AFAIK, none of this code has been vetted for its suitability as a
> consistently backwards-compatible public API. 
> 
> In future, we'll need to provide common code to all component
> libraries developed as part of the MyFaces effort (and outside MyFaces
> too), and due to the independent upgrade requirements for individual
> component libraries, that common codebase will need to provide a
> guarantee of backwards compatiblilty. 
> 
> One example of such shared code for the future might be a common
> strategy for the FileUpload feature.  It would be a real shame if all
> of the internal implementation code for this FileUpload feature became
> part of a public API just because it was added to Commons.  So, I
> propose a split in Commons between public API and private
> implementation.  In fact, I think it shouldn't be called Commons
> either. :-) 
> 
> [groupId = org.apache.myfaces]
> myfaces-api-x.y.z.jar
> myfaces-impl-x.y.z.jar
> 
> Dependent projects should be free to create compile-time dependencies
> against myfaces-api, but not myfaces-impl. 
> 
> The code currently in Commons will need an overhaul to prepare it for
> such backwards compatibility strictness.  We should take a hard look
> at the codebase in there and decide how best to trim it to a managable
> size that can realisticly be kept compatible across releases. 
> 
> Now, this raises the point about the naming for the current API and
> implementation for the specification.  How about the following?
> 
> [groupId = org.apache.myfaces]
> jsf-api-a.b.c.jar
> jsf-impl-a.b.c.jar
> 
> I think this makes two things very clear.
>      1. MyFaces spec api and impl do not contain any non-spec related
>         code (i.e. no non-portable "extensions" to the spec) 
>      2. MyFaces spec api and impl are equivalents of the reference api
>         and impl from Sun
> In addition, we might need to break the dependency between
> jsf-impl-x.y.z.jar and myfaces-api-x.y.z.jar/my-faces-impl.x.y.z.jar
> above.  This may still involve "inlining" commons into the jsf-impl
> JAR to avoid potential problems with JavaEE containers vs. webapp
> ClassLoaders.  
> 
> It certainly feels better to have a directed dependency from the
> MyFaces API / Impl -> standard JSF API / Impl rather than the
> reverse. :-)
> 
> Btw, do JavaEE containers, e.g. Tomcat, properly isolate the Webapp
> ClassLoader from the container's own ClassLoader, preventing
> visibility of jsf-impl and only exposing jsf-api to the Webapp
> ClassLoader?  This should be perfectly possible using appropriate
> ClassLoader parentage, but I'm not certain if it is commonly done or
> mentioned in the JavaEE specification. 
> 
> For Tomahawk, Tobago and ADF Faces, we can have the following.
> 
> [groupId = org.apache.myfaces]
> tomahawk-api-d.e.f.jar
> tomahawk-impl-d.e.f.jar
> 
> tobago-api-g.h.i.jar
> tobago-impl-g.h.i.jar
> 
> adf-faces-api-j.k.l.jar*
> adf-faces-impl-j.k.l.jar*
> 
> where each has a compile time dependeny on both jsf-api and
> myfaces-api but only a runtime dependency on the internal
> implementation details of jsf-impl and myfaces-impl.
> 
> *adf-faces to be renamed during incubation. 
> 
> When any of these projects need to be upgraded, and it depends on a
> newer version of myfaces-api / myfaces-impl, the upgrade can proceed
> with confidence because the newer version guarantees backwards
> compatibilty at compile-time for myfaces-api and at runtime for
> myfaces-impl. 
> 
> Thoughts?
> 
> Kind Regards,
> John Fallows.
> -- 
> http://apress.com/book/bookDisplay.html?bID=10044
> Author: Pro JSF and Ajax: Building Rich Internet Components, Apress 

Reply via email to