You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Randahl Fink Isaksen <ra...@rockit.dk> on 2006/10/30 19:50:49 UTC

Its a bug: Facelets+MyFaces cannot serve UTF-8 and here is why!

I finally found out why the combination of Facelets 1.1.11 and MyFaces 
1.1.4 makes it impossible to serve UTF-8. The problem is that they both 
expect each other to provide the encoding. First the FaceletViewHandler 
tries to make MyFaces decide which encoding to use by doing this:

        String encoding = null;
        ResponseWriter writer = renderKit.createResponseWriter(
                NullWriter.Instance, contentType, encoding);
        encoding = getResponseEncoding(context, 
writer.getCharacterEncoding());

For now, just notice here that createResponseWriter() is invoked with an 
encoding of null. In MyFaces the default render kit is HtmlRenderKitImpl 
and when Facelets call createResponseWriter() with a null encoding 
MyFaces responds by doing this:

        if(characterEncoding==null)
        {
            characterEncoding = HtmlRendererUtils.DEFAULT_CHAR_ENCODING;
        }

So MyFaces essentially says that if Facelets does not state explicetly 
which encoding it wants it just uses its default encoding, and 
DEFAULT_CHAR_ENCODING is in MyFaces equal to ISO-8859-1.

Now, back to the first code snippet - in the last line of the shown 
FaceletViewHandler code above a method called getResponseEncoding() is 
invoked and it contains this code:

        if (encoding == null) {
            encoding = "UTF-8";

This code will not have any effect because Facelets already invoked 
MyFaces with a null encoding which made MyFaces fall back to ISO-8859-1 
and thus the encoding is not null anymore.

So is this a MyFaces bug or a Facelets bug? In the code above Facelets 
deliberately chooses not to decide for a specific character encoding 
thereby expecting that

1. the JSF implementation provides the developer with means for 
specifying which character encoding he wants and that
2. the render kit provided by the JSF implementation will return this 
desired character encoding

This is in my opinion a wrong assumption - nothing in the JSF 
specification 1.1 says this is so. On the contrary the specification 
explicitly states that the encoding parameter is required when you 
invoke createReponseWriter, quote: "... the required value for the 
characterEncoding parameter for this method..." (section 8.1). So 
invoking createResponseWriter() with a null encoding is a violation of 
the specification, and thus I think this is a serious Facelets bug.

I sincerely hope the Facelets developers will comment on this. Thank you.

Randahl



Re: Its a bug: Facelets+MyFaces cannot serve UTF-8 and here is why!

Posted by Randahl Fink Isaksen <ra...@rockit.dk>.
Hi Jeff

Regarding CVS build - great! Found the CVS sources too now and yes it 
looks like it is getting fixed so that is great news.

Ah, a fellow Thunderbird user - what a great app ;-)
Sure - I'll click reply, but actually I almost never change the subject 
of the original message for the same reason you mentioned.

Randahl



