[ https://issues.apache.org/jira/browse/MYFACES-3128?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Juan Fernandez Corugedo resolved MYFACES-3128. ---------------------------------------------- Resolution: Duplicate Fix Version/s: 2.1.0 2.1.0-SNAPSHOT https://issues.apache.org/jira/browse/MYFACES-2628 > Problems with a custom Resource Resolver > ---------------------------------------- > > Key: MYFACES-3128 > URL: https://issues.apache.org/jira/browse/MYFACES-3128 > Project: MyFaces Core > Issue Type: Bug > Affects Versions: 2.0.5 > Environment: GlassFish 3.0 with Oracle JVM 1.6 and Websphere > 7.0.0.13 with IBM JVM 1.6 > Reporter: Juan Fernandez Corugedo > Fix For: 2.1.0-SNAPSHOT, 2.1.0 > > Attachments: mojarra-test.war, myfaces-test.war > > > Hi. > I'm working in a project with Myfaces 2.0.5 (or 2.1.0) 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 -- This message is automatically generated by JIRA. For more information on JIRA, see: http://www.atlassian.com/software/jira