Bug text:
A DESCRIPTION OF THE REQUEST :
I'm using Apache Trinidad which uses the RI JSF1.2.
If I change Trinidad's demo faces-config.xml file to use a bogus
default-render-kit-id, I get a NPE.
<!-- Use the Trinidad RenderKit -->
<default-render-kit-id>
org.apache.myfaces.trinidad.coreBAD
</default-render-kit-id>
I get this:
java.lang.NullPointerException
at
com.sun.faces.renderkit.RenderKitUtils.getResponseStateManager(RenderKitUtils.java:246)
at
com.sun.faces.lifecycle.RestoreViewPhase.isPostback(RestoreViewPhase.java:267)
at
com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:172)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at
com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:104)
Truncated. see log file for complete stacktrace
This seems to me to be a bug in
com.sun.faces.renderkit.RenderKitUtils.getResponseStateManager:
3 renderKit = factory.getRenderKit(context, renderKitId);
244 }
245 }
246 return renderKit.getResponseStateManager();
Someone fixed the problem in MyFaces.
see this revision:
http://svn.apache.org/viewvc?view=rev&revision=807541
and we think it should be fixed in the RI as well.
JUSTIFICATION :
This NPE was impossible for the end user to track down. We have changed
the render-kit-id from an old release to the new release, and the old
default-render-kit-id was still in the faces-config.xml file. Instead of
getting an error message to tell them that their default-render-kit-id
was bad, they got a NPE.
Suggested fix:
Bugster 6992700 gracefully handle the case where a non-existent
render-kit-id is specified.
SECTION: Modified Files
----------------------------
M jsf-ri/src/main/java/com/sun/faces/context/FacesContextImpl.java
M jsf-ri/src/main/java/com/sun/faces/renderkit/RenderKitUtils.java
- There are two places where a bogus render-kit-id, such as
+<application>
+ <default-render-kit-id>
+ org.apache.myfaces.trinidad.coreBAD
+ </default-render-kit-id>
+</application>
will cause NPE. In both of these places, Mojarra takes the following
action in this case.
* Log an informative SEVERE Level warning message.
* Try to use the HTML_BASIC render-kit instead. If that doesn't work,
throw a FacesException.
M jsf-ri/systest-per-webapp/build-tests.xml
A jsf-ri/systest-per-webapp/bogus-render-kit-id
A jsf-ri/systest-per-webapp/bogus-render-kit-id/src
A jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java
A jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com
A jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun
A jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces
A jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces/systest
A jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces/systest/render
A jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces/systest/render/model
A jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces/systest/render/model/BogusRenderKitIdBean.java
A jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces/systest/render/BogusRenderKitIdTestCase.java
A jsf-ri/systest-per-webapp/bogus-render-kit-id/web
A jsf-ri/systest-per-webapp/bogus-render-kit-id/web/index.xhtml
A jsf-ri/systest-per-webapp/bogus-render-kit-id/web/WEB-INF
A jsf-ri/systest-per-webapp/bogus-render-kit-id/web/WEB-INF/faces-config.xml
- Test content
SECTION: DIFFS
Index: jsf-ri/src/main/java/com/sun/faces/context/FacesContextImpl.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/context/FacesContextImpl.java (revision 8717)
+++ jsf-ri/src/main/java/com/sun/faces/context/FacesContextImpl.java (working copy)
@@ -74,6 +74,7 @@
import com.sun.faces.util.FacesLogger;
import com.sun.faces.util.Util;
import com.sun.faces.renderkit.RenderKitUtils;
+import javax.faces.FacesException;
public class FacesContextImpl extends FacesContext {
@@ -405,6 +406,22 @@
return lastRk;
} else {
lastRk = rkFactory.getRenderKit(this, renderKitId);
+ if (lastRk == null) {
+ if (LOGGER.isLoggable(Level.SEVERE)) {
+ LOGGER.log(Level.SEVERE, "Unable to locate renderkit "
+ + "instance for render-kit-id {0}. Using {1} instead.",
+ new String[]{renderKitId,
+ RenderKitFactory.HTML_BASIC_RENDER_KIT});
+ }
+ renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
+ if (null != vr) {
+ vr.setRenderKitId(renderKitId);
+ }
+ lastRk = rkFactory.getRenderKit(this, renderKitId);
+ if (lastRk == null) {
+ throw new FacesException("Unable to locate renderkit instance for render-kit-id " + renderKitId);
+ }
+ }
lastRkId = renderKitId;
return lastRk;
}
Index: jsf-ri/src/main/java/com/sun/faces/renderkit/RenderKitUtils.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/renderkit/RenderKitUtils.java (revision 8717)
+++ jsf-ri/src/main/java/com/sun/faces/renderkit/RenderKitUtils.java (working copy)
@@ -209,13 +209,30 @@
FactoryFinder
.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
if (factory == null) {
- throw new IllegalStateException();
+ throw new FacesException("Unable to locate RenderKitFactory for " + FactoryFinder.RENDER_KIT_FACTORY);
} else {
RequestStateManager.set(context,
RequestStateManager.RENDER_KIT_IMPL_REQ,
factory);
}
renderKit = factory.getRenderKit(context, renderKitId);
+ if (renderKit == null) {
+ if (LOGGER.isLoggable(Level.SEVERE)) {
+ LOGGER.log(Level.SEVERE, "Unable to locate renderkit "
+ + "instance for render-kit-id {0}. Using {1} instead.",
+ new String [] { renderKitId,
+ RenderKitFactory.HTML_BASIC_RENDER_KIT} );
+ }
+ renderKitId = RenderKitFactory.HTML_BASIC_RENDER_KIT;
+ UIViewRoot root = context.getViewRoot();
+ if (null != root) {
+ root.setRenderKitId(renderKitId);
+ }
+ }
+ renderKit = factory.getRenderKit(context, renderKitId);
+ if (renderKit == null) {
+ throw new FacesException("Unable to locate renderkit instance for render-kit-id " + renderKitId);
+ }
}
}
return renderKit.getResponseStateManager();
Index: jsf-ri/systest-per-webapp/build-tests.xml
===================================================================
--- jsf-ri/systest-per-webapp/build-tests.xml (revision 8717)
+++ jsf-ri/systest-per-webapp/build-tests.xml (working copy)
@@ -132,6 +132,10 @@
value="com/sun/faces/systest/ProcessAsJspxTestCase.class" />
<property name="request-char-encoding-no-session"
value="com/sun/faces/systest/NoSessionCharEncTestCase.class" />
+ <property name="request-char-encoding-no-session"
+ value="com/sun/faces/systest/NoSessionCharEncTestCase.class" />
+ <property name="bogus-render-kit-id"
+ value="com/sun/faces/systest/render/BogusRenderKitIdTestCase.class" />
<!--
EXCLUDED APPLICATIONS:
Index: jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces/systest/render/model/BogusRenderKitIdBean.java
===================================================================
--- jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces/systest/render/model/BogusRenderKitIdBean.java (revision 0)
+++ jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces/systest/render/model/BogusRenderKitIdBean.java (revision 0)
@@ -0,0 +1,64 @@
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ *
https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.faces.systest.render.model;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.RequestScoped;
+import javax.faces.context.FacesContext;
+
+
+_at_ManagedBean
+_at_RequestScoped
+public class BogusRenderKitIdBean {
+
+ public String getConfiguredRenderKitId() {
+ FacesContext context = FacesContext.getCurrentInstance();
+ return context.getApplication().getViewHandler().calculateRenderKitId(context);
+ }
+
+ public String getViewRootRenderKitId() {
+ FacesContext context = FacesContext.getCurrentInstance();
+ return context.getViewRoot().getRenderKitId();
+
+ }
+
+}
Index: jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces/systest/render/BogusRenderKitIdTestCase.java
===================================================================
--- jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces/systest/render/BogusRenderKitIdTestCase.java (revision 0)
+++ jsf-ri/systest-per-webapp/bogus-render-kit-id/src/java/com/sun/faces/systest/render/BogusRenderKitIdTestCase.java (revision 0)
@@ -0,0 +1,74 @@
+
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ *
https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.faces.systest.render;
+
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import com.sun.faces.htmlunit.AbstractTestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+
+public class BogusRenderKitIdTestCase extends AbstractTestCase {
+
+
+ public BogusRenderKitIdTestCase(String name) {
+ super(name);
+ }
+
+ public static Test suite() {
+ return (new TestSuite(BogusRenderKitIdTestCase.class));
+ }
+
+ public void test01() throws Exception {
+
+ HtmlPage page = getPage("/faces/index.xhtml");
+ String text = page.asText();
+ assertTrue("Expected: Configured render-kit-id: "
+ + "org.apache.myfaces.trinidad.coreBAD. "
+ + "UIViewRoot render-kit-id: HTML_BASIC."
+ + " actual: " + text,
+ text.matches("(?s).*Configured\\s*render-kit-id:\\s*org.apache.myfaces.trinidad.coreBAD.*UIViewRoot\\s*render-kit-id:\\s*HTML_BASIC.*"
+
+));
+ }
+}
Index: jsf-ri/systest-per-webapp/bogus-render-kit-id/web/index.xhtml
===================================================================
--- jsf-ri/systest-per-webapp/bogus-render-kit-id/web/index.xhtml (revision 0)
+++ jsf-ri/systest-per-webapp/bogus-render-kit-id/web/index.xhtml (revision 0)
@@ -0,0 +1,20 @@
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="
http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
+ xmlns:h="
http://java.sun.com/jsf/html">
+<head>
+ <title>Hello JSF 2!</title>
+</head>
+<body>
+<h:form id="form">
+<p>Configured render-kit-id: #{bogusRenderKitIdBean.configuredRenderKitId}.</p>
+
+<p>UIViewRoot render-kit-id: #{bogusRenderKitIdBean.viewRootRenderKitId}.</p>
+
+ <h:commandButton id="command" value="submit" />
+</h:form>
+</body>
+</html>
+
+
Index: jsf-ri/systest-per-webapp/bogus-render-kit-id/web/WEB-INF/faces-config.xml
===================================================================
--- jsf-ri/systest-per-webapp/bogus-render-kit-id/web/WEB-INF/faces-config.xml (revision 0)
+++ jsf-ri/systest-per-webapp/bogus-render-kit-id/web/WEB-INF/faces-config.xml (revision 0)
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<faces-config
+ xmlns="
http://java.sun.com/xml/ns/javaee"
+ xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.xsd"
+ version="2.1">
+
+<application>
+ <default-render-kit-id>
+ org.apache.myfaces.trinidad.coreBAD
+ </default-render-kit-id>
+</application>
+
+</faces-config>
--
| ed.burns_at_sun.com | office: +1 407 458 0017
| homepage: | http://ridingthecrest.com/
| 2 work days until German Oracle User's Group Conference
| 7 work days until GlassFish 3.1 Hard Code Freeze