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