Jeff Bischoff wrote:
> Randahl,
>
> Yes I am looking at their CVS. According to the commit logs, and the 
> file diffs, it looks like they fixed this bug in the CVS five days 
> ago. So hopefully you will be okay with their next release. :)
>
> Also, I noticed you keep making new message subjects for what is 
> essentially the same conversation thread. This is cross-posting, and 
> can lead to confusion. If you do choose to change message subjects, 
> can you at least do it while replying to your original message? That 
> way mail readers like mine (thunderbird) can figure out that the 
> threads are connected.
>
> Regards,
>
> Jeff Bischoff
> Kenneth L Kurz & Associates, Inc.
>
> Randahl Fink Isaksen wrote:
>> Thanks Jeff. Well, I am looking at the source of 1.1.11 which version 
>> are you looking at (what do you mean by "current")? Is it the latest 
>> and greatest sources in a CVS you are looking at?
>>
>> And yes I did write to the facelets list and file a bug report.
>>
>> Randahl
>>
>>
>> Jeff Bischoff wrote:
>>> Randahl,
>>>
>>> You posted the following code from FaceletViewHandler
>>>
>>> >        String encoding = null;
>>> >        ResponseWriter writer = renderKit.createResponseWriter(
>>> >                NullWriter.Instance, contentType, encoding);
>>> >        encoding = getResponseEncoding(context,
>>> > writer.getCharacterEncoding());
>>>
>>> Those lines certainly looked odd (i.e. why is encoding set after the 
>>> call to createResponseWriter?), so I looked up the current source 
>>> file. This is what I found:
>>>
>>> -------------------------------------------
>>> // get the encoding
>>> String encoding = (String) 
>>> extContext.getRequestMap().get("facelets.Encoding");
>>>
>>> // Create a dummy ResponseWriter with a bogus writer,
>>> // so we can figure out what content type the ReponseWriter
>>> // is really going to ask for
>>> ResponseWriter writer = renderKit.createResponseWriter(
>>>                 NullWriter.Instance, contentType, encoding);
>>>
>>> contentType = getResponseContentType(context, writer.getContentType());
>>> encoding = getResponseEncoding(context, writer.getCharacterEncoding());
>>>
>>> // apply them to the response
>>> response.setContentType(contentType + "; charset=" + encoding);
>>>
>>> // removed 2005.8.23 to comply with J2EE 1.3
>>> // response.setCharacterEncoding(encoding);
>>>
>>> // Now, clone with the real writer
>>> writer = writer.cloneWithWriter(response.getWriter());
>>>
>>> return writer;
>>> -------------------------------------------
>>>
>>> Notice in this code, there is no explicitly setting the encoding to 
>>> null. Actually, it seems like they do a bit of work to try to get 
>>> the correct encoding. Perhaps there was a bug in the version you are 
>>> looking at, but they have since fixed it?
>>>
>>> > I sincerely hope the Facelets developers will comment on this. 
>>> Thank you.
>>> >
>>>
>>> I hope they will too, assuming you posted this to their mailing 
>>> list. I wouldn't really expect them to respond here. :)
>>>
>>> Regards,
>>>
>>> Jeff Bischoff
>>> Kenneth L Kurz & Associates, Inc.
>>>
>>> Randahl Fink Isaksen wrote:
>>>> I finally found out why the combination of Facelets 1.1.11 and 
>>>> MyFaces 1.1.4 makes it impossible to serve UTF-8. The problem is 
>>>> that they both expect each other to provide the encoding. First the 
>>>> FaceletViewHandler tries to make MyFaces decide which encoding to 
>>>> use by doing this:
>>>>
>>>
>>>>
>>>> For now, just notice here that createResponseWriter() is invoked 
>>>> with an encoding of null. In MyFaces the default render kit is 
>>>> HtmlRenderKitImpl and when Facelets call createResponseWriter() 
>>>> with a null encoding MyFaces responds by doing this:
>>>>
>>>>        if(characterEncoding==null)
>>>>        {
>>>>            characterEncoding = 
>>>> HtmlRendererUtils.DEFAULT_CHAR_ENCODING;
>>>>        }
>>>>
>>>> So MyFaces essentially says that if Facelets does not state 
>>>> explicetly which encoding it wants it just uses its default 
>>>> encoding, and DEFAULT_CHAR_ENCODING is in MyFaces equal to ISO-8859-1.
>>>>
>>>> Now, back to the first code snippet - in the last line of the shown 
>>>> FaceletViewHandler code above a method called getResponseEncoding() 
>>>> is invoked and it contains this code:
>>>>
>>>>        if (encoding == null) {
>>>>            encoding = "UTF-8";
>>>>
>>>> This code will not have any effect because Facelets already invoked 
>>>> MyFaces with a null encoding which made MyFaces fall back to 
>>>> ISO-8859-1 and thus the encoding is not null anymore.
>>>>
>>>> So is this a MyFaces bug or a Facelets bug? In the code above 
>>>> Facelets deliberately chooses not to decide for a specific 
>>>> character encoding thereby expecting that
>>>>
>>>> 1. the JSF implementation provides the developer with means for 
>>>> specifying which character encoding he wants and that
>>>> 2. the render kit provided by the JSF implementation will return 
>>>> this desired character encoding
>>>>
>>>> This is in my opinion a wrong assumption - nothing in the JSF 
>>>> specification 1.1 says this is so. On the contrary the 
>>>> specification explicitly states that the encoding parameter is 
>>>> required when you invoke createReponseWriter, quote: "... the 
>>>> required value for the characterEncoding parameter for this 
>>>> method..." (section 8.1). So invoking createResponseWriter() with a 
>>>> null encoding is a violation of the specification, and thus I think 
>>>> this is a serious Facelets bug.
>>>>
>>>> I sincerely hope the Facelets developers will comment on this. 
>>>> Thank you.
>>>>
>>>> Randahl
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>>
>>>
>>
>>
>>
>>
>
>
>
>


Re: Its a bug: Facelets+MyFaces cannot serve UTF-8 and here is why!

Posted by Jeff Bischoff <jb...@klkurz.com>.
Randahl,

Yes I am looking at their CVS. According to the commit logs, and the 
file diffs, it looks like they fixed this bug in the CVS five days ago. 
So hopefully you will be okay with their next release. :)

