OK, agreed.

Thanks for the explanation!

Regards,
Jakob

2011/5/6 Leonardo Uribe <[email protected]>:
> Hi
>
> Unfortunately, I already tried it without success. The problem is the 
> algorithm
> for calculate the viewId when suffix mapping is used "requires" check if the
> physical resource exists, and there is no access from this part of the
> lifecycle to that object (because is a facelets object, so the only one
> who knows about it is facelets vdl). That's the reason why in this case a spec
> change was required to fix it.
>
> Note in some part of MYFACES-2628 it says:
>
> "....To solve this issue maybe we can hold a duplicate instance to
> ResourceResolver, one on facelets vdl (specifically on the factory) and the
> other one on RestoreViewSupport instance. After all, this class is expected
> to be stateless, so it will be no problem. ..."
>
> It is possible to create a fix, but from my point of view since there
> is a proper
> fix on 2.1.x, that version should be used in this case instead.
>
> regards,
>
> Leonardo Uribe
>
> 2011/5/6 Jakob Korherr <[email protected]>:
>> Hi,
>>
>> we could provide a config parameter that enables this fix also in MyFaces 
>> 2.0.x.
>>
>> WDYT Leo?
>>
>> Regards,
>> Jakob
>>
>> 2011/5/6 Leonardo Uribe <[email protected]>:
>>> Hi
>>>
>>> It is a known problem in JSF 2.0. see:
>>>
>>> https://issues.apache.org/jira/browse/MYFACES-2628
>>> http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-893
>>>
>>> Theorically there are 2 options:
>>>
>>> 1. Use MyFaces core 2.1.0-SNAPSHOT.
>>> 2. Use prefix mapping for your pages instead suffix mapping.
>>>
>>> Please close the issue as duplicate.
>>>
>>> regards,
>>>
>>> Leonardo Uribe
>>>
>>> 2011/5/6 Jakob Korherr <[email protected]>:
>>>> Hi,
>>>>
>>>> This seems to be an implementation issue of MyFaces. Please file a
>>>> ticket in our JIRA at https://issues.apache.org/jira/browse/MYFACES
>>>>
>>>> Thanks!
>>>>
>>>> Regards,
>>>> Jakob
>>>>
>>>> 2011/5/6 Juan Fernandez-Corugedo Igual <[email protected]>:
>>>>>
>>>>> Hi.
>>>>>
>>>>> I'm working in a project with Myfaces 2.0.5 and I have had a problem with 
>>>>> a
>>>>> custom ResourceResolver.
>>>>>
>>>>> I have coded a ResourceResolver that dynamically builds an XHTML file when
>>>>> the engine asks him to resolve a certain URL.
>>>>>
>>>>> To achieve this, I have update the web.xml as follows:
>>>>>
>>>>>   <context-param>
>>>>>     <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
>>>>>     <param-value>*.test;*.xhtml</param-value>
>>>>>   </context-param>
>>>>>
>>>>>   <context-param>
>>>>>       <param-name>javax.faces.FACELETS_RESOURCE_RESOLVER</param-name>
>>>>>
>>>>> <param-value>com.test.view.facelets.CustomResourceResolver</param-value>
>>>>>   </context-param>
>>>>>
>>>>> My CustomResourceResolver is very simple:
>>>>>
>>>>> package com.test.view.facelets;
>>>>>
>>>>> import java.io.ByteArrayInputStream;
>>>>> import java.io.IOException;
>>>>> import java.io.InputStream;
>>>>> import java.net.MalformedURLException;
>>>>> import java.net.URL;
>>>>> import java.net.URLConnection;
>>>>> import java.net.URLStreamHandler;
>>>>>
>>>>> import javax.faces.view.facelets.ResourceResolver;
>>>>>
>>>>> public class CustomResourceResolver extends ResourceResolver {
>>>>>
>>>>>     private ResourceResolver innerResourceResolver;
>>>>>
>>>>>     private String viewSource = ".... xhtml of the test page ....";
>>>>>
>>>>>     public CustomResourceResolver(ResourceResolver resourceResolver){
>>>>>         this.innerResourceResolver = resourceResolver;
>>>>>     }
>>>>>
>>>>>     @Override
>>>>>     public URL resolveUrl(String path) {
>>>>>         System.out.println("Buscando la URL del recurso: " + path);
>>>>>         URL result = null;
>>>>>
>>>>>         if(path.endsWith(".test")){
>>>>>             try{
>>>>>                 result = getUrlForResourceAsStream(path);
>>>>>             }catch(Exception e){
>>>>>                 System.out.println("Unexpected error while obtaining the 
>>>>> URL
>>>>> from resource " + path);
>>>>>                 e.printStackTrace(System.out);
>>>>>             }
>>>>>
>>>>>         }else{
>>>>>             result = this.innerResourceResolver.resolveUrl(path);
>>>>>         }
>>>>>
>>>>>         return result;
>>>>>     }
>>>>>
>>>>>     private URL getUrlForResourceAsStream(String path) throws
>>>>> MalformedURLException {
>>>>>         URLStreamHandler handler = new URLStreamHandler() {
>>>>>             protected URLConnection openConnection(URL u) throws 
>>>>> IOException
>>>>> {
>>>>>                 final String file = u.getFile();
>>>>>                 return new URLConnection(u) {
>>>>>                     public void connect() throws IOException {
>>>>>                     }
>>>>>
>>>>>                     public InputStream getInputStream() throws 
>>>>> IOException {
>>>>>                         System.out.println("Opening internal url to " +
>>>>> file);
>>>>>
>>>>>                         try{
>>>>>                             System.out.println("Generando el InputStream 
>>>>> de
>>>>> la pagina:\n" + viewSource);
>>>>>                             return new
>>>>> ByteArrayInputStream(viewSource.getBytes("UTF-8"));
>>>>>                         }catch (Exception e) {
>>>>>                             e.printStackTrace();
>>>>>                             throw new RuntimeException("Unexpected error
>>>>> while obtaining the view", e);
>>>>>                         }
>>>>>                     }
>>>>>                 };
>>>>>             }
>>>>>         };
>>>>>         return new URL("internal", null, 0, path, handler);
>>>>>     }
>>>>> }
>>>>>
>>>>>
>>>>> As you can see, the code is very simple. When the suffix matches the 
>>>>> pattern
>>>>> ".test", the Resolver creates a mock URL with a backing
>>>>> ByteArrayInputStream. If the suffix does not matches the pattern, the 
>>>>> normal
>>>>> ResourceResolver is invoked.
>>>>>
>>>>> With this configuration and code, when I request the URL:
>>>>> http://xxxxxx:yyyy/zzzzz/anything.test  the application fails with error:
>>>>>
>>>>> The problem is this:
>>>>>
>>>>> java.lang.NullPointerException
>>>>>     at java.lang.StringBuilder.<init>(StringBuilder.java:92)
>>>>>     at
>>>>> org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.getRenderedViewId(FaceletViewDeclarationLanguage.java:1630)
>>>>>     at
>>>>> org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.buildView(FaceletViewDeclarationLanguage.java:279)
>>>>>     ....
>>>>>
>>>>> The executes the viewHandler.createView("xxxx.test") method. It internally
>>>>> calls the getViewHandlerSupport().calculateViewId(context, viewId); method
>>>>> to obtain the viewId, and this method calls
>>>>> DefaultViewHandlerSupport.checkResourceExists(FacesContext context, String
>>>>> viewId), that checks the physical file of this resource, but there are not
>>>>> any file for this resource!!!! so it return false, and the viewId of the
>>>>> resulting ViewRoot is assigned to null.
>>>>>
>>>>> This causes a NullPointerException later, when the code executes the
>>>>> ViewDeclarationLanguage.buildView(FacesContext context, ViewRoot 
>>>>> viewRoot).
>>>>>
>>>>> If I change the Myfaces implementation with Mojarra 2.0.4, it works
>>>>> perfectly, so I think that the problem is in the implementation.
>>>>>
>>>>> I can't extend any class of interface of Myfaces, because my application
>>>>> must not be coupled to a specific implementation.
>>>>>
>>>>> I have attached two web projects, one with Myfaces configuration, that
>>>>> fails, and the same project with Mojarra configuration, that works (Both
>>>>> without the jars of the implementation)
>>>>>
>>>>> How can I solve this?
>>>>>
>>>>> Thanks
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Jakob Korherr
>>>>
>>>> blog: http://www.jakobk.com
>>>> twitter: http://twitter.com/jakobkorherr
>>>> work: http://www.irian.at
>>>>
>>>
>>
>>
>>
>> --
>> Jakob Korherr
>>
>> blog: http://www.jakobk.com
>> twitter: http://twitter.com/jakobkorherr
>> work: http://www.irian.at
>>
>



-- 
Jakob Korherr

blog: http://www.jakobk.com
twitter: http://twitter.com/jakobkorherr
work: http://www.irian.at

Reply via email to