Map a servlet to a cron url? - google-app-engine

How do I map a servlet to a cron url? This question results from the comment to the answer in the following post: Use Cron jobs with Appengine Endpoints API
In my project the cron job is called as shown in the log in Google App Engine and the url https://[url-commented-out].appspot.com/_ah/api/stocksApi/v1/stocks executes properly when tested in the web browser and returns the proper value.
But I am getting the error 405: HTTP method GET not supported by this URL, when I try to run it in GAE. I've read https://cloud.google.com/appengine/docs/java/config/cron My code in cron.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/_ah/api/stocksApi/v1/stocks</url>
<description>Backend Process Stocks</description>
<schedule>every 1 minutes from 11:10 to 11:30</schedule>
<timezone>America/New_York</timezone>
</cron>
</cronentries>
My web.xml is:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>
[package].StocksEndpoint</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/api/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>cron</web-resource-name>
<url-pattern>/_ah/api/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
I am using Android Studio and have added a backend module by following HelloEndpoints and I have a StocksEndpoint.java
file with a getStocks(); method that returns stocks.

First add a servlet mapping for your cron to web.xml:
<!-- stock servlet -->
<servlet>
<servlet-name>StockServlet</servlet-name>
<servlet-class>YOUR.PACKAGE.HERE.StockServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StockServlet</servlet-name>
<url-pattern>/cron/stocks</url-pattern>
</servlet-mapping>
make sure to update the servlet class for your servlet!
Then finally put the new cron url in your cron.xml:
<cron>
<url>/cron/stocks</url>
<description>Backend Process Stocks</description>
<schedule>every 1 minutes from 11:10 to 11:30</schedule>
<timezone>America/New_York</timezone>
</cron>

Unfortunately urls under /_ah/api are restricted and cannot be called from within your App.
There are a couple of ways to go around this but the most accepted option is usually to use a regular servlet to serve Cron requests rather connecting to the endpoint.

Related

Appengine clear expired session, but Admin permission is required to access https://[domain]/_ah/sessioncleanup?clear

The project work in Appengine, and I want to clear the expired session, follow this doc :
https://groups.google.com/forum/#!msg/google-appengine-java/Tw2a8cYz05o/UgsWaoQhWYcJ
Web.xml
<servlet>
<servlet-name>_ah_sessioncleanup</servlet-name>
<servlet-class>com.google.apphosting.utils.servlet.SessionCleanupServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>_ah_sessioncleanup</servlet-name>
<url-pattern>/_ah/sessioncleanup</url-pattern>
</servlet-mapping>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<security-constraint>
<web-resource-collection>
<web-resource-name>session-clean-up</web-resource-name>
<url-pattern>/_ah/sessioncleanup</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
cron.xml
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/_ah/sessioncleanup?clear</url>
<description>Clean up sessions</description>
<schedule>every 15 minutes</schedule>
</cron>
</cronentries>
But the log show that :
09:55:00.957 GET 403 94 B 2 ms AppEngine /_ah/sessioncleanup?clear
Response 403
Anybody can help me? thanks.

Solr : IOException occured when talking to Server