Also, I noticed you keep making new message subjects for what is 
essentially the same conversation thread. This is cross-posting, and can 
lead to confusion. If you do choose to change message subjects, can you 
at least do it while replying to your original message? That way mail 
readers like mine (thunderbird) can figure out that the threads are 
connected.

Regards,

Jeff Bischoff
Kenneth L Kurz & Associates, Inc.

Randahl Fink Isaksen wrote:
> Thanks Jeff. Well, I am looking at the source of 1.1.11 which version 
> are you looking at (what do you mean by "current")? Is it the latest and 
> greatest sources in a CVS you are looking at?
> 
> And yes I did write to the facelets list and file a bug report.
> 
> Randahl
> 
> 
> Jeff Bischoff wrote:
>> Randahl,
>>
>> You posted the following code from FaceletViewHandler
>>
>> >        String encoding = null;
>> >        ResponseWriter writer = renderKit.createResponseWriter(
>> >                NullWriter.Instance, contentType, encoding);
>> >        encoding = getResponseEncoding(context,
>> > writer.getCharacterEncoding());
>>
>> Those lines certainly looked odd (i.e. why is encoding set after the 
>> call to createResponseWriter?), so I looked up the current source 
>> file. This is what I found:
>>
>> -------------------------------------------
>> // get the encoding
>> String encoding = (String) 
>> extContext.getRequestMap().get("facelets.Encoding");
>>
>> // Create a dummy ResponseWriter with a bogus writer,
>> // so we can figure out what content type the ReponseWriter
>> // is really going to ask for
>> ResponseWriter writer = renderKit.createResponseWriter(
>>                 NullWriter.Instance, contentType, encoding);
>>
>> contentType = getResponseContentType(context, writer.getContentType());
>> encoding = getResponseEncoding(context, writer.getCharacterEncoding());
>>
>> // apply them to the response
>> response.setContentType(contentType + "; charset=" + encoding);
>>
>> // removed 2005.8.23 to comply with J2EE 1.3
>> // response.setCharacterEncoding(encoding);
>>
>> // Now, clone with the real writer
>> writer = writer.cloneWithWriter(response.getWriter());
>>
>> return writer;
>> -------------------------------------------
>>
>> Notice in this code, there is no explicitly setting the encoding to 
>> null. Actually, it seems like they do a bit of work to try to get the 
>> correct encoding. Perhaps there was a bug in the version you are 
>> looking at, but they have since fixed it?
>>
>> > I sincerely hope the Facelets developers will comment on this. Thank 
>> you.
>> >
>>
>> I hope they will too, assuming you posted this to their mailing list. 
>> I wouldn't really expect them to respond here. :)
>>
>> Regards,
>>
>> Jeff Bischoff
>> Kenneth L Kurz & Associates, Inc.
>>
>> Randahl Fink Isaksen wrote:
>>> I finally found out why the combination of Facelets 1.1.11 and 
>>> MyFaces 1.1.4 makes it impossible to serve UTF-8. The problem is that 
>>> they both expect each other to provide the encoding. First the 
>>> FaceletViewHandler tries to make MyFaces decide which encoding to use 
>>> by doing this:
>>>
>>
>>>
>>> For now, just notice here that createResponseWriter() is invoked with 
>>> an encoding of null. In MyFaces the default render kit is 
>>> HtmlRenderKitImpl and when Facelets call createResponseWriter() with 
>>> a null encoding MyFaces responds by doing this:
>>>
>>>        if(characterEncoding==null)
>>>        {
>>>            characterEncoding = HtmlRendererUtils.DEFAULT_CHAR_ENCODING;
>>>        }
>>>
>>> So MyFaces essentially says that if Facelets does not state 
>>> explicetly which encoding it wants it just uses its default encoding, 
>>> and DEFAULT_CHAR_ENCODING is in MyFaces equal to ISO-8859-1.
>>>
>>> Now, back to the first code snippet - in the last line of the shown 
>>> FaceletViewHandler code above a method called getResponseEncoding() 
>>> is invoked and it contains this code:
>>>
>>>        if (encoding == null) {
>>>            encoding = "UTF-8";
>>>
>>> This code will not have any effect because Facelets already invoked 
>>> MyFaces with a null encoding which made MyFaces fall back to 
>>> ISO-8859-1 and thus the encoding is not null anymore.
>>>
>>> So is this a MyFaces bug or a Facelets bug? In the code above 
>>> Facelets deliberately chooses not to decide for a specific character 
>>> encoding thereby expecting that
>>>
>>> 1. the JSF implementation provides the developer with means for 
>>> specifying which character encoding he wants and that
>>> 2. the render kit provided by the JSF implementation will return this 
>>> desired character encoding
>>>
>>> This is in my opinion a wrong assumption - nothing in the JSF 
>>> specification 1.1 says this is so. On the contrary the specification 
>>> explicitly states that the encoding parameter is required when you 
>>> invoke createReponseWriter, quote: "... the required value for the 
>>> characterEncoding parameter for this method..." (section 8.1). So 
>>> invoking createResponseWriter() with a null encoding is a violation 
>>> of the specification, and thus I think this is a serious Facelets bug.
>>>
>>> I sincerely hope the Facelets developers will comment on this. Thank 
>>> you.
>>>
>>> Randahl
>>>
>>>
>>>
>>>
>>>
>>
>>
>>
>>
> 
> 
> 
> 



Re: Its a bug: Facelets+MyFaces cannot serve UTF-8 and here is why!

Posted by Randahl Fink Isaksen <ra...@rockit.dk>.
Thanks Jeff. Well, I am looking at the source of 1.1.11 which version 
are you looking at (what do you mean by "current")? Is it the latest and 
greatest sources in a CVS you are looking at?

And yes I did write to the facelets list and file a bug report.

Randahl


Jeff Bischoff wrote:
> Randahl,
>
> You posted the following code from FaceletViewHandler
>
> >        String encoding = null;
> >        ResponseWriter writer = renderKit.createResponseWriter(
> >                NullWriter.Instance, contentType, encoding);
> >        encoding = getResponseEncoding(context,
> > writer.getCharacterEncoding());
>
> Those lines certainly looked odd (i.e. why is encoding set after the 
> call to createResponseWriter?), so I looked up the current source 
> file. This is what I found:
>
> -------------------------------------------
> // get the encoding
> String encoding = (String) 
> extContext.getRequestMap().get("facelets.Encoding");
>
> // Create a dummy ResponseWriter with a bogus writer,
> // so we can figure out what content type the ReponseWriter
> // is really going to ask for
> ResponseWriter writer = renderKit.createResponseWriter(
>                 NullWriter.Instance, contentType, encoding);
>
> contentType = getResponseContentType(context, writer.getContentType());
> encoding = getResponseEncoding(context, writer.getCharacterEncoding());
>
> // apply them to the response
> response.setContentType(contentType + "; charset=" + encoding);
>
> // removed 2005.8.23 to comply with J2EE 1.3
> // response.setCharacterEncoding(encoding);
>
> // Now, clone with the real writer
> writer = writer.cloneWithWriter(response.getWriter());
>
> return writer;
> -------------------------------------------
>
> Notice in this code, there is no explicitly setting the encoding to 
> null. Actually, it seems like they do a bit of work to try to get the 
> correct encoding. Perhaps there was a bug in the version you are 
> looking at, but they have since fixed it?
>
> > I sincerely hope the Facelets developers will comment on this. Thank 
> you.
> >
>
> I hope they will too, assuming you posted this to their mailing list. 
> I wouldn't really expect them to respond here. :)
>
> Regards,
>
> Jeff Bischoff
> Kenneth L Kurz & Associates, Inc.
>
> Randahl Fink Isaksen wrote:
>> I finally found out why the combination of Facelets 1.1.11 and 
>> MyFaces 1.1.4 makes it impossible to serve UTF-8. The problem is that 
>> they both expect each other to provide the encoding. First the 
>> FaceletViewHandler tries to make MyFaces decide which encoding to use 
>> by doing this:
>>
>
>>
>> For now, just notice here that createResponseWriter() is invoked with 
>> an encoding of null. In MyFaces the default render kit is 
>> HtmlRenderKitImpl and when Facelets call createResponseWriter() with 
>> a null encoding MyFaces responds by doing this:
>>
>>        if(characterEncoding==null)
>>        {
>>            characterEncoding = HtmlRendererUtils.DEFAULT_CHAR_ENCODING;
>>        }
>>
>> So MyFaces essentially says that if Facelets does not state 
>> explicetly which encoding it wants it just uses its default encoding, 
>> and DEFAULT_CHAR_ENCODING is in MyFaces equal to ISO-8859-1.
>>
>> Now, back to the first code snippet - in the last line of the shown 
>> FaceletViewHandler code above a method called getResponseEncoding() 
>> is invoked and it contains this code:
>>
>>        if (encoding == null) {
>>            encoding = "UTF-8";
>>
>> This code will not have any effect because Facelets already invoked 
>> MyFaces with a null encoding which made MyFaces fall back to 
>> ISO-8859-1 and thus the encoding is not null anymore.
>>
>> So is this a MyFaces bug or a Facelets bug? In the code above 
>> Facelets deliberately chooses not to decide for a specific character 
>> encoding thereby expecting that
>>
>> 1. the JSF implementation provides the developer with means for 
>> specifying which character encoding he wants and that
>> 2. the render kit provided by the JSF implementation will return this 
>> desired character encoding
>>
>> This is in my opinion a wrong assumption - nothing in the JSF 
>> specification 1.1 says this is so. On the contrary the specification 
>> explicitly states that the encoding parameter is required when you 
>> invoke createReponseWriter, quote: "... the required value for the 
>> characterEncoding parameter for this method..." (section 8.1). So 
>> invoking createResponseWriter() with a null encoding is a violation 
>> of the specification, and thus I think this is a serious Facelets bug.
>>
>> I sincerely hope the Facelets developers will comment on this. Thank 
>> you.
>>
>> Randahl
>>
>>
>>
>>
>>
>
>
>
>


Re: Its a bug: Facelets+MyFaces cannot serve UTF-8 and here is why!

Posted by Jeff Bischoff <jb...@klkurz.com>.
Randahl,

You posted the following code from FaceletViewHandler

 >        String encoding = null;
 >        ResponseWriter writer = renderKit.createResponseWriter(
 >                NullWriter.Instance, contentType, encoding);
 >        encoding = getResponseEncoding(context,
 > writer.getCharacterEncoding());

Those lines certainly looked odd (i.e. why is encoding set after the 
call to createResponseWriter?), so I looked up the current source file. 
This is what I found:

-------------------------------------------
// get the encoding
String encoding = (String) 
extContext.getRequestMap().get("facelets.Encoding");

// Create a dummy ResponseWriter with a bogus writer,
// so we can figure out what content type the ReponseWriter
// is really going to ask for
ResponseWriter writer = renderKit.createResponseWriter(
                 NullWriter.Instance, contentType, encoding);

contentType = getResponseContentType(context, writer.getContentType());
encoding = getResponseEncoding(context, writer.getCharacterEncoding());

// apply them to the response
response.setContentType(contentType + "; charset=" + encoding);

// removed 2005.8.23 to comply with J2EE 1.3
// response.setCharacterEncoding(encoding);

// Now, clone with the real writer
writer = writer.cloneWithWriter(response.getWriter());

return writer;
-------------------------------------------

Notice in this code, there is no explicitly setting the encoding to 
null. Actually, it seems like they do a bit of work to try to get the 
correct encoding. Perhaps there was a bug in the version you are looking 
at, but they have since fixed it?

 > I sincerely hope the Facelets developers will comment on this. Thank you.
 >

I hope they will too, assuming you posted this to their mailing list. I 
wouldn't really expect them to respond here. :)

Regards,

Jeff Bischoff
Kenneth L Kurz & Associates, Inc.

Randahl Fink Isaksen wrote:
> I finally found out why the combination of Facelets 1.1.11 and MyFaces 
> 1.1.4 makes it impossible to serve UTF-8. The problem is that they both 
> expect each other to provide the encoding. First the FaceletViewHandler 
> tries to make MyFaces decide which encoding to use by doing this:
> 

> 
> For now, just notice here that createResponseWriter() is invoked with an 
> encoding of null. In MyFaces the default render kit is HtmlRenderKitImpl 
> and when Facelets call createResponseWriter() with a null encoding 
> MyFaces responds by doing this:
> 
>        if(characterEncoding==null)
>        {
>            characterEncoding = HtmlRendererUtils.DEFAULT_CHAR_ENCODING;
>        }
> 
> So MyFaces essentially says that if Facelets does not state explicetly 
> which encoding it wants it just uses its default encoding, and 
> DEFAULT_CHAR_ENCODING is in MyFaces equal to ISO-8859-1.
> 
> Now, back to the first code snippet - in the last line of the shown 
> FaceletViewHandler code above a method called getResponseEncoding() is 
> invoked and it contains this code:
> 
>        if (encoding == null) {
>            encoding = "UTF-8";
> 
> This code will not have any effect because Facelets already invoked 
> MyFaces with a null encoding which made MyFaces fall back to ISO-8859-1 
> and thus the encoding is not null anymore.
> 
> So is this a MyFaces bug or a Facelets bug? In the code above Facelets 
> deliberately chooses not to decide for a specific character encoding 
> thereby expecting that
> 
> 1. the JSF implementation provides the developer with means for 
> specifying which character encoding he wants and that
> 2. the render kit provided by the JSF implementation will return this 
> desired character encoding
> 
> This is in my opinion a wrong assumption - nothing in the JSF 
> specification 1.1 says this is so. On the contrary the specification 
> explicitly states that the encoding parameter is required when you 
> invoke createReponseWriter, quote: "... the required value for the 
> characterEncoding parameter for this method..." (section 8.1). So 
> invoking createResponseWriter() with a null encoding is a violation of 
> the specification, and thus I think this is a serious Facelets bug.
> 
> I sincerely hope the Facelets developers will comment on this. Thank you.
> 
> Randahl
> 
> 
> 
> 
>