Help

Ok maybe it's not a minefield, but there's still quite a few gotchas when trying to build a Weld application to run in Google App Engine. Since I'm currently renovating my house I decided that it would be fun to blog about the experience (a software guy doing physical labour? weird!!) and it only made sense to kick the GAE tyres to see what all the hype was about. Google have done a great job providing a richly featured cloud platform with plenty of good documentation and a helpful online community, and the free quotas they provide are more than enough for the average low traffic web site.

If you are a typical Java EE developer like me though, you have to approach GAE development with a slightly different development mindset. This article will guide you through the step by step process for getting a Weld-based application running on GAE, and help you to avoid some speed bumps along the way. To get started, you'll need just 2 things - a JDK and Eclipse. For the rest of the stuff that you'll need I'll explain as we go along.

This article is rather large and as such will come in two parts; part 1 will cover project creation, configuration and deploying a minimal app to GAE, and part 2 will dive into some of the issues faced when developing an application.

Oh, by the way if you want to see an example Weld app running on GAE (and see me getting my hands dirty) then you can check out my site at http://www.renovatorsblog.com.

Downloading the Google App Engine SDK Eclipse Plugin

I consider the GAE SDK to be an essential ingredient for GAE app development. It handles all the work of setting up your project, enhancing your entity classes, running your app in local development mode and even deploying your app straight to the production GAE environment.

To install the SDK plugin for Eclipse, you can follow the instructions here:

http://code.google.com/appengine/docs/java/tools/eclipse.html

For the impatient though, here's a summary of the installation steps (for Eclipse 3.5):

  1. Click the Help menu -> Install New Software
  2. In the Work with box, enter http://dl.google.com/eclipse/plugin/3.5, then click the Add button then click OK.
  3. Expand the Plugin entry and check the 'Google Plugin for Eclipse 3.5' item, then expand the SDKs entry and check the 'Google App Engine Java SDK 1.3.0' item.
  4. Click the Next button, and accept any terms of service.
  5. Click the Finish button, wait for installation to complete and then when asked if you want to restart Eclipse, select 'Yes'.

Create an App Engine account

If you don't have one already, then you'll need a GAE account. They're free, all you need is a Google account. So go to the following page and sign up:

http://appengine.google.com

Once you've done that, you should be presented with the 'My Applications' screen, containing an empty list and a 'Create an Application' button:

Create an Application

To be able to deploy an application to GAE, you need to give it a unique application identifier. Clicking the 'Create an Application' button will take you to the following screen, where you can enter your application identifier and a title for your application.

For the authentication options, you either have the choice of using Google Accounts which allows anyone with a Google account to sign in, or you can restrict your application just to the users of a Google Apps domain. We're going to choose door number one, and allow any user with a Google account to sign in.