I have been struggling to find a solution to this problem which I have tried to explain here. Would really appreciate some ideas that I could try, to fix this.
We have Spring Web Services with Microsoft SQL Server as back end. We have been working on SQL to SOLR migration project, where we are required to index all the SQL data to SOLR and perform searches there instead, due to a lot of performance issues our application has been facing.
The basic approach that we took is as follows:
1) Created SOLR EAR as mentioned HERE
2) Deployed the SOLR EAR on IBM Websphere v7.0 in the DEV env
3) Deployed the Spring Web Services EAR on Websphere server in LOCAL
4) Following is how we are trying to access the core from web service. Here, I have shown example of one core whereas in the actual code, we are accessing multiple cores in the same way.
spring.xml
:/solr/collection1/"/>
SearchEngineRepositoryImpl.java
package com.example.solr.repository;
import javax.annotation.Resource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.Circle;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.FacetOptions;
import org.springframework.data.solr.core.query.SimpleFacetQuery;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.FacetEntry;
import org.springframework.data.solr.core.query.result.FacetPage;
import org.springframework.stereotype.Repository;
#Repository
public class SearchEngineRepositoryImpl implements SearchEngineRepository{
#Resource
private SolrTemplate solrTemplateCollection1;
public List<SearchDocument> search(SearchCriteria searchCriteria){
Criteria solrSearchCriteira = new Criteria("name").contains(searchCriteria.getName());
SimpleFacetQuery searchQuery = new SimpleFacetQuery(solrSearchCriteira);
FacetPage<SearchDocument> results = solrTemplateCollection1.queryForFacetPage(searchQuery,SearchDocument.class);
// rest of code
.
.
.
}
}
When I am trying to run the web service, I am getting the following exception:
UUID: 4b5f05b1-23ce-4b80-b6cb-bfef6d1e5abd Cause: org.springframework.data.solr.UncategorizedSolrException: IOException occured when talking to server at: http://<host>:<port>/solr/collection1; nested exception is org.apache.solr.client.solrj.SolrServerException: IOException occured when talking to server at: http://<host>:<port>/solr/collection1
at org.springframework.data.solr.core.SolrTemplate.execute(SolrTemplate.java:122)
at org.springframework.data.solr.core.SolrTemplate.query(SolrTemplate.java:332)
at org.springframework.data.solr.core.SolrTemplate.queryForFacetPage(SolrTemplate.java:286)
at com.example.solr.repository.SearchEngineRepositoryImpl.search(SearchEngineRepositoryImpl.java:105)
at com.example.solr.service.SearchServiceImpl.search(SearchServiceImpl.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at org.springframework.ws.server.endpoint.MethodEndpoint.invoke(MethodEndpoint.java:134)
at org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter.invokeInternal(DefaultMethodEndpointAdapter.java:240)
at org.springframework.ws.server.endpoint.adapter.AbstractMethodEndpointAdapter.invoke(AbstractMethodEndpointAdapter.java:53)
at org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:233)
at org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:173)
at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:88)
at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:59)
at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:292)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:838)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1230)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:779)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:478)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:136)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:97)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:195)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:960)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1064)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:87)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:909)
at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1662)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:200)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:459)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:526)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:312)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:283)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:175)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)
at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)
at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1862)
Caused by: org.apache.solr.client.solrj.SolrServerException: IOException occured when talking to server at: http://<host>:<port>/solr/collection1
at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:413)
at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:180)
at org.apache.solr.client.solrj.request.QueryRequest.process(QueryRequest.java:90)
at org.apache.solr.client.solrj.SolrServer.query(SolrServer.java:301)
at org.springframework.data.solr.core.SolrTemplate$11.doInSolr(SolrTemplate.java:339)
at org.springframework.data.solr.core.SolrTemplate$11.doInSolr(SolrTemplate.java:336)
at org.springframework.data.solr.core.SolrTemplate.execute(SolrTemplate.java:118)
... 53 more
Caused by: org.apache.http.conn.ConnectTimeoutException: Connect to host:port timed out
at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:129)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:640)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:352)
... 59 more
I am able to invoke SOLR console and other SOLR queries in the browser.
Also, when I deploy the Web Services and SOLR EARs on the same Websphere server (i.e. after changing the hostname to localhost in the spring.xml), I am getting a proper response.
There is no authentication setup in the web.xml of SOLR EAR.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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-app_2_5.xsd"
version="2.5"
metadata-complete="true"
>
<filter>
<filter-name>SolrRequestFilter</filter-name>
<filter-class>org.apache.solr.servlet.SolrDispatchFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SolrRequestFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>Zookeeper</servlet-name>
<servlet-class>org.apache.solr.servlet.ZookeeperInfoServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>LoadAdminUI</servlet-name>
<servlet-class>org.apache.solr.servlet.LoadAdminUiServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>RedirectOldAdminUI</servlet-name>
<servlet-class>org.apache.solr.servlet.RedirectServlet</servlet-class>
<init-param>
<param-name>destination</param-name>
<param-value>${context}/#/</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>RedirectOldZookeeper</servlet-name>
<servlet-class>org.apache.solr.servlet.RedirectServlet</servlet-class>
<init-param>
<param-name>destination</param-name>
<param-value>${context}/zookeeper</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>RedirectLogging</servlet-name>
<servlet-class>org.apache.solr.servlet.RedirectServlet</servlet-class>
<init-param>
<param-name>destination</param-name>
<param-value>${context}/#/~logging</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>SolrRestApi</servlet-name>
<servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
<init-param>
<param-name>org.restlet.application</param-name>
<param-value>org.apache.solr.rest.SolrRestApi</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>RedirectOldAdminUI</servlet-name>
<url-pattern>/admin/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>RedirectOldAdminUI</servlet-name>
<url-pattern>/admin</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>RedirectOldZookeeper</servlet-name>
<url-pattern>/zookeeper.jsp</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>RedirectLogging</servlet-name>
<url-pattern>/logging</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Zookeeper</servlet-name>
<url-pattern>/zookeeper</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>LoadAdminUI</servlet-name>
<url-pattern>/admin.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SolrRestApi</servlet-name>
<url-pattern>/schema/*</url-pattern>
</servlet-mapping>
<mime-mapping>
<extension>.xsl</extension>
<mime-type>application/xslt+xml</mime-type>
</mime-mapping>
<welcome-file-list>
<welcome-file>admin.html</welcome-file>
</welcome-file-list>
</web-app>
Providing other info on SOLR setup for reference:
SOLR Home location :: /Websphere/AppServer/profiles/AppServer01/solr
SOLR Core location :: /Websphere/AppServer/profiles/AppServer01/solr/collection1
solr.xml
<?xml version="1.0" encoding="UTF-8" ?>
<solr persistent="false">
<cores adminPath="/admin/cores" host="${host:}" hostPort="${jetty.port:8983}" hostContext="${hostContext:solr}" defaultCoreName="collection1">
<core name="collection1" instanceDir="collection1" />
<shardHandlerFactory name="shardHandlerFactory" class="HttpShardHandlerFactory">
<str name="urlScheme">${urlScheme:}</str>
</shardHandlerFactory>
</cores>
</solr>

Deploy vaadin app to Google App Engine - Error NOT_FOUND

I successfully deployed a Vaadin application, but when calling it I see ERROR : NOT_FOUND
I suppose that my default page is not found,because the default page is selected wrong.
Question:
How can I point (I suppose in my web.xml) to my default page?
My web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>GoogleAppVaadin701Project</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
Vaadin eclipse plugin does not create web.xml which works for vaadin application. In the book of vaadin you can find section about web.xml - https://vaadin.com/book/vaadin7/-/page/application.environment.html
following is basic servlet definition and mapping based on the book which works fine. Just change the UI parameter to point to your UI implementation
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>
com.vaadin.server.GAEVaadinServlet
</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>com.example.higoogle.HigoogleUI</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

GAE display index.html with JAX-RS

I'm pretty sure this questions is very easy.
I built a app with google app engine. I use JPA and JAX-RS with Jersey.
my web.xml looks like this:
<?xml version="1.0" encoding="utf-8" standalone="no"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value/>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
My index.html is in war/WEB-INF/index.html. What do i need to do to display it ?
index.html should go directly under war as in war/index.html.
keep your file in war folder itself,
Don't keep inside WEB-INF.
Once you have taken it out,
You just need to give localhost:8888/ it will display the welcome-file ie index.html
you can keep other Jsp's inside WEB-INF, it will just be invisible for direct URL access.

Google App Engine - JSF - Facelets - Why not *.xhtml as a url-pattern?

I'm migrating an existing app from Tomcat to GAE. When testing locally, the xhtml pages are loaded as static pages. All processing is bypassed including my filter. However, if I reference a page that doesn't exist, my security filter forwards the request to the login.xhtml and the JSF/facelet renders fine.
Any idea why the xhtml pages are getting processed?
Other integrations: eclipse Helios, gae 1.6.5, maven (eclipse/m2), moharra 2.0.9, richfaces 4.2.0, spring 3.1.1
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.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-app_3_0.xsd">
<!-- https://community.jboss.org/wiki/HowToUseRichFaces40WithGoogleAppEngine -->
<context-param>
<param-name>com.sun.faces.enableThreading</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Production</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<filter>
<filter-name>SecurityFilter</filter-name>
<filter-class>com.xyz.web.filter.SecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecurityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Resource Servlet</servlet-name>
<servlet-class>org.richfaces.webapp.ResourceServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Resource Servlet</servlet-name>
<url-pattern>/org.richfaces.resources/*</url-pattern>
</servlet-mapping>
</web-app>
Update:
It works if I add the following mapping and refer to the page with .jsf extension. Referring to the .xhtml directly, still loads the source. Is it typical configuration to refer to .jsf extension for a .xhtml? If so, how do you configure the app so the source isn't available when accessed via .xhtml?
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
If I correctly understand your needs, you should add
<static-files>
<exclude path="/**.xhtml" />
</static-files>
in appengine-web.xml
If you skip this, your web browser will get reply from "static file server", not from JSF.

Resources