On 2/22/06, Adam Winer <[EMAIL PROTECTED]> wrote:
Definitely.  I think we need to extract a few issues here,
and consider them separately.

(1) Do we need to be in the practice of identifying APIs that
   external developers can depend on, and are not subject to
   change. If so, how?
(2) Do we consider Tomahawk, Tobago, and ADF as purely
  internal codebases that therefore can depend on anything,
  or do we define explicit contracts between the various parts
  of the overall MyFaces codebase?  In particular, do we define
  subparts of the architecture as internal even within the project?
(3) Do we split up JARs, and if so what do we name them?

#3 is pretty minor, and not the big deal here - I'd rather John
hadn't even mentioned it, since it's very easy to get sidetracked
on what is a relatively minor sidepoint.  Needs to get talked
about at some point, but until we've decided that there should
even be two JARs or what they'd contain, doesn't make much
sense to talk about what they should be called!

You're totally right Adam - I was getting ahead of myself. :-)

Let's focus on #1 and #2 for now.

#1 is something that's very important.  I'm deeply uncomfortable
with the notion of just identifying internal classes with Javadoc,
for two main reasons:
  - Developers will have no rigorous approach to marking
    such classes, and will almost certainly routinely fail to do so
    properly.  The quantity of code in MyFaces with little or no
    Javadoc is a bit discouraging.  (Total digression:  if there isn't
    such a rule already, nothing should get out of Sandbox without
    complete Javadoc.)
  - End users have no quick way to look at their code and audit it
    they're using illicit code.  Contrast that to the ease of saying
    "am I using javax.faces or com.sun.faces /org.apache?"

The current reality of the MyFaces codebase is that such distinctions
aren't made at all.  In the Tomahawk components, the component
class, the Renderer, and the Tag are all public classes in the same
package, with no Javadoc indication of public or private status.
Are these all really public APIs that can be freely relied on?

The approach we've used in the ADF Faces codebase - and
been very happy with - is to separate out the API and IMPL
by using different Java packages and JARs.  That makes it
trivial for end users to audit their code, or even better to
prevent such dependencies from ever creeping in by only
adding a compile dependency on the API jar.

#2 may not seem important yet, but as the MyFaces codebase
grows in size, it will become really, really important to making
progress.  Without well-defined and minimal dependencies of
the external projects on commons, it will become difficult to
make interesting changes to commons.  For example, take
the script-injection code in AddResource;  why the dependencies
on Servlet APIs?  If I wanted to tackle this, how much code in
the rest of the codebase do I have to analyze and possibly
re-code?

I see three potential levels:
  - Totally public APIs.
  - APIs that are public *within* MyFaces, but private externally
  - APIs that are private even *within* MyFaces, that is,
    only a very limited set of closely related code can depend
    on it.

The middle of these intuitive seems the least desirable - as Manfred
points out, why should code that is acceptable for use by all
component libraries be unacceptable for general use?   But as
I understand the current approach, that's what the myfaces-commons
would in fact be.

-- Adam



On 2/22/06, Sean Schofield <[EMAIL PROTECTED]> wrote:
> I agree with Manfred that we should not rename the implementation jars
> (myfaces-impl.jar and myfaces-api.jar) for the reasons he has stated.
> Even if you take Maven out of the picture you don't want to clash with
> jar names the RI is using.
>
> Naming is only a small part of what John is suggesting, however.  I
> think he is onto something here even though I don't necessarily agree
> with all of the proposed solutions to the issue.
>
> The issue that John raises that interests me is the future inclusion
> of Tobago and ADF.  There may be code that could be shared between
> these two projects and Tomahawk that has nothing to do with impl.  So
> essentially we are talking about another core for components.
>
> I'm not sure how much overlap there is although on the surface there
> seems to be a lot.  I will need to dive deeper into the two projects
> before I could say for sure.  Lets take the tree case since I am not
> familiar with the file upload component and presumably John is
> familiar with the ADF tree.  Is it possible to have a single component
> shared between Tomahawk and ADF and only have different renderers in
> the separate subprojects?  That would be interesting and probably more
> realistic then an outright merger of the two trees.
>
> If something like this is possible then maybe we could have a
> tomahawk-core.jar with the components and tomahawk-impl.jar with the
> tags, renderers and config files?
>
> Sean
>
> On 2/22/06, Manfred Geiler <[EMAIL PROTECTED]> wrote:
> > On 2/21/06, John Fallows <[EMAIL PROTECTED] > 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
> >
> > My definite
> > -1 on naming anything other than the current MyFaces JSF API and Impl
> > as "myfaces-api-*" or "myfaces-impl-*"
> >
> > Not only this would totally confuse our users, having equally named
> > artifacts in Maven that not only differ in version and/or
> > features/bugs but totally differ in their contents sounds more than
> > unreasonable to me.
> >
> >
> > > 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
> >
> > -1 on naming any of our libs identical to any other publicly available
> > lib. Ok, they would differ in Maven groupId, but AFAICT most of our
> > end users will not use Maven at all. Anyway, having equally named libs
> > from different sources sounds very dangerous to me.
> >
> > -0.9 on renaming our current api and impl libs at all
> >
> >
> > > I think this makes two things very clear.
> > >
> > > MyFaces spec api and impl do not contain any non-spec related code (i.e. no
> > > non-portable "extensions" to the spec)
> > >
> > > 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.
> >
> > +1 on "inlining" commons into the jsf-impl JAR for the above reasons
> > I will do some additional experiments on this today. Stay tuned...
> >
> >
> > > It certainly feels better to have a directed dependency from the MyFaces API
> > > / Impl -> standard JSF API / Impl rather than the reverse. :-)
> >
> > Don't know what you mean by that.
> >
> >
> > > 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?
> >
> > I have the feeling of a slight overkill here. Splitting everything
> > into api and impl makes things unnecessarily complicated. Making it
> > clear in javadoc what is subject to change and what api people can
> > rely on shoud be enough IMHO.
> >
> > What I could do secondary to the planned refactoring of commons
> > classes (package move from o.a.myfaces .* --> o.a.myfaces.commons.*)
> > is to try splitting commons classes into "MyFaces specific helpers"
> > and "Reasonable public interest goodies". The former would be those
> > classes that are subject to change on most releases and could be moved
> > into their own package "o.a.myfaces.commons.private.*" or better, but
> > perhaps confusing "o.a.myfaces.commons.impl.*". The latter would be
> > those "API like" utils and base classes that people may rely on in
> > their own custom components.
> >
> > WDYT?
> >
> > Manfred
> >
>



--
http://apress.com/book/bookDisplay.html?bID=10044
Author: Pro JSF and Ajax: Building Rich Internet Components, Apress

Reply via email to