Of course, if you don't want to then you don't have to require your users to sign in to your application at all (by not specifying any security restrictions for your pages, which we'll get to a bit later). If you do want some kind of security though, the advantage of using the Google accounts API is that you don't have to worry about building the screens, creating user/role entities, writing action code, etc for managing the users in your app - Google takes care of all that for you.

Creating the project

Once you've created a new application with a unique application identifier, you'll be presented with an 'Application Registered Successfully' message. Click the 'View the dashboard...' link to view the dashboard for your new app:

Now that we've created our new app, it's time to create the project. In Eclipse, click File -> New -> Web Application Project to get the following dialog:

Enter a project name and the default package for your classes. Uncheck the 'Use Google Web Toolkit' option (we'll be using JSF 2.0 for our view) and then click Finish to create the new project. Then, right click on the new project in the Package Explorer and select Google -> App Engine Settings.

In the 'Application ID' box, enter the unique application identifier that you registered for your application. For the Version, just enter 1, then click OK to save your settings. The values actually get saved in /war/WEB-INF/appengine-web.xml, so open this file up now and take a look at what it contains. Actually, there's one more setting you need to add to this file, to be able to support user sessions in your app. Add the following line to the file:

<sessions-enabled>true</sessions-enabled>

The complete file should look something like this:

<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
	<application>myapplication</application>
	<version>1</version>
	<sessions-enabled>true</sessions-enabled>
	
	<!-- Configure java.util.logging -->
	<system-properties>
		<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
	</system-properties>
	
</appengine-web-app>

Configuring JSF

Like any servlet-based application, the web.xml file is where most of the important stuff is configured. JSF requires quite a lot of config, so let's look at the options one at a time. By the way, Google actually have some documentation on configuring JSF 2.0 for GAE, so if you're interested you can check it out here.

The first thing we need to do is disable some of the multi-threaded stuff in JSF, as GAE doesn't support multi-threaded applications. Add the following two entries to /war/WEB-INF/web.xml:

  <context-param>
    <param-name>com.sun.faces.enableMultiThreadedStartup</param-name>
    <param-value>false</param-value>
  </context-param>
  
  <context-param>
    <param-name>com.sun.faces.enableThreading</param-name>
    <param-value>false</param-value>
  </context-param>  

Next, we need to configure the Faces servlet. This will alllow requests that end in the .jsf suffix to be handled by JSF:

  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>

Next, we need to configure EL:

  <context-param>
    <param-name>com.sun.faces.expressionFactory</param-name>
    <param-value>com.sun.el.ExpressionFactoryImpl</param-value>
  </context-param>

Finally, there's a couple more options recommended by Google. From what I've read, version 1.3.0 onward of the SDK now supports server-side state saving, however I haven't tried it yet so let's just leave it as client-side for now - the reason for this is to avoid a DatastoreTimeoutException issue that can possibly render a user's session broken until their session has expired (there's a Google Groups thread on this subject here if you're interested).

  <context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>

The following option is mentioned on the JSF 2.0 and GAE compatibility issues page, and is required to prevent a ConfigurationException from occurring because of a threading issue:

  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Production</param-value>
  </context-param>

Once you've added all these options to web.xml, you can also create a faces-config.xml file in the WEB-INF directory also. Since JSF 2.0 this file isn't actually required, but since we'll be putting our navigation rules there later on it won't hurt to create it now. Thankfully in JSF 2.0 there is minimal configuration required here, basically an empty file:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0"
   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_0.xsd">
</faces-config>

Adding the JSF libs to your project

Due to the way that JSF 2.0 checks if it can use InitialContext (see the processJndiEntries() method in WebConfiguration.java - there are certain Java classes that aren't supported in GAE, the ones that are can be found in the JRE whitelist), we need to use a hacked version of jsf-impl.jar that comments out the body of the processJndiEntries() method. You can download a modified jsf-impl.jar from Josh Carrier's blog, direct link here:

Once you download it, place it in the WEB-INF/lib directory in your project. You'll also need jsf-api.jar, which you can get directly from the following link. Once you get it stick it in the WEB-INF/lib directory also.

We'll also need to download the EL libraries. I couldn't really find an official download page just for EL, so just download them straight from the java.net Maven repository:

Once you download them both put them in the WEB-INF/lib directory.

Configuring Weld

The configuration for Weld is quite simple, all you need to do is add the following entry to web.xml:

  <listener>
    <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
  </listener>

Next, create an empty file (no contents whatsoever) called beans.xml in the /war/WEB-INF directory. This is so Weld can find your beans. Getting the Weld libs is a little more work, unfortunately. We've made a few fixes to the Weld code to address some issues with running in GAE, so you can't use the 1.0 download. The option here is to either a) build it yourself (which I'll go through the steps for in a moment, since you might be impatient ;) or b) wait for the 1.0.1.RC2 release, which should be out any day now.

Building Weld from SVN

Compiling the Weld libs from source is really not as scary as many people think, all you need is an SVN client and Maven 2. We only need the weld-servlet module, so start by checking it out from SVN:

svn checkout http://anonsvn.jboss.org/repos/weld/servlet/trunk/

Once you have it checked out, you can build it by running mvn clean install. Once it's built, copy the weld-servlet-xxx.jar file from the build/target directory into the WEB-INF/lib directory of your project. This is the only jar file you need to add to your project for Weld support.

With all the required libraries now in your project's WEB-INF/lib directory, do a refresh in Eclipse (either press F5 or right click on your project and select Refresh) then go into the Java Build Path page (right click on project -> Properties -> Java Build Path) and click on the Libraries tab. Click the 'Add Jars' button and browse to your project's war/WEB-INF/lib directory and select weld-servlet.jar, then click OK. This will allow us to use the CDI annotations in our classes.

Hello World

Now that we've got our project set up and all the required libraries in place, it's time to write some code. Just to ensure that everything is working ok, we're going to start with a simple Hello World example. First of all, create the following bean class in your new project:

import javax.inject.Named;

@Named
public class HelloWorld
{
   public String getMessage()
   {
      return "Hello, World";
   }
}

Next, create the following JSF page in the /war directory (call it helloworld.xhtml):

<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<f:view xmlns="http://www.w3.org/1999/xhtml"
   xmlns:ui="http://java.sun.com/jsf/facelets"
   xmlns:f="http://java.sun.com/jsf/core"
   xmlns:h="http://java.sun.com/jsf/html"
   contentType="text/html">   
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>  
  </head>
  <body>
    #{helloWorld.message}
  </body>
</html>
</f:view>

Running your app locally

To take your new application for a test run it's best to try running it locally before you deploy it to production. Right-click on your project, then click Run As -> Web Application. You should see a few log messages as the servlet container starts up, and then the following message:

The server is running at http://localhost:8888/

Once you see this, it means your app is up and running. Open your web browser and go to http://localhost:8888/helloworld.jsf. If everything is in order you should see the following page:

If you see this page, then congratulations! It's time to deploy your app to the GAE production environment. If you don't see this page, then go through all the previous steps to make sure you haven't missed anything. After that, if you still can't get this page to display then post a comment describing where you're stuck and we'll try to help you out.

Deploying to Google App Engine

Now it's time to deploy your application. Right click on your project, and select Google -> Deploy To App Engine. You will be prompted for your Google accounts username and password, so enter them here. After entering them the deployment process will take a little while complete, but eventually you'll get a 'Deployment completed successfully' message.

To see if your deployment was successful, go to your web browser and open your application page - Google apps are deployed to <app-id>.appspot.com, where the app-id is your unique application ID. For example, if your application ID is joeblogshelloworld, then your application will be available at http://joeblogshelloworld.appspot.com. So open your application page as follows:

http://<app-id>.appspot.com/helloworld.jsf

If all has gone well, then you should see the same Hello, World message that you saw when running your application locally.

Summary

This concludes part 1 of this article, where we saw how to set up the GAE SDK, create a new GAE project, and configure JSF 2.0 and Weld. We also tested that our JSF page was working by evaluating an EL expression, and confirmed that our Weld bean could be found by using it as a backing bean for our page.

In the next part of this series, we'll spend some time looking at the application development process, and how to make use of the APIs that Google App Engine provides for security, database access and data caching, among other things.

47 comments:
 
03. Feb 2010, 16:15 CET | Link
Michael Schuetz

Absolutely great!!

I will try this out this evening and give you feedback, if you like.

Regards Michael

ReplyQuote
 
03. Feb 2010, 16:32 CET | Link

Thanks Michael, that would be much appreciated. Our GAE support is still in its infancy, with stuff like conversation context support etc still in the works. Being able to base your application model on CDI though is of course an advantage in any environment, and I think that CDI+GAE is a potent combination. I'm looking forward to us growing our support for this great platform.

 
03. Feb 2010, 16:48 CET | Link
Preben

Lovely, I have been looking for something like this! I'm happy you are keeping an eye on GAE, as I am sure that application server as a service is the future.

 
03. Feb 2010, 18:56 CET | Link
Paul Bakker | paulb(AT)infosupport.com

Great, I've been trying this myself last week with the latest release, which doesn't work as you also noted. I will give it another try with the latest sources.

Having JSF 2 and CDI running on a managed platform is a great alternative for lightweight Java alternatives such as PHP in my opinion. Much better frameworks but still easy to deploy. Looking forward to full support!

 
03. Feb 2010, 20:10 CET | Link
Andre Eugenio

Great post Shane, looking forward for part 2 !

Regards.

 
03. Feb 2010, 20:33 CET | Link

A quick update - there is no need to build Weld itself, just the Servlet extension, as the Servlet extension uses the latest version of Weld now.

 
04. Feb 2010, 05:56 CET | Link
Will this support (injecting into) servlets deployed in my project? Or does this only work on EL expressions and JSF components?
 
04. Feb 2010, 07:57 CET | Link
Michael Schuetz

Shane,

I walked through your tutorial step by step. Setting up project worked without any problems.

Then I needed to build weld-servlet for my one (building weld-core was not necessary - thanks Pete) There I got:

[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireMavenVersion failed with message:
Detected Maven Version: 2.2.1 is not in the allowed range [2.0.10,2.0.10].

So I needed to change maven version.

OK, everything fine. I can start and see app on local system as expected.

But I got the following error when trying to deploy to cloud:

com.google.appengine.tools.admin.AdminException: Unable to update app: Error posting to URL: http://appengine.google.com/api/appversion/deploy?app_id=weld-gae&version=1&
400 Bad Request

Client Error (400)
The request is invalid for an unspecified reason.

at com.google.appengine.tools.admin.AppAdminImpl.update(AppAdminImpl.java:62)
at com.google.appengine.eclipse.core.proxy.AppEngineBridgeImpl.deploy(AppEngineBridgeImpl.java:271)
at com.google.appengine.eclipse.core.deploy.DeployProjectJob.runInWorkspace(DeployProjectJob.java:148)
at org.eclipse.core.internal.resources.InternalWorkspaceJob.run(InternalWorkspaceJob.java:38)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
Caused by: java.io.IOException: Error posting to URL: http://appengine.google.com/api/appversion/deploy?app_id=weld-gae&version=1&
400 Bad Request

Client Error (400)
The request is invalid for an unspecified reason.

at com.google.appengine.tools.admin.ServerConnection.send(ServerConnection.java:143)
at com.google.appengine.tools.admin.ServerConnection.post(ServerConnection.java:81)
at com.google.appengine.tools.admin.AppVersionUpload.send(AppVersionUpload.java:522)
at com.google.appengine.tools.admin.AppVersionUpload.deploy(AppVersionUpload.java:481)
at com.google.appengine.tools.admin.AppVersionUpload.commit(AppVersionUpload.java:444)
at com.google.appengine.tools.admin.AppVersionUpload.doUpload(AppVersionUpload.java:127)
at com.google.appengine.tools.admin.AppAdminImpl.update(AppAdminImpl.java:56)
... 4 more

Regards Michael

 
04. Feb 2010, 08:24 CET | Link
Scott wrote on Feb 03, 2010 23:56:
Will this support (injecting into) servlets deployed in my project? Or does this only work on EL expressions and JSF components?

Unfortunately dependency injection doesn't work for servlets in GAE at this stage, only for your CDI beans. It may work at some point in the future, but don't hold me to that.

 
04. Feb 2010, 08:28 CET | Link
Michael Schuetz wrote on Feb 04, 2010 01:57:
Shane, I walked through your tutorial step by step. Setting up project worked without any problems. Then I needed to build weld-servlet for my one (building weld-core was not necessary - thanks Pete) There I got:
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireMavenVersion failed with message:
Detected Maven Version: 2.2.1 is not in the allowed range [2.0.10,2.0.10].
So I needed to change maven version.

Hmm I thought this was fixed, perhaps Pete can shed some light on this.

OK, everything fine. I can start and see app on local system as expected. But I got the following error when trying to deploy to cloud:
*error text snipped*
Regards Michael

I sometimes get deployment errors too - just remember that Google App Engine is still in the preview stage and not everything is going to work perfectly 100% of the time. My best advice here is to keep trying until it's successful ;)

 
04. Feb 2010, 14:37 CET | Link
Michael Schuetz
My best advice here is to keep trying until it's successful ;)

You're right - second try succeeded.

So, I'm ready for Part 2 of your tutorial (-: Especially the database access part interests me most.

Michael

 
04. Feb 2010, 18:54 CET | Link
Troy

Hi Shane,

I followed your tutorial but I am getting this exception when trying to deploy Any thoughts?

04/02/2010 11:42:46 AM com.google.apphosting.utils.jetty.JettyLogger warn
WARNING: Failed startup of context com.google.apphosting.utils.jetty.DevAppEngineWebAppContext@1d225a7{/,/home/bigfoot/projects/VeloRepublic/Velo-Google/war}
java.util.zip.ZipException: error in opening zip file
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:114)
        at java.util.jar.JarFile.<init>(JarFile.java:133)
        at java.util.jar.JarFile.<init>(JarFile.java:97)
        at org.mortbay.jetty.webapp.TagLibConfiguration.configureWebApp(TagLibConfiguration.java:171)
        at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1215)
        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:120)
        at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:217)
        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.<init>(DevAppServerMain.java:113)
        at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:89)
 
