Ken,

can I ask you to file that as a jira-issue?

If possible, include both yours and Craigs evaluation of the problem
as comments.

regards,

Martin

On 8/24/05, Craig McClanahan <[EMAIL PROTECTED]> wrote:
> On 8/23/05, Ken Weiner <[EMAIL PROTECTED]> wrote:
> > Thanks for the replies.  Do other specs from JCP behave this way?
> 
> Yes, they *all* do.  An implementation of a JCP spec is required to
> provide the javax.foo classes, as well as whatever implementation
> classes they require to conform to the spec requirements.  The primary
> difference for JSF is there is relatively more executable code in the
> javax.faces classes, rather than just specifying APIs.  But the
> compatibility test that MyFaces will be required to pass include
> signature tests that ensure any given implementation implements
> *exactly* the set of public and protected methods (and variables if
> any) as is required by the spec.
> 
> > don't remember ever seeing another situation where there are multiple
> > versions of the same exact (same fully-qualified name) class.
> 
> Question -- where do you get your definition of javax.servlet.Servlet
> when you compile your webapp?  Answer ... that is totally up to the
> server implementation you are using -- they do *not* all necessarily
> share the same physical source code (although such sharing is not
> uncommon either -- lots of app server vendors use the same
> javax.servlet classes that Tomcat does, for example, because they are
> available under the Apache license).
> 
> The same principle applies to all of the JCP specs.
> 
> > Here is an example of how my component would break if I switched
> > implementations:
> >
> > Let's say I am coding a component that has children components.  My
> > component extends javax.faces.render.Renderer.  If I am using the RI,
> > I may be tempted to accept (not override) the implementation of
> > Renderer.encodeChildren() which simply iterates thought the children
> > and renders them as follows:
> >
> >     public void encodeChildren(FacesContext context, UIComponent component)
> >         throws IOException {
> >         if (context == null || component == null) {
> >             throw new NullPointerException();
> >         }
> >         Iterator kids = component.getChildren().iterator();
> >         while (kids.hasNext()) {
> >             UIComponent kid = (UIComponent) kids.next();
> >             kid.encodeBegin(context);
> >             if (kid.getRendersChildren()) {
> >                 kid.encodeChildren(context);
> >             }
> >             kid.encodeEnd(context);
> >         }
> >     }
> >
> > Now if I switch to MyFaces, none of my children would render because
> > the MyFaces version of javax.faces.render.Renderer.encodeChildren()
> > does not render the children.  It looks like this:
> >
> >     public void encodeChildren(FacesContext context,  UIComponent component)
> >             throws IOException
> >     {
> >         if (context == null) throw new NullPointerException("context");
> >         if (component == null) throw new NullPointerException("component");
> >     }
> >
> > So if I understand things correctly, my component would essentially
> > break because none of its children would render with MyFaces.  Does
> > that make sense?
> >
> 
> There are a couple bunch of overlapping questions here.
> 
> * Does the spec require a particular behavior of this method?  If so,
>   then an implementation that doesn't follow those requirements is
>   totally broken, and should not be used until it is fixed.
> 
> * Do the compatibility tests actually test that particular asserion?
>   This will vary by assertion (like any other piece of software, the
>   TCK tests are limited by how much resource can be devoted to
>   creating them), so you cannot expect 100% coverage of even the
>   testable assertions.  But, even if an assertion is not tested,
>   failure to conform to the requirements means the implementation
>   is broken (and, to be fair, the MyFaces folks will go out of their way
>   to ensure compatibility with the spec requirements).
> 
> * Does a particular implementation (either the RI or MyFaces in this case)
>   do something *not* required by the spec?  That's also perfectly legal
>   as long as they don't violate any of the spec requirements in doing so.
>   However, apps that depend on that behavior are locking themselves
>   in to that particular implementation.
> 
> Going back to the servlet API example above, how do *you* know that
> your container's implementation of
> HttpServletRequest.getSession(boolean) does the right thing?  Only
> because (a) the implementations that matter have all been tested
> against the servlet API's tests, and (b) the community considers
> compatibility with the specs important enough to insist that their
> vendors conform.  Note that this is true regardless of whether the
> implementation class is a javax.foo class provided by the server, or
> some internal com.foo class that implements a standard interface.
> 
> > I realize I could override the encodeChildren() method to be safe, but
> > don't you agree that it would be easy for someone to fall into a trap?
> >  Maybe, in this case, one of the implementations is not adhering to
> > the spec.
> 
> To the specific question on Renderer.encodeChildren, the requirements
> are laid out in Section 8.2 of the spec (which references section
> 3.1.12 for the description of the corresponding methods on
> UIComponent, and in the RI javadocs, which are (by reference)
> incorporated into the JSF spec.  In 3.1.12 we read that
> encodeChildren() is called only if the component's rendersChildren()
> returns true, and is responsible for "creating the response data ...
> corresponding to this component's children."  If the MyFaces
> implementation in UIComponentBase does not do that, it's broken and
> needs to be fixed.
> 
> We get a more explicit indication of the *required* functionality by
> reading the Javadocs for UIComponent.encodeChildren():
> 
>     If our "rendered" property is "true", render the child
>     UIComponents of this UIComponent.  This method
>     will only be called if the "rendersChildren" property
>     is "true".
> 
> Seems pretty clear cut, right?  An implementation either conforms to
> the requirements or it doesn't.  Implementations that don't need bug
> reports filed against them in the areas of non-conformance, so that it
> can be fixed.
> 
> To be fair, the MyFaces developers have not yet been able to run the
> TCK tests of the JSF spec against their implementation, so haven't
> gotten the benefit of finding the issues that the tests will point
> out.  There is an ongoing negotiation to license the TCK to Apache
> (using the scholarship characteristic of Apache for which Sun (as the
> TCK developer in this partiular case) uses to make TCKs available at
> no cost to qualified non-profits).  Once that process is completed,
> I'm sure a number of compliance issues will surface and be quickly
> fixed.
> 
> But, for you as an application developer -- you should count on *only*
> the assertions described in the spec, and you should insist that your
> JSF implementation conform to those assertions.  Reliance on any
> non-specified behavior (of either MyFaces or the RI, in this
> particular scenario) risks making your application non-portable.
> 
> >
> > -Ken
> >
> 
> Craig McClanahan
> (Co-Spec Lead, JSF 1.0)
> 


-- 

http://www.irian.at
Your JSF powerhouse - 
JSF Trainings in English and German

Reply via email to