So a recent update to the Google App Engine SDK broke my JSF 2.0 web application. I received this message on local server start-up:
WARNING: Error starting handlers
Throwable occurred: java.lang.NoClassDefFoundError:
javax.naming.InitialContext is a restricted class. Please see the Google
App Engine developer’s guide for more details.
Apparently this was due to how JSF checks if it can use InitialContext first (bug report)- by invoking it. Unfortunately, this sends GAE into a panic, since javax.naming.InitialContext is not one of the whitelisted JRE classes.
**Edit 3: for your convenience, I have pre-packaged this solution into its own .jar file. See bottom of post for further details.
Note: If you haven’t yet set up your JSF-enabled GAE project, follow this guide.
The solution: override the JSF implementation of WebConfiguration, at least until GAE or Mojarra put out a fix. At the very least, this will let you once again use JSF on 1.2.6 locally – I’m still hitting an error 500 when deployed on the app server, but it might be due to some other libs in my web app*. Please post a comment if you find a better solution!**
Here are the steps I took:
- Add jsf-api.jar and jsf-impl.jar to your build path.
- Create the package structure com.sun.faces.config
- Create a WebConfiguration class in com.sun.faces.config and put in the following code [.java link].
Make sure that, if you’ve just updated the GAE plugin in Eclipse, that your project has been updated to use GAE 1.2.6 too.
*Edit: the error 500 I stated earlier was in fact due to another library causing a crash – probably another 1.2.6 incompatibility? So if you implement this patch, other libraries aside, you should be able to run your app locally and on app engine.
Edit 2: the error 500 was due to an old Jersey core/client implementation, and upgrading to 1.0.3 fixed it. Also, if you’re in Eclipse and need to upgrade your 1.2.5 web project to 1.2.6 but get an error about “dev_appserver” or “KickStart”, just add the following argument to your Run Configuration’s Arguments/vm tab:
-javaagent:C:\eclipse\plugins\com.google.appengine.eclipse.sdkbundle_1.2.6.v200910131704\appengine-java-sdk-1.2.6\lib\agent\appengine-agent.jar
Where C:\eclipse is where Eclipse has been installed.
**Edit 3: for your convenience, I have pre-packaged this solution into its own .jar file, which can be used interchangeably with the official jsf-impl.jar. Neither jsf-impl-gae.jar or jsf-api.jar, or the aforementioned solution have to be on the build path with this solution. Just place this in /war/WEB-INF/lib and delete the original jsf-impl.jar.
Download jsf-impl-gae.jar | Full Readme | Eclipse project on SVN
And if you’re interested in the fix on the Sun Jersey Core library, see my post here.
Enjoy!
Thanks a lot for this Josh. It’s saved me a lot of work.
By: Scott Stevenson on October 25, 2009
at 12:21 pm
Thank you Josh!
By: Mirco Attocchi on November 11, 2009
at 2:48 am
[…] ran into the problem detailed here ( JNDI problem in jsf 2.0 and google app engine ) right off the bat. I tried to use his packaged jar, but app-engine kept giving me an exception […]
By: JSF 2.0.2 and Google App Engine « DigitalJoel on December 21, 2009
at 5:00 pm
this solution applies to sdk 1.3.0?
By: Gleidson Guimarães Moura on December 23, 2009
at 5:42 am
Thank you, Josh. You Class seems to be working on 1.3.0, too.
Would you happen to know if this will be resolved directly by either the mojarra project or the gae project in a future release.
I saw your solution mentioned in one of the bug comments and thought that you might be “in the know.”
By: Dennis Gesker on January 4, 2010
at 4:56 pm
@Scott, Mirco: you’re welcome!
@Gleidson: looks like from Dennis’ tests, this solution is still compatible
@Dennis: I’m not affiliated with either project, so I can’t provide you any estimates on a proper fix – sorry!
By: joshjcarrier on January 4, 2010
at 6:42 pm
Another thanks here Josh. Used it to get GAE working with PrimeFaces, Spring and Maven.
By: Brendan Haire on January 19, 2010
at 2:37 pm
I got the problem stated here in the first instance.
I wonder why this site https://sites.google.com/a/wildstartech.com/adventures-in-java/Java-Platform-Enterprise-Edition/JavaServer-Faces/sun-javaserver-faces-reference-implementation/configuring-jsf-20-to-run-on-the-google-appengine/javaserverfaces-20-and-google-app-engine-compatibility-issues doesn’t mention of this problem.
Your fix worked like a charm! Thanks, you saved my day.
Regards,
Gurdev
By: Gurdev Parmar on March 21, 2010
at 7:51 am
[…] but couldn’t figure out the source of this exception. Then I’ve Googled this article. I’ve followed instructions on this blog (thanks Josh) com.sun.faces.config.WebConfiguration […]
By: Getting started with Google App Engine and JSF on March 25, 2010
at 11:44 am
Thanks a lot for this!!
By: Tulio Domingos on April 16, 2010
at 8:13 am
Hi,
Thanks a lot for the jar – worked great for JSF2.
I was trying to use seam-2.2.1.CR1 with JSF2. But the deployment fails with the following stack trace as soon as I add the seam jars.
Any help is greatly appreciated.
Thanks.
Aaron
com.sun.faces.config.ConfigurationException: CONFIGURATION FAILED! com.sun.facelets.compiler.Compiler
at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:354)
at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:219)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:530)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:135)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1218)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:500)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:448)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:117)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:117)
at org.mortbay.jetty.Server.doStart(Server.java:217)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:188)
at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:147)
at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:219)
at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:162)
at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
at com.google.appengine.tools.development.DevAppServerMain.(DevAppServerMain.java:113)
at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:89)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:110)
Caused by: java.lang.ClassNotFoundException: com.sun.facelets.compiler.Compiler
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:151)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2389)
at java.lang.Class.getConstructor0(Class.java:2699)
at java.lang.Class.getDeclaredConstructor(Class.java:1985)
at com.google.appengine.tools.development.agent.runtime.Runtime$2.run(Runtime.java:129)
at com.google.appengine.tools.development.agent.runtime.Runtime$2.run(Runtime.java:127)
at java.security.AccessController.doPrivileged(Native Method)
at com.google.appengine.tools.development.agent.runtime.Runtime.newInstance(Runtime.java:126)
at com.sun.faces.config.processor.AbstractConfigProcessor.createInstance(AbstractConfigProcessor.java:269)
at com.sun.faces.config.processor.LifecycleConfigProcessor.addPhaseListeners(LifecycleConfigProcessor.java:131)
at com.sun.faces.config.processor.LifecycleConfigProcessor.process(LifecycleConfigProcessor.java:110)
at com.sun.faces.config.processor.AbstractConfigProcessor.invokeNext(AbstractConfigProcessor.java:113)
at com.sun.faces.config.processor.FactoryConfigProcessor.process(FactoryConfigProcessor.java:222)
at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:335)
By: Aaron on April 17, 2010
at 5:53 am
Thanks man that was nice.
Just FYI.. I know people are genious still..
when you go on
http://code.google.com/p/joshjcarrier/source/browse/trunk/Sun+JSF+GAE/jsf-impl-gae.jar
for downloading jar just click on “view raw file”
By: Manoj on May 11, 2010
at 3:16 pm
Hi Josh,
The issue that you pointed to has been closed as invalid – they say it is expected behavior?
By: raj on July 20, 2010
at 3:30 pm
Don’t use this jar anymore. its outdated…
go and get yourself the latest mojjara and binary and get the WebConfiguration.java and rop it into com.sun.faces.config and comment the entire body of the method private void processJndiEntries(String contextName)
this jar was great and very helpfull in the past… used it for a while… but now its outdated….
By: Daniel on September 29, 2010
at 1:38 pm
Here you can find the complete tutorial on how to use the original mojarra jars with GAE :
http://www.neverslair-blog.net/daniels-tips-and-tutorials/
By: Daniel on October 27, 2010
at 2:06 am
[…] a look at this site https://javadocs.wordpress.com/2009/10/17/mojarra-jsf-2-0-rc2-and-google-app-engine-sdk-1-2-6/ and download this file […]
By: Google App Engine pilvipalvelu ja Java EE 6, osa 3 | Spagettikoodi on December 1, 2010
at 12:13 am
[…] Article discussing the solution to the ‘javax.naming.InitialContext is a restricted class’ problem. (link) […]
By: Google App Engine with JSF2, CDI | The Java Momentum on April 6, 2011
at 1:32 pm
[…] for the java.lang.NoClassDefFoundError: javax.naming.InitialContext is a restricted class. error. Here it is If you enjoyed this article, please consider sharing […]
By: Day2 with JSF Configuring GAE for JSF using Weld | 46 Grandin on May 2, 2011
at 11:33 am
[…] Mojarra JSF 2.0 RC2 and Google App Engine SDK 1.2.6 « Josh Carrier’s Blag […]
By: Google App Engine « cloudzillion on March 2, 2012
at 7:50 am
replacing jsf-impl.jar with jsf-impl-gae.jar worked very well
thank you very much
By: Daniel on March 6, 2012
at 12:52 am
[…] Mojarra JSF 2.0 RC2 and Google App Engine SDK 1.2.6 This article is under – GAE Tutorials , Tags : error gae jsf2 mkyong Founder and Chief Editor of Mkyong.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. […]
By: GAE + JSF : javax.naming.InitialContext is a restricted class on August 28, 2012
at 6:37 pm
[…] JSF 2 impl jar fix – Josh has kindly provided a fix for JSF impl jar which resolves the startup problem […]
By: Using JSF 2 with Google App Engine | Addy Bhardwaj's Tech Scribbling on November 24, 2012
at 8:39 am
Your method of telling all in this article is genuinely pleasant, all
can without difficulty know it, Thanks a lot.
By: Dominga on July 21, 2013
at 5:17 pm
[…] Mojarra JSF 2.0 RC2 and Google App Engine SDK 1.2.6 « Josh Carrier’s Blag […]
By: Google App Engine | No fluff, just stuff...that matters. on February 27, 2014
at 11:24 pm