04. Feb 2010, 19:03 CET | Link
Shane Bryzak wrote on Feb 04, 2010 02:28:
Michael Schuetz wrote on Feb 04, 2010 01:57:
Shane, I walked through your tutorial step by step. Setting up project worked without any problems. Then I needed to build weld-servlet for my one (building weld-core was not necessary - thanks Pete) There I got:
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireMavenVersion failed with message:
Detected Maven Version: 2.2.1 is not in the allowed range [2.0.10,2.0.10].
So I needed to change maven version.
Hmm I thought this was fixed, perhaps Pete can shed some light on this.

It is now :-)

 
04. Feb 2010, 19:11 CET | Link
Troy

Sorted it.

It was the jar file for Josh's JSF GAE fix. I needed to use svn checkout to get it from google code repo (follow the link to josh's blog).

Great work on the tutorial, first time with GAE. I will be following the next one with interest!

Cheers, Troy

 
05. Feb 2010, 01:03 CET | Link

Note that it's faster to just download the JSF 2.0 API JAR from the java.net Maven 2 repository.

 
05. Feb 2010, 01:10 CET | Link

Shane, great job on this tutorial! We really appreciate the time you took to do this research AND document it.

The only thing that concerns me is the requirement to go fetch JARs from various places, especially the patched version of Mojarra. I'm going to touch base with the Mojarra guys to see if we can round these up into a single place.

One other small note. It's not necessary to specify the javax.faces.DEFAULT_SUFFIX context parameter as the .xhtml file extension is the default in JSF 2.0.

 
05. Feb 2010, 04:25 CET | Link

Thanks Dan, I've updated the article with the direct link for the JSF API jar, and also your other suggestions. I agree, it would be great if we could download the JSF libs all from one place, so if you could pull some strings it would be nice ;)

Also I was discussing the WebConfiguration.processJndiEntries() issue with Pete when it occurred that there might not be a Mojarra issue raised to address this. There certainly wasn't one mentioned on Josh's blog (just a link to a related GAE issue on Google Code which was closed). Basically what I think we need is a configuration option to disable the processJndiEntries() check, if we could have this then we wouldn't need to use a hacked jar.

 
05. Feb 2010, 08:02 CET | Link
Michael Schuetz

Hi,

So, everything works now (including maven plugin). I kicked out GWT.

For those who just want to start and play around - you can download the stuff here:

http://berlin-incubator.googlecode.com/svn/trunk/weldGae/

All you need is Eclipse with Google-Plugin..

When you change the apps name (appengine-web.xml) you can deploy it on the GAE cloud for your own.

Regards Michael

 
09. Feb 2010, 15:00 CET | Link
Michael Schuetz

Hi, there is a nice tutorial on how to access JPA with GAE: http://code.google.com/intl/de-DE/appengine/docs/java/datastore/usingjpa.html.

It's very easy and worked out of the box. An example implementation can be checked out here, directly: http://berlin-incubator.googlecode.com/svn/trunk/weldGae/

Don't get me wrong - I really look forward to Shane's second part of the tutorial - still a lot stuff to cover. But I was just curious.. (-:

Regards Michael

 
11. Feb 2010, 20:42 CET | Link

Very nice! I will be trying this over the weekend.

 
12. Feb 2010, 00:23 CET | Link

How do I get a CDI bean from Weld on a GAE Servlet?

Weld docs say:

Java EE components may obtain an instance of BeanManager from JNDI by looking up the name java:comp/BeanManager. Any operation of BeanManager may be called at any time during the execution of the application.

But GAE doesn't support JNDI. So, how can I get a BeanManager instance to get a bean?

 
12. Feb 2010, 00:26 CET | Link

Another confusion:

15.3. Calling a bean from a servlet It's easy to use a bean from a servlet in Java EE 6. Simply inject the bean using field or initializer method injection.

Weld docs

However, on containers which do not support servlet injection, like GAE (or Jetty?) the simply inject the bean isn't simple anymore.

 
15. Feb 2010, 21:24 CET | Link

This is related, but I suggest you comment on the issue to ensure it is tested in GAE too.

 
17. Feb 2010, 22:47 CET | Link

Regarding to GAE Jndi lack of support there is a nice Aspectj hack here. Regards

 
18. Feb 2010, 05:54 CET | Link
Jeremy Norris | jnorris(AT)pattern73.com
Hendy Irawan wrote on Feb 11, 2010 18:23:
How do I get a CDI bean from Weld on a GAE Servlet? Weld docs say: Java EE components may obtain an instance of BeanManager from JNDI by looking up the name java:comp/BeanManager. Any operation of BeanManager may be called at any time during the execution of the application. But GAE doesn't support JNDI. So, how can I get a BeanManager instance to get a bean?

Try this: servletContext.getAttribute(javax.enterprise.inject.spi.BeanManager)

(My Link)

 
22. Feb 2010, 21:35 CET | Link
dea

Unfortunately, it seems it is not possible to use method calls in el-expressions, even using el-impl-2.2 exception is thrown:

java.lang.NoSuchMethodError: javax.el.ELResolver.invoke(Ljavax/el/ELContext;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Class;[Ljava/lang/Object;)Ljava/lang/Object; at com.sun.el.parser.AstValue.getValue(AstValue.java:111) at com.sun.el.parser.AstValue.getValue(AstValue.java:163) at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:219) at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:71) ...

I'm still stick on JBoss-EL implementation (jboss-el-1.0_02CR5.jar):

    <param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
 
30. Mar 2010, 22:11 CET | Link

You can use MyFaces on Google App Engine without any patching stuff.

16. Apr 2010, 13:31 CET | Link
hi, great post. i was trying to put together a jsf 2, seam 2 project on gae. unfortunately - i managed to run jsf 2 only. as soon as i add the seam 2 jars, the deployment fails with the stack trace below:

[the seam jars are: jboss-seam, jboss-seam-debug, jboss-seam-ioc, joss-seam-mail, jboss-seam-remoting, jboss-seam-ui]

any help is greatly appreciated ...

thanks...

WARNING: Failed startup of context com.google.apphosting.utils.jetty.DevAppEngineWebAppContext@3aabc1{/,/Users/ndr/Documents/playground/ndr/out/artifacts/ndr_war_exploded}
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.<init>(DevAppServerMain.java:113)
        at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:89)
Caused by: java.lang.NoClassDefFoundError: com/sun/facelets/compiler/Compiler
        at java.lang.Class.getDeclaredConstructors0(Native Method)
        at java.lang.Class.privateGetDeclaredConstructors(Class.java:2328)
        at java.lang.Class.getConstructor0(Class.java:2640)
        at java.lang.Class.getDeclaredConstructor(Class.java:1953)
        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)
 
01. Sep 2010, 22:08 CET | Link

When I try to activate a intercepor, I get this error log on GAE remote server:

com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException: Error Rendering View[/contact_list.xhtml]
javax.el.ELException: /template/list.xhtml @11,72 value="#{managedBean.resultList}": Error reading 'resultList' on type contactlist.managedbean.ContactListMB_$$_javassist_7
	at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:107)
	at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190)
	at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:178)
	at javax.faces.component.UIData.getValue(UIData.java:554)
	at javax.faces.component.UIData.getDataModel(UIData.java:1248)
	at javax.faces.component.UIData.getRowCount(UIData.java:339)
	at org.primefaces.component.datatable.DataTableRenderer.getNumberOfRowsToRender(DataTableRenderer.java:690)
	at org.primefaces.component.datatable.DataTableRenderer.encodeTable(DataTableRenderer.java:562)
	at org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:492)
	at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:273)
	at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:878)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1620)
	at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
	at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:848)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1613)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
	at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1616)
	at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:380)
	at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:126)
	at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:273)
	at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:127)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
	at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:97)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
	at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
	at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
	at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
	at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:238)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.Server.handle(Server.java:326)
	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
	at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
	at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
	at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:135)
	at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:251)
	at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:6784)
	at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:6782)
	at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)
	at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:398)
	at com.google.net.rpc.impl.Server$2.run(Server.java:852)
	at com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)
	at com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:576)
	at com.google.net.rpc.impl.Server.startRpc(Server.java:807)
	at com.google.net.rpc.impl.Server.processRequest(Server.java:369)
	at com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:442)
	at com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:319)
	at com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:290)
	at com.google.net.async.Connection.handleReadEvent(Connection.java:474)
	at com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:831)
	at com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207)
	at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:103)
	at com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:251)
	at com.google.apphosting.runtime.JavaRuntime$RpcRunnable.run(JavaRuntime.java:418)
	at java.lang.Thread.run(Thread.java:636)
Caused by: java.lang.reflect.InvocationTargetException
	at com.google.appengine.runtime.Request.process-6099822ce4437c8b(Request.java)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:43)
	at javax.el.BeanELResolver.getValue(BeanELResolver.java:72)
	at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:53)
	at com.sun.faces.el.FacesCompositeELResolver.getValue(FacesCompositeELResolver.java:72)
	at com.sun.el.parser.AstValue.getValue(AstValue.java:96)
	at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:183)
	at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:71)
	at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:102)
	... 64 more
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.google.apphosting.runtime.security.shared.stub.sun.reflect.ReflectionFactory
	at org.jboss.interceptor.proxy.InterceptorProxyCreatorImpl.createProxyInstance(InterceptorProxyCreatorImpl.java:68)
	at org.jboss.weld.bean.ManagedBean.applyInterceptors(ManagedBean.java:585)
	at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget.produce(ManagedBean.java:249)
	at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:331)
	at br.gov.demoiselle.internal.context.ViewContext.get(ViewContext.java:34)
	at org.jboss.weld.bean.proxy.ClientProxyMethodHandler.getProxiedInstance(ClientProxyMethodHandler.java:143)
	at org.jboss.weld.bean.proxy.ClientProxyMethodHandler.invoke(ClientProxyMethodHandler.java:100)
	at org.jboss.weld.util.CleanableMethodHandler.invoke(CleanableMethodHandler.java:43)
	at contactlist.managedbean.ContactListMB_$$_javassist_7.getResultList(ContactListMB_$$_javassist_7.java)
	... 75 more

Without the interceptor, its works fine. How can I work with my interceptors on GAE? Thats possible?

21. Oct 2010, 17:28 CET | Link

There is away to use the original implementation of mojarra... JSF 2 jars

It Works fine for me...

Here is how to set it up, I wrote it on my page.. http://www.neverslair-blog.net/daniels-tips-and-tutorials/

http://xebee.xebia.in/2010/07/21/google-app-engine-maven-jsf2/

21. Oct 2010, 17:30 CET | Link

There is away to use the original implementation of mojarra... JSF 2 jars

It Works fine for me...

Here is how to set it up, I wrote it on my page.. http://www.neverslair-blog.net/daniels-tips-and-tutorials/

 
03. Nov 2010, 20:39 CET | Link

Has anyone had any luck getting this example running with Weld 1.1.0.Beta1? I got it to work perfectly with 1.0.1 but 1.1.0 is throwing this:

Failed startup of context com.google.apphosting.utils.jetty.RuntimeAppEngineWebAppContext@a166bd{/,/base/data/home/apps/mtuckersandbox/1.345962963786090736}
com.google.common.collect.ComputationException: org.jboss.weld.resources.spi.ResourceLoadingException: Error loading class org.jboss.weld.conversation.AbstractConversationManager
	at com.google.common.collect.ComputingConcurrentHashMap.compute(ComputingConcurrentHashMap.java:218)
	at com.google.common.collect.ComputingConcurrentHashMap.apply(ComputingConcurrentHashMap.java:100)
	at com.google.common.collect.MapMaker$ComputingMapAdapter.get(MapMaker.java:515)
	at org.jboss.weld.resources.ClassTransformer.loadClass(ClassTransformer.java:182)
	at org.jboss.weld.bootstrap.BeanDeployer.addClass(BeanDeployer.java:94)
	at org.jboss.weld.bootstrap.BeanDeployer.addClasses(BeanDeployer.java:131)
	at org.jboss.weld.bootstrap.BeanDeployment.deployBeans(BeanDeployment.java:171)
	at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:412)
	at org.jboss.weld.environment.servlet.Listener.contextInitialized(Listener.java:207)
	at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
	at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
	at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
	at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
	at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
	at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:191)
	at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:168)
	at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:123)
	at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:261)
	at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:8486)
	at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:8484)
	at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)
	at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:418)
	at com.google.net.rpc.impl.Server$RpcTask.runInContext(Server.java:572)
	at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:448)
	at com.google.tracing.TraceContext.runInContext(TraceContext.java:688)
	at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:326)
	at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:318)
	at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:446)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
	at java.lang.Thread.run(Thread.java:636)
Caused by: org.jboss.weld.resources.spi.ResourceLoadingException: Error loading class org.jboss.weld.conversation.AbstractConversationManager
	at org.jboss.weld.resources.ClassTransformer.loadClass(ClassTransformer.java:188)
	at org.jboss.weld.introspector.jlr.WeldClassImpl.<init>(WeldClassImpl.java:160)
	at org.jboss.weld.introspector.jlr.WeldClassImpl.of(WeldClassImpl.java:142)
	at org.jboss.weld.resources.ClassTransformer$TransformTypeToWeldClass.apply(ClassTransformer.java:52)
	at org.jboss.weld.resources.ClassTransformer$TransformTypeToWeldClass.apply(ClassTransformer.java:40)
	at com.google.common.collect.ComputingConcurrentHashMap.compute(ComputingConcurrentHashMap.java:206)
	... 31 more
Caused by: java.lang.NoClassDefFoundError: sun.reflect.ReflectionFactory is a restricted class. Please see the Google App Engine developer's guide for more details.
	at com.google.appengine.runtime.Request.process-94a73c31ffc9ed13(Request.java)
	at sun.reflect.ReflectionFactory.<clinit>(ReflectionFactory.java)
	at java.lang.reflect.Method.invoke(Method.java:43)
	at org.jboss.weld.util.reflection.instantiation.ReflectionFactoryInstantiator.<init>(ReflectionFactoryInstantiator.java:45)
	at org.jboss.weld.util.reflection.instantiation.InstantiatorFactory$1.<init>(InstantiatorFactory.java:42)
	at org.jboss.weld.util.reflection.instantiation.InstantiatorFactory.<clinit>(InstantiatorFactory.java:38)
	at org.jboss.weld.util.Proxies.getUnproxyableClassException(Proxies.java:213)
	at org.jboss.weld.util.Proxies.getUnproxyableTypeException(Proxies.java:159)
	at org.jboss.weld.util.Proxies.getUnproxyableTypesException(Proxies.java:191)
	at org.jboss.weld.util.Proxies.isTypesProxyable(Proxies.java:180)
	at org.jboss.weld.introspector.jlr.AbstractWeldAnnotated.<init>(AbstractWeldAnnotated.java:179)
	at org.jboss.weld.introspector.jlr.AbstractWeldMember.<init>(AbstractWeldMember.java:55)
	at org.jboss.weld.introspector.jlr.WeldFieldImpl.<init>(WeldFieldImpl.java:73)
	at org.jboss.weld.introspector.jlr.WeldFieldImpl.of(WeldFieldImpl.java:54)
	at org.jboss.weld.introspector.jlr.WeldClassImpl.<init>(WeldClassImpl.java:181)
	at org.jboss.weld.introspector.jlr.WeldClassImpl.of(WeldClassImpl.java:142)
	at org.jboss.weld.resources.ClassTransformer$TransformTypeToWeldClass.apply(ClassTransformer.java:52)
	at org.jboss.weld.resources.ClassTransformer$TransformTypeToWeldClass.apply(ClassTransformer.java:40)
	at com.google.common.collect.ComputingConcurrentHashMap.compute(ComputingConcurrentHashMap.java:206)
	at com.google.common.collect.ComputingConcurrentHashMap.apply(ComputingConcurrentHashMap.java:100)
	at com.google.common.collect.MapMaker$ComputingMapAdapter.get(MapMaker.java:515)
	at org.jboss.weld.resources.ClassTransformer.loadClass(ClassTransformer.java:182)
	at org.jboss.weld.introspector.jlr.WeldClassImpl.<init>(WeldClassImpl.java:160)
	at org.jboss.weld.introspector.jlr.WeldClassImpl.of(WeldClassImpl.java:142)
	at org.jboss.weld.resources.ClassTransformer$TransformTypeToWeldClass.apply(ClassTransformer.java:52)
	at org.jboss.weld.resources.ClassTransformer$TransformTypeToWeldClass.apply(ClassTransformer.java:40)
	at com.google.common.collect.ComputingConcurrentHashMap.compute(ComputingConcurrentHashMap.java:206)
	at com.google.common.collect.ComputingConcurrentHashMap.apply(ComputingConcurrentHashMap.java:100)
	at com.google.common.collect.MapMaker$ComputingMapAdapter.get(MapMaker.java:515)
	at org.jboss.weld.resources.ClassTransformer.loadClass(ClassTransformer.java:182)
	at org.jboss.weld.bootstrap.BeanDeployer.addClass(BeanDeployer.java:94)
	at org.jboss.weld.bootstrap.BeanDeployer.addClasses(BeanDeployer.java:131)
	at org.jboss.weld.bootstrap.BeanDeployment.deployBeans(BeanDeployment.java:171)
	at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:412)
	at org.jboss.weld.environment.servlet.Listener.contextInitialized(Listener.java:207)
	at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
	at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
	at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
	at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
	at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
	at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
	... 11 more
04. Nov 2010, 00:23 CET | Link

How to do it with maven? In my simple projectk I have to us myfaces and gae-maven-plugin. All my attempts to use you instructions fails.

 
05. Nov 2010, 23:39 CET | Link

I have followed the tutorial, but I can't get it to work. Although the application runs without any problems showing up on the logs, no tag is rendered on the page. If I use the expression directly, {helloWorld.message}, nothing is printed, still. Using @ManagedBean wields the same effect. Any clues on what could be the problem?

 
25. Nov 2010, 11:30 CET | Link
Ali Ok wrote on Mar 30, 2010 16:11:
You can use MyFaces on Google App Engine without any patching stuff.

If you use MyFaces (myfaces-api.jar and myfaces-impl.jar) instead of Mojarra (jsf-api.jar and jsf-impl.jar) you don't need to do any patching of jsf-impl.jar.

MyFaces ships with GAE support out of the box!

 
25. Nov 2010, 23:30 CET | Link

RichFaces 4 does not support MyFaces 2.0.2 because of bugs

 
12. Feb 2012, 16:51 CET | Link
tilm4nn
@Rodrigo I had the same problem, evering seemed to work, no error messages but Named or ManagedBean instance could not be resolved by el. Then I tried to start the same app with Tomcat 7 instead of AppEngine and got the following error: LinkageError: WebappClassLoader of org.jboss.weld.environment.servlet.Listener and StandardClassLoader of javax.servlet.jsp.JspApplicationContext have different Class objects for the type javax.el.ELResolver and this information helped me to fix the problem. Like proposed above I had added el-api and el-impl to my project but now I realised that the GAE SDK Library also includes a el-api.jar. So I removed the one I had added in WEB-INF\lib leaving only the impl there and now it works like a charm.
 
17. Dec 2013, 09:01 CET | Link

Right now, are rarely getting worried Replica Louis Vuitton handbags using manufacturer with Replica Handbags. When we talk about imitation, we have an element that is significantly more cost-effective but seems to be perfect in addition to would be a excellent surprise for Designer Replica Handbags special someone. At this moment, the issue, which might slip in your head, is how we will get cheap points that can continue to make a difference. The answer then is easy to understand. From leading online Rolex Replicas stores, just like Replica Rolex Totes Pro, we have exceptional companies providing their particular Replica Luxuries duplicate goods in low-priced prices. They don’t skimp on upon high quality Replica Shoes and do not let their clientele need the opinion connected with dressed in a reproduction, the expense is a great deal decreased.

 
23. Dec 2013, 09:04 CET | Link

I spray painted the canvas with replica chanel handbags sale chalkboard paint to give it a nice matte black finish then decrapified the junk drawer to discount fake chanel 2.55 bags find these gold corner brackets just waiting for their shining moment. I used a little glue in the corners to keep the art piece in place.

 
05. Mar 2014, 03:55 CET | Link

It goes like this: Your company puts out an ad for a position and someone answers it, but also installs malicious software on a small business computer and uses it to log into the company online bank account. They then set up fraudulent fund transfers, adding fake employees or payees, and finally move the money to offshore havens. government.

 
22. Mar 2014, 09:35 CET | Link
paraphrasing help | wapexp39(AT)gmail.com

In the 'Provision ID' box, enter the one of a kind requisition identifier that you enlisted for your requisition. For the Version, simply enter 1, then click OK to spare your settings. The qualities really get spared in /war/web-Inf/appengine-web.xml, so open this index up now and examine what it holds. Really, there's one all the more setting you have to add to this index, to have the ability to help client sessions in your application. Add the accompanying line to the document:paraphrasing help

 
24. Apr 2014, 05:40 CET | Link

The grip and firmness of your instances also are definitely the top, and also the hues the iPhone five situations come in undoubtedly are a range of these which would even go well with your wardrobe, so wait around no more to pick the appropriate a person for your possess demands. And when you want scenarios produced of leather; the iPhone 5 Cases funky and elegant vary is to choose from.

 
02. Jul 2014, 14:41 CET | Link
jackman30
Click HELP for text formatting instructalso the hues the iPhone five situations come in undoubtedly are a range of these which would even go well with your wardrobe, so wait around no more to pick the appropriate a person for your possess demands. And when you want scenarios produced of leatherions. Then edit this text and check the preview.<a href="http://www.bespokebabybedding.com">http://www.bespokebabybedding.com</a>
[My Link=>]
12. Sep 2014, 13:03 CET | Link
asadalikhatri

Magic Of Making Up: TW (T Dub) Jackson Reveals His Weirdly Effective Relationship Repair Mechanism That Stops Breakups, Divorces, And Lovers Rejections Even In The Most Hopeless Of Situations... Written for consumers by a consumer, this fan site includes a fun and informative Magic Of Making Up review, ebook FAQ, and PDF download guide that provides an insider's look at the program and answers frequently asked questions about TW Jackson's unique and highly popular relationship guide.einfache Anleitung folgen

 
04. Oct 2014, 13:25 CET | Link
jam

Matters relevant to actual estates are tough to handle either you are looking for a home or just want to offer your home, you need the advice of experts in handling your residence issues. Quick Sale House

17. Oct 2014, 12:41 CET | Link

In order to understand the power of Miami SEO services, all that you need to do is focus on the average scenario in which you decide to search for something using your favorite search engine. http://www.miami-seocompany.com

27. Oct 2014, 09:17 CET | Link

This package does not guarantee perfection in three days but with some extra time and consistent routine you can be sure that the habit to use a potty always will stick.potty train boy

Post Comment