http://git-wip-us.apache.org/repos/asf/struts-site/blob/124e36c4/content/docs/getting-started.html
----------------------------------------------------------------------
diff --git a/content/docs/getting-started.html 
b/content/docs/getting-started.html
new file mode 100644
index 0000000..172a83d
--- /dev/null
+++ b/content/docs/getting-started.html
@@ -0,0 +1,189 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd";>
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License. 
+-->
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" 
href="https://struts.apache.org/css/default.css";>
+    <style type="text/css">
+        .dp-highlighter {
+            width:95% !important;
+        }
+    </style>
+    <style type="text/css">
+        .footer {
+            background-image:      
url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
+            background-repeat:     repeat-x;
+            background-position:   left top;
+            padding-top:           4px;
+            color:                 #666;
+        }
+    </style>
+    <script type="text/javascript" language="javascript">
+        var hide = null;
+        var show = null;
+        var children = null;
+
+        function init() {
+            /* Search form initialization */
+            var form = document.forms['search'];
+            if (form != null) {
+                form.elements['domains'].value = location.hostname;
+                form.elements['sitesearch'].value = location.hostname;
+            }
+
+            /* Children initialization */
+            hide = document.getElementById('hide');
+            show = document.getElementById('show');
+            children = document.all != null ?
+                    document.all['children'] :
+                    document.getElementById('children');
+            if (children != null) {
+                children.style.display = 'none';
+                show.style.display = 'inline';
+                hide.style.display = 'none';
+            }
+        }
+
+        function showChildren() {
+            children.style.display = 'block';
+            show.style.display = 'none';
+            hide.style.display = 'inline';
+        }
+
+        function hideChildren() {
+            children.style.display = 'none';
+            show.style.display = 'inline';
+            hide.style.display = 'none';
+        }
+    </script>
+    <title>Getting Started</title>
+</head>
+<body onload="init()">
+<table border="0" cellpadding="2" cellspacing="0" width="100%">
+    <tr class="topBar">
+        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
+            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a 
href="tutorials.html">Tutorials</a>&nbsp;&gt;&nbsp;<a 
href="getting-started.html">Getting Started</a>
+        </td>
+        <td align="right" valign="middle" nowrap>
+            <form name="search" action="https://www.google.com/search"; 
method="get">
+                <input type="hidden" name="ie" value="UTF-8" />
+                <input type="hidden" name="oe" value="UTF-8" />
+                <input type="hidden" name="domains" value="" />
+                <input type="hidden" name="sitesearch" value="" />
+                <input type="text" name="q" maxlength="255" value="" />
+                <input type="submit" name="btnG" value="Google Search" />
+            </form>
+        </td>
+    </tr>
+</table>
+
+<div id="PageContent">
+    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
+        <!-- We'll enable this once we figure out how to access (and save) the 
logo resource -->
+        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; 
margin: 4px 4px 4px 10px;" border="0"-->
+        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 
2 Documentation</div>
+        <div style="margin: 0px 10px 8px 10px"  class="pagetitle">Getting 
Started</div>
+
+        <div class="greynavbar" align="right" style="padding: 2px 10px; 
margin: 0px;">
+            <a 
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=14811855";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Edit Page"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=14811855";>Edit
 Page</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Browse Space"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW";>Browse 
Space</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=14811855";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Add Page"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=14811855";>Add
 Page</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=14811855";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Add News"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=14811855";>Add
 News</a>
+        </div>
+    </div>
+
+    <div class="pagecontent">
+        <div class="wiki-content">
+            <div id="ConfluenceContent"><div 
class="confluence-information-macro confluence-information-macro-warning"><span 
class="aui-icon aui-icon-small aui-iconfont-error 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>THIS PAGE IS DEPRECATED, PLEASE 
FOLLOW THE LINK TO THE NEW GETTING STARTED GUIDE!</p><p><a shape="rect" 
class="external-link" 
href="http://struts.apache.org/getting-started/";>http://struts.apache.org/getting-started/</a></p></div></div><div
 class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>The framework documentation is 
written for active web developers and assumes a working knowledge about how 
Java web applications are built. For more about the underlying nuts and bolts, 
see the <a shape="rect" class="external-link" href="http://struts.apache.org/p
 rimer.html">Key Technologies Primer</a>.</p></div></div><p>Follow along with 
these tutorials to get started using Struts 2. The example code for the 
tutorialsis available for checkout from the <br clear="none"> Struts 2 GitHub 
repository at <a shape="rect" class="external-link" 
href="https://github.com/apache/struts-examples"; 
rel="nofollow">https://github.com/apache/struts-examples</a>. The example 
projects use Maven<br clear="none"> to manage the artifact dependencies and to 
build the .war files.</p><div class="confluence-information-macro 
confluence-information-macro-tip"><span class="aui-icon aui-icon-small 
aui-iconfont-approve confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>The <a shape="rect" 
class="external-link" href="http://struts.apache.org/mail.html";>Struts 2 user 
mailing list</a> is an excellent place to get help. If you are having a problem 
getting the tutorial example applications to work search the Struts 2 mailing 
list. If y
 ou don't find an answer to your problem, post a question on the mailing 
list.</p></div></div><h3 id="GettingStarted-GettingStarted">Getting 
Started</h3><p><a shape="rect" 
href="how-to-create-a-struts-2-web-application.html">How To Create A Struts 2 
Web Application</a></p><p><a shape="rect" 
href="hello-world-using-struts-2.html">Hello World Using Struts 2</a></p><p><a 
shape="rect" href="using-struts-2-tags.html">Using Struts 2 Tags</a></p><p><a 
shape="rect" href="coding-struts-2-actions.html">Coding Struts 2 
Actions</a></p><p><a shape="rect" href="processing-forms.html">Processing 
Forms</a></p><p><a shape="rect" href="form-validation.html">Form 
Validation</a></p><p><a shape="rect" href="message-resource-files.html">Message 
Resource Files</a></p><p><a shape="rect" 
href="exception-handling.html">Exception Handling</a></p><p><a shape="rect" 
href="debugging-struts.html">Debugging Struts</a></p><p><a shape="rect" 
href="struts-2-form-tags.html">Struts 2 Form Tags</a></p><p><a shape="rect" 
 href="form-validation-using-xml.html">Form Validation Using XML</a></p><p><a 
shape="rect" href="struts-control-tags.html">Control Tags</a></p><p><a 
shape="rect" href="wildcard-method-selection.html">Wildcard Method 
Selection</a></p><p><a shape="rect" href="struts-2-themes.html">Struts 2 
Themes</a></p><p><a shape="rect" href="spring-and-struts-2.html">Spring and 
Struts 2</a></p><p><a shape="rect" href="struts-2-annotations.html">Struts 2 
Annotations</a></p><p><a shape="rect" 
href="introducing-interceptors.html">Introducing Interceptors</a></p><p><a 
shape="rect" href="unit-testing.html">Unit Testing</a></p><p><a shape="rect" 
href="http-session.html">HTTP Session</a></p><p><a shape="rect" 
href="preparable-interface.html">Preparable Interface</a></p><p><a shape="rect" 
href="exclude-parameters.html">Exclude Parameters</a></p><div 
class="confluence-information-macro 
confluence-information-macro-information"><span class="aui-icon aui-icon-small 
aui-iconfont-info confluence-information-macr
 o-icon"></span><div class="confluence-information-macro-body"><p>Looking for 
the old <a shape="rect" href="bootstrap.html">Bootstrap 
tutorials</a>?</p></div></div></div>
+        </div>
+
+                    <div class="tabletitle">
+                Children
+            <span class="smalltext" id="show" style="display: inline;">
+              <a href="javascript:showChildren()">Show Children</a></span>
+            <span class="smalltext" id="hide" style="display: none;">
+              <a href="javascript:hideChildren()">Hide Children</a></span>
+            </div>
+            <div class="greybox" id="children" style="display: none;">
+                                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                                    $page.link($child)
+                    <span class="smalltext">(Apache Struts 2 
Documentation)</span>
+                    <br>
+                            </div>
+        
+    </div>
+</div>
+<div class="footer">
+    Generated by CXF SiteExporter
+</div>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/struts-site/blob/124e36c4/content/docs/glassfish-2x.html
----------------------------------------------------------------------
diff --git a/content/docs/glassfish-2x.html b/content/docs/glassfish-2x.html
new file mode 100644
index 0000000..ef4f306
--- /dev/null
+++ b/content/docs/glassfish-2x.html
@@ -0,0 +1,155 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd";>
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License. 
+-->
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" 
href="https://struts.apache.org/css/default.css";>
+    <style type="text/css">
+        .dp-highlighter {
+            width:95% !important;
+        }
+    </style>
+    <style type="text/css">
+        .footer {
+            background-image:      
url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
+            background-repeat:     repeat-x;
+            background-position:   left top;
+            padding-top:           4px;
+            color:                 #666;
+        }
+    </style>
+    <link href='https://struts.apache.org/highlighter/style/shCoreStruts.css' 
rel='stylesheet' type='text/css' />
+    <link href='https://struts.apache.org/highlighter/style/shThemeStruts.css' 
rel='stylesheet' type='text/css' />
+    <script src='https://struts.apache.org/highlighter/js/shCore.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushPlain.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushXml.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushJava.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushJScript.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushGroovy.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushBash.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushCss.js' 
type='text/javascript'></script>
+    <script type="text/javascript">
+        SyntaxHighlighter.defaults['toolbar'] = false;
+        SyntaxHighlighter.all();
+    </script>
+    <script type="text/javascript" language="javascript">
+        var hide = null;
+        var show = null;
+        var children = null;
+
+        function init() {
+            /* Search form initialization */
+            var form = document.forms['search'];
+            if (form != null) {
+                form.elements['domains'].value = location.hostname;
+                form.elements['sitesearch'].value = location.hostname;
+            }
+
+            /* Children initialization */
+            hide = document.getElementById('hide');
+            show = document.getElementById('show');
+            children = document.all != null ?
+                    document.all['children'] :
+                    document.getElementById('children');
+            if (children != null) {
+                children.style.display = 'none';
+                show.style.display = 'inline';
+                hide.style.display = 'none';
+            }
+        }
+
+        function showChildren() {
+            children.style.display = 'block';
+            show.style.display = 'none';
+            hide.style.display = 'inline';
+        }
+
+        function hideChildren() {
+            children.style.display = 'none';
+            show.style.display = 'inline';
+            hide.style.display = 'none';
+        }
+    </script>
+    <title>Glassfish 2.x</title>
+</head>
+<body onload="init()">
+<table border="0" cellpadding="2" cellspacing="0" width="100%">
+    <tr class="topBar">
+        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
+            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a 
href="guides.html">Guides</a>&nbsp;&gt;&nbsp;<a 
href="core-developers-guide.html">Core Developers Guide</a>&nbsp;&gt;&nbsp;<a 
href="application-servers.html">Application Servers</a>&nbsp;&gt;&nbsp;<a 
href="glassfish-2x.html">Glassfish 2.x</a>
+        </td>
+        <td align="right" valign="middle" nowrap>
+            <form name="search" action="https://www.google.com/search"; 
method="get">
+                <input type="hidden" name="ie" value="UTF-8" />
+                <input type="hidden" name="oe" value="UTF-8" />
+                <input type="hidden" name="domains" value="" />
+                <input type="hidden" name="sitesearch" value="" />
+                <input type="text" name="q" maxlength="255" value="" />
+                <input type="submit" name="btnG" value="Google Search" />
+            </form>
+        </td>
+    </tr>
+</table>
+
+<div id="PageContent">
+    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
+        <!-- We'll enable this once we figure out how to access (and save) the 
logo resource -->
+        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; 
margin: 4px 4px 4px 10px;" border="0"-->
+        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 
2 Documentation</div>
+        <div style="margin: 0px 10px 8px 10px"  class="pagetitle">Glassfish 
2.x</div>
+
+        <div class="greynavbar" align="right" style="padding: 2px 10px; 
margin: 0px;">
+            <a 
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=40505336";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Edit Page"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=40505336";>Edit
 Page</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Browse Space"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW";>Browse 
Space</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=40505336";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Add Page"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=40505336";>Add
 Page</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=40505336";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Add News"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=40505336";>Add
 News</a>
+        </div>
+    </div>
+
+    <div class="pagecontent">
+        <div class="wiki-content">
+            <div id="ConfluenceContent"><h3 
id="Glassfish2.x-Conventionpluginsupport">Convention plugin support</h3><p>To 
have proper support of the&#160;<a shape="rect" 
href="convention-plugin.html">Convention Plugin</a>&#160;in Glassfish 2.x when 
packed as EAR archive add the following constant to 
<code>struts.xml</code></p><div class="code panel pdl" style="border-width: 
1px;"><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">&lt;constant 
name="struts.convention.exclude.parentClassLoader" value="false" /&gt;
+</pre>
+</div></div><p>Thanks to&#160;<a shape="rect" class="external-link" 
href="http://stackoverflow.com/a/22490925/1805267"; 
rel="nofollow">pavpal</a>!</p></div>
+        </div>
+
+        
+    </div>
+</div>
+<div class="footer">
+    Generated by CXF SiteExporter
+</div>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/struts-site/blob/124e36c4/content/docs/google-app-engine-gae.html
----------------------------------------------------------------------
diff --git a/content/docs/google-app-engine-gae.html 
b/content/docs/google-app-engine-gae.html
new file mode 100644
index 0000000..accd085
--- /dev/null
+++ b/content/docs/google-app-engine-gae.html
@@ -0,0 +1,355 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd";>
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License. 
+-->
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" 
href="https://struts.apache.org/css/default.css";>
+    <style type="text/css">
+        .dp-highlighter {
+            width:95% !important;
+        }
+    </style>
+    <style type="text/css">
+        .footer {
+            background-image:      
url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
+            background-repeat:     repeat-x;
+            background-position:   left top;
+            padding-top:           4px;
+            color:                 #666;
+        }
+    </style>
+    <link href='https://struts.apache.org/highlighter/style/shCoreStruts.css' 
rel='stylesheet' type='text/css' />
+    <link href='https://struts.apache.org/highlighter/style/shThemeStruts.css' 
rel='stylesheet' type='text/css' />
+    <script src='https://struts.apache.org/highlighter/js/shCore.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushPlain.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushXml.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushJava.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushJScript.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushGroovy.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushBash.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushCss.js' 
type='text/javascript'></script>
+    <script type="text/javascript">
+        SyntaxHighlighter.defaults['toolbar'] = false;
+        SyntaxHighlighter.all();
+    </script>
+    <script type="text/javascript" language="javascript">
+        var hide = null;
+        var show = null;
+        var children = null;
+
+        function init() {
+            /* Search form initialization */
+            var form = document.forms['search'];
+            if (form != null) {
+                form.elements['domains'].value = location.hostname;
+                form.elements['sitesearch'].value = location.hostname;
+            }
+
+            /* Children initialization */
+            hide = document.getElementById('hide');
+            show = document.getElementById('show');
+            children = document.all != null ?
+                    document.all['children'] :
+                    document.getElementById('children');
+            if (children != null) {
+                children.style.display = 'none';
+                show.style.display = 'inline';
+                hide.style.display = 'none';
+            }
+        }
+
+        function showChildren() {
+            children.style.display = 'block';
+            show.style.display = 'none';
+            hide.style.display = 'inline';
+        }
+
+        function hideChildren() {
+            children.style.display = 'none';
+            show.style.display = 'inline';
+            hide.style.display = 'none';
+        }
+    </script>
+    <title>Google App Engine (GAE)</title>
+</head>
+<body onload="init()">
+<table border="0" cellpadding="2" cellspacing="0" width="100%">
+    <tr class="topBar">
+        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
+            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a 
href="faqs.html">FAQs</a>&nbsp;&gt;&nbsp;<a 
href="google-app-engine-gae.html">Google App Engine (GAE)</a>
+        </td>
+        <td align="right" valign="middle" nowrap>
+            <form name="search" action="https://www.google.com/search"; 
method="get">
+                <input type="hidden" name="ie" value="UTF-8" />
+                <input type="hidden" name="oe" value="UTF-8" />
+                <input type="hidden" name="domains" value="" />
+                <input type="hidden" name="sitesearch" value="" />
+                <input type="text" name="q" maxlength="255" value="" />
+                <input type="submit" name="btnG" value="Google Search" />
+            </form>
+        </td>
+    </tr>
+</table>
+
+<div id="PageContent">
+    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
+        <!-- We'll enable this once we figure out how to access (and save) the 
logo resource -->
+        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; 
margin: 4px 4px 4px 10px;" border="0"-->
+        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 
2 Documentation</div>
+        <div style="margin: 0px 10px 8px 10px"  class="pagetitle">Google App 
Engine (GAE)</div>
+
+        <div class="greynavbar" align="right" style="padding: 2px 10px; 
margin: 0px;">
+            <a 
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=114612";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Edit Page"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=114612";>Edit
 Page</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Browse Space"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW";>Browse 
Space</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=114612";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Add Page"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=114612";>Add
 Page</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=114612";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Add News"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=114612";>Add
 News</a>
+        </div>
+    </div>
+
+    <div class="pagecontent">
+        <div class="wiki-content">
+            <div id="ConfluenceContent"><p>It is possible to run, at least, a 
simple Struts 2 application on GAE with a little work.  Namely, you need to 
tell OGNL to not do security manager permission checks, which will fail since 
GAE has a security manager and you don't have the ability to add the 
OGNL-specific permissions.  Therefore, somewhere in your initialization code, 
add this:</p>
+
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
+OgnlRuntime.setSecurityManager(null);
+</pre>
+</div></div>
+
+<p>The easiest place for this is in a Servlet context listener, executing when 
the context is initialized.</p>
+
+<p>For Struts 2.1.8, Jeromy Evans did some work to get things running on GAE. 
The following post on the mailing list reports both the issues and the 
workarounds.</p>
+
+<h3 id="GoogleAppEngine(GAE)-IssueswhendeployingonGAE">Issues when deploying 
on GAE</h3>
+
+<p>Jeromy Evans: I've put in some more effort to get Struts 2.1.8 snapshot 
running in live GAE environment.  I made progress moving to Sitemesh 2.4.2, 
disabling OgnlRuntime SecurityManager and moving to convention-2.1.8-SNAPSHOT 
(WW-3114)</p>
+
+<p>The next issue is that XWorks XMLConfigurationProvider throws a 
SecurityException on the following line (211):</p>
+
+<p>// Force loading of class to detect no class def found exceptions<br 
clear="none">
+cimpl.getDeclaredConstructors();</p>
+
+<p>SecurityException: Unable to get members for 
o.a.s.c.PackageBasedActionConfigBuilder</p>
+
+<p>cimpl is the Class of the ActionConfigBuilder bean specified in 
struts-plugin.xml and loaded by ClassLoaderTools.  I believe this is a 
technique to eagerly load the class.</p>
+
+<p>I'm not sure why that's access is not permitted in the sandbox. It's not 
documented anywhere I can see and It only occurs in the live environment.</p>
+
+<p>As a work-around (guess), I changed it to cimpl.getDeclaredClasses() 
instead which is permitted (I don't know if this has the same effect on the 
ClassLoader).  That got me past the issue above, but the same SecurityException 
occurs in XWork's ContainerImpl$ConstructorInjector.findConstructorIn():<br 
clear="none">
+SecurityException: Unable to get members for Class 
o.a.s.v.v.VelocityManager</p>
+
+<p>which seems to be a fundamental problem with XWork's constructor injection 
in GAE.</p>
+
+<p>As a side note,  Guice 2's constructor injection works okay in GAE. I 
imagine the Guice 2 codebase is now very different beast than XWork's IOC 
though.</p>
+
+<p>I guess I need to approach the GAE forum now.  Has anyone got any ideas 
about what to attempt next on the S2/Xwork side?  Stack traces for the two 
cases are below.</p>
+
+<div class="preformatted panel" style="border-width: 1px;"><div 
class="preformattedContent panelContent">
+<pre> 
+Failed startup of context 
com.google.apphosting.utils.jetty.RuntimeAppEngineWebAppContext@67fe80{/,/base/data/home/apps/{appname}/1.335834217966711427}
+Unable to load configuration. - bean - 
jar:file:/base/data/home/apps/{appname}/1.335834217966711427/WEB-INF/lib/struts2-convention-plugin-2.1.8-SNAPSHOT.jar!/struts-plugin.xml:32:155
+       at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:431)
+       at 
org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:69)
+       at 
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter.init(StrutsPrepareFilter.java:50)
+       at 
com.google.inject.servlet.FilterDefinition.init(FilterDefinition.java:81)
+       at 
com.google.inject.servlet.ManagedFilterPipeline.initPipeline(ManagedFilterPipeline.java:102)
+       at com.google.inject.servlet.GuiceFilter.init(GuiceFilter.java:168)
+       at org.mortbay.jetty.servlet.FilterHolder.doStart(FilterHolder.java:99)
+       at 
org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
+       at 
org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:589)
+       at org.mortbay.jetty.servlet.Context.startContext(Context.java:139)
+       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 
com.google.apphosting.runtime.jetty.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:190)
+       at 
com.google.apphosting.runtime.jetty.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:167)
+       at 
com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:127)
+       at 
com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:235)
+       at 
com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4823)
+       at 
com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4821)
+       at 
com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)
+       at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:359)
+       at com.google.net.rpc.impl.Server$2.run(Server.java:820)
+       at 
com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)
+       at 
com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:516)
+       at com.google.net.rpc.impl.Server.startRpc(Server.java:775)
+       at com.google.net.rpc.impl.Server.processRequest(Server.java:348)
+       at 
com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:436)
+       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:428)
+       at 
com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:762)
+       at 
com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207)
+       at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:101)
+       at 
com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:251)
+       at 
com.google.apphosting.runtime.JavaRuntime$RpcRunnable.run(JavaRuntime.java:374)
+       at java.lang.Thread.run(Unknown Source)
+Caused by: Unable to load configuration. - bean - 
jar:file:/base/data/home/apps/{appname}/1.335834217966711427/WEB-INF/lib/struts2-convention-plugin-2.1.8-SNAPSHOT.jar!/struts-plugin.xml:32:155
+       at 
com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:58)
+       at 
org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:374)
+       at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:418)
+       ... 36 more
+Caused by: Unable to load bean: 
type:org.apache.struts2.convention.ActionConfigBuilder 
class:org.apache.struts2.convention.PackageBasedActionConfigBuilder - bean - 
jar:file:/base/data/home/apps/{appname}/1.335834217966711427/WEB-INF/lib/struts2-convention-plugin-2.1.8-SNAPSHOT.jar!/struts-plugin.xml:32:155
+       at 
com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.register(XmlConfigurationProvider.java:222)
+       at 
org.apache.struts2.config.StrutsXmlConfigurationProvider.register(StrutsXmlConfigurationProvider.java:101)
+       at 
com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:165)
+       at 
com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:55)
+       ... 38 more
+Caused by: java.lang.SecurityException: Unable to get members for class 
org.apache.struts2.convention.PackageBasedActionConfigBuilder
+       at 
com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_$10.run(Class_.java:357)
+       at 
com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_$10.run(Class_.java:347)
+       at java.security.AccessController.doPrivileged(Native Method)
+       at 
com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_.getMembers(Class_.java:347)
+       at 
com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_.getDeclaredConstructors(Class_.java:192)
+       at 
com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.register(XmlConfigurationProvider.java:212)
+       ... 41 more
+</pre>
+</div></div> 
+
+<p>&#8212; case two &#8212;</p>
+<div class="preformatted panel" style="border-width: 1px;"><div 
class="preformattedContent panelContent">
+<pre> 
+{
+[{appname}/1.335835094531171610].&lt;stdout&gt;: 642  [Runtime Network Thread] 
ERROR org.apache.struts2.dispatcher.Dispatcher  - Dispatcher initialization 
failed
+java.lang.RuntimeException: java.lang.RuntimeException: 
java.lang.RuntimeException: java.lang.SecurityException: Unable to get members 
for class org.apache.struts2.views.velocity.VelocityManager
+       at 
com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.inject(ContainerImpl.java:295)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl$2.call(ContainerImpl.java:104)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl$2.call(ContainerImpl.java:102)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:574)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl.injectStatics(ContainerImpl.java:101)
+       at 
com.opensymphony.xwork2.inject.ContainerBuilder.create(ContainerBuilder.java:493)
+       at 
com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:184)
+       at 
com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:55)
+       at 
org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:374)
+       at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:418)
+       at 
org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:69)
+       at 
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter.init(StrutsPrepareFilter.java:50)
+       at 
com.google.inject.servlet.FilterDefinition.init(FilterDefinition.java:81)
+       at 
com.google.inject.servlet.ManagedFilterPipeline.initPipeline(ManagedFilterPipeline.java:102)
+       at com.google.inject.servlet.GuiceFilter.init(GuiceFilter.java:168)
+       at org.mortbay.jetty.servlet.FilterHolder.doStart(FilterHolder.java:99)
+       at 
org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
+       at 
org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:589)
+       at org.mortbay.jetty.servlet.Context.startContext(Context.java:139)
+       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 
com.google.apphosting.runtime.jetty.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:190)
+       at 
com.google.apphosting.runtime.jetty.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:167)
+       at 
com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:127)
+       at 
com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:235)
+       at 
com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4823)
+       at 
com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:4821)
+       at 
com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)
+       at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:359)
+       at com.google.net.rpc.impl.Server$2.run(Server.java:820)
+       at 
com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)
+       at 
com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:516)
+       at com.google.net.rpc.impl.Server.startRpc(Server.java:775)
+       at com.google.net.rpc.impl.Server.processRequest(Server.java:348)
+       at 
com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:436)
+       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:428)
+       at 
com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:762)
+       at 
com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207)
+       at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:101)
+       at 
com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:251)
+       at 
com.google.apphosting.runtime.JavaRuntime$RpcRunnable.run(JavaRuntime.java:374)
+       at java.lang.Thread.run(Unknown Source)
+Caused by: java.lang.RuntimeException: java.lang.RuntimeException: 
java.lang.SecurityException: Unable to get members for class 
org.apache.struts2.views.velocity.VelocityManager
+       at 
com.opensymphony.xwork2.inject.ContainerBuilder$4.create(ContainerBuilder.java:132)
+       at com.opensymphony.xwork2.inject.Scope$2$1.create(Scope.java:51)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl$ParameterInjector.inject(ContainerImpl.java:462)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl.getParameters(ContainerImpl.java:477)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl.access$000(ContainerImpl.java:34)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.inject(ContainerImpl.java:293)
+       ... 45 more
+Caused by: java.lang.RuntimeException: java.lang.SecurityException: Unable to 
get members for class org.apache.struts2.views.velocity.VelocityManager
+       at 
com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:495)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl$7.call(ContainerImpl.java:532)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:581)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:530)
+       at 
com.opensymphony.xwork2.config.impl.LocatableFactory.create(LocatableFactory.java:32)
+       at 
com.opensymphony.xwork2.inject.ContainerBuilder$4.create(ContainerBuilder.java:130)
+       ... 50 more
+Caused by: java.lang.SecurityException: Unable to get members for class 
org.apache.struts2.views.velocity.VelocityManager
+       at 
com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_$10.run(Class_.java:357)
+       at 
com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_$10.run(Class_.java:347)
+       at java.security.AccessController.doPrivileged(Native Method)
+       at 
com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_.getMembers(Class_.java:347)
+       at 
com.google.apphosting.runtime.security.shared.intercept.java.lang.Class_.getDeclaredConstructors(Class_.java:192)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl$ConstructorInjector.findConstructorIn(ContainerImpl.java:366)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl$ConstructorInjector.&lt;init&gt;(ContainerImpl.java:319)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl$5.create(ContainerImpl.java:305)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl$5.create(ContainerImpl.java:304)
+       at 
com.opensymphony.xwork2.inject.util.ReferenceCache$CallableCreate.call(ReferenceCache.java:150)
+       at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
+       at java.util.concurrent.FutureTask.run(Unknown Source)
+       at 
com.opensymphony.xwork2.inject.util.ReferenceCache.internalCreate(ReferenceCache.java:76)
+       at 
com.opensymphony.xwork2.inject.util.ReferenceCache.get(ReferenceCache.java:116)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl.getConstructor(ContainerImpl.java:594)
+       at 
com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:491)
+       ... 55 more
+</pre>
+</div></div> 
+
+<h3 id="GoogleAppEngine(GAE)-Workarounds">Workarounds</h3>
+
+<blockquote><p>As a work-around (guess), I changed it to 
cimpl.getDeclaredClasses() instead which is permitted (I don't know if this has 
the same effect on the ClassLoader).  That got me past the issue above, but the 
same SecurityException occurs in XWork's 
ContainerImpl$ConstructorInjector.findConstructorIn():</p></blockquote>
+<p>    SecurityException: Unable to get members for Class 
o.a.s.v.v.VelocityManager</p>
+
+
+<p>This exception occurs within Google App Engine because XWork eagerly loads 
the VelocityManager Class for the bean struts-default.xml.  VelocityManager 
uses the VelocityToolbox optional dependency (in velocity-tools) which is not 
deployed with the application by default.  I presume the GAE ClassLoader checks 
all imported classes against the whitelist and fails if the class is not 
found.<br clear="none">
+It's overcome by deploying the application velocity.</p>
+
+<p>I now have Struts 2.1.8-snapshot with Convention, Sitemesh and JSON, within 
a Guice2 servlet filter for IOC, running within GAE.</p>
+
+<p>The mandatory work-around are:</p>
+<ul class="alternate"><li>to still use a ServletContextListener to disable the 
OgnlRuntime security manager.  If not done, an IllegalAccessException occurs in 
OgnlUtil.setProperty(String) at run-time.  This exception is swallowed, but it 
typically results in an NPE in ServletRedirectResult.isPathUrl(String) because 
location cannot be set.</li><li>the velocity dependencies need to be deployed 
with the application even if not in use.  If not done, a security exception 
occurs while getting the members of VelocityManager because VelocityManager 
imports VelocityToolbox and VelocityEngine.</li></ul>
+
+
+<p>I don't think any S2 code changes are required at this time.</p></div>
+        </div>
+
+        
+    </div>
+</div>
+<div class="footer">
+    Generated by CXF SiteExporter
+</div>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/struts-site/blob/124e36c4/content/docs/groovyresult.html
----------------------------------------------------------------------
diff --git a/content/docs/groovyresult.html b/content/docs/groovyresult.html
new file mode 100644
index 0000000..d3259b6
--- /dev/null
+++ b/content/docs/groovyresult.html
@@ -0,0 +1,386 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd";>
+<!-- 
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License. 
+-->
+<html>
+<head>
+    <link type="text/css" rel="stylesheet" 
href="https://struts.apache.org/css/default.css";>
+    <style type="text/css">
+        .dp-highlighter {
+            width:95% !important;
+        }
+    </style>
+    <style type="text/css">
+        .footer {
+            background-image:      
url('https://cwiki.apache.org/confluence/images/border/border_bottom.gif');
+            background-repeat:     repeat-x;
+            background-position:   left top;
+            padding-top:           4px;
+            color:                 #666;
+        }
+    </style>
+    <link href='https://struts.apache.org/highlighter/style/shCoreStruts.css' 
rel='stylesheet' type='text/css' />
+    <link href='https://struts.apache.org/highlighter/style/shThemeStruts.css' 
rel='stylesheet' type='text/css' />
+    <script src='https://struts.apache.org/highlighter/js/shCore.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushPlain.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushXml.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushJava.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushJScript.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushGroovy.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushBash.js' 
type='text/javascript'></script>
+    <script src='https://struts.apache.org/highlighter/js/shBrushCss.js' 
type='text/javascript'></script>
+    <script type="text/javascript">
+        SyntaxHighlighter.defaults['toolbar'] = false;
+        SyntaxHighlighter.all();
+    </script>
+    <script type="text/javascript" language="javascript">
+        var hide = null;
+        var show = null;
+        var children = null;
+
+        function init() {
+            /* Search form initialization */
+            var form = document.forms['search'];
+            if (form != null) {
+                form.elements['domains'].value = location.hostname;
+                form.elements['sitesearch'].value = location.hostname;
+            }
+
+            /* Children initialization */
+            hide = document.getElementById('hide');
+            show = document.getElementById('show');
+            children = document.all != null ?
+                    document.all['children'] :
+                    document.getElementById('children');
+            if (children != null) {
+                children.style.display = 'none';
+                show.style.display = 'inline';
+                hide.style.display = 'none';
+            }
+        }
+
+        function showChildren() {
+            children.style.display = 'block';
+            show.style.display = 'none';
+            hide.style.display = 'inline';
+        }
+
+        function hideChildren() {
+            children.style.display = 'none';
+            show.style.display = 'inline';
+            hide.style.display = 'none';
+        }
+    </script>
+    <title>GroovyResult</title>
+</head>
+<body onload="init()">
+<table border="0" cellpadding="2" cellspacing="0" width="100%">
+    <tr class="topBar">
+        <td align="left" valign="middle" class="topBarDiv" align="left" nowrap>
+            &nbsp;<a href="home.html">Home</a>&nbsp;&gt;&nbsp;<a 
href="faqs.html">FAQs</a>&nbsp;&gt;&nbsp;<a 
href="cookbook.html">Cookbook</a>&nbsp;&gt;&nbsp;<a 
href="groovyresult.html">GroovyResult</a>
+        </td>
+        <td align="right" valign="middle" nowrap>
+            <form name="search" action="https://www.google.com/search"; 
method="get">
+                <input type="hidden" name="ie" value="UTF-8" />
+                <input type="hidden" name="oe" value="UTF-8" />
+                <input type="hidden" name="domains" value="" />
+                <input type="hidden" name="sitesearch" value="" />
+                <input type="text" name="q" maxlength="255" value="" />
+                <input type="submit" name="btnG" value="Google Search" />
+            </form>
+        </td>
+    </tr>
+</table>
+
+<div id="PageContent">
+    <div class="pageheader" style="padding: 6px 0px 0px 0px;">
+        <!-- We'll enable this once we figure out how to access (and save) the 
logo resource -->
+        <!--img src="/wiki/images/confluence_logo.gif" style="float: left; 
margin: 4px 4px 4px 10px;" border="0"-->
+        <div style="margin: 0px 10px 0px 10px" class="smalltext">Apache Struts 
2 Documentation</div>
+        <div style="margin: 0px 10px 8px 10px"  
class="pagetitle">GroovyResult</div>
+
+        <div class="greynavbar" align="right" style="padding: 2px 10px; 
margin: 0px;">
+            <a 
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13865";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/notep_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Edit Page"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/editpage.action?pageId=13865";>Edit
 Page</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/browse_space.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Browse Space"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/listpages.action?key=WW";>Browse 
Space</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13865";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/add_page_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Add Page"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/createpage.action?spaceKey=WW&fromPageId=13865";>Add
 Page</a>
+            &nbsp;
+            <a 
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13865";>
+                <img 
src="https://cwiki.apache.org/confluence/images/icons/add_blogentry_16.gif";
+                     height="16" width="16" border="0" align="absmiddle" 
title="Add News"></a>
+            <a 
href="https://cwiki.apache.org/confluence/pages/createblogpost.action?spaceKey=WW&fromPageId=13865";>Add
 News</a>
+        </div>
+    </div>
+
+    <div class="pagecontent">
+        <div class="wiki-content">
+            <div id="ConfluenceContent"><div 
class="confluence-information-macro 
confluence-information-macro-information"><p class="title">Groovy Plugin 
Available</p><span class="aui-icon aui-icon-small aui-iconfont-info 
confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body">
+<p>There is now a Struts 2 Groovy plugin that largely superceded this page: <a 
shape="rect" class="external-link" 
href="http://cwiki.apache.org/S2PLUGINS/groovy-plugin.html";>http://cwiki.apache.org/S2PLUGINS/groovy-plugin.html</a></p></div></div>
+<h2 id="GroovyResult-GroovyResult-Groovyscriptsasaview">GroovyResult - Groovy 
scripts as a view</h2>
+
+<p>This is an attempt to create a Result type that uses Groovy (<a 
shape="rect" class="external-link" href="http://groovy.codehaus.org"; 
rel="nofollow">http://groovy.codehaus.org</a>) files as a view. It exposes the 
current ActionContext to a groovy script. This doesn't really have much 
practical use, but it's fun nonetheless and shows how easy it is to create a 
Result. There is another Result (JFreeChartResult) in the <a shape="rect" 
href="https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=117058";>Cookbook</a></p>
+
+<h2 id="GroovyResult-Installation">Installation</h2>
+
+<p>Not much - just make sure you have Groovy in your classpath, and the antlr, 
asm-* and groovy jars available to your webapp.</p>
+
+<h2 id="GroovyResult-Configuration">Configuration</h2>
+
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 1px;"><b>acdtion.xml</b></div><div 
class="codeContent panelContent pdl">
+<pre class="brush: xml; gutter: false; theme: Default" style="font-size:12px;">
+&lt;result-types&gt;
+   &lt;result-type name="groovy" 
class="myapp.action2.extensions.GroovyResult"/&gt;
+&lt;/result-types&gt;
+</pre>
+</div></div>
+<p>xwork.xml - action definitions</p>
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
+&lt;action name="MyAction" class="myapp.action2.actions.MyAction"&gt;
+  &lt;result name="success" type="groovy"&gt;
+    &lt;param name="file"&gt;test.groovy&lt;/param&gt;
+  &lt;/result&gt;
+&lt;/action&gt;
+</pre>
+</div></div>
+<p>The result type takes one parameter (for now), namely 'file', which 
contains the name of the groovy script in our script directory.</p>
+
+<h2 id="GroovyResult-Showmethecode!">Show me the code !</h2>
+
+<p>Here's the code of the actual GroovyResult. This is a verbose version, with 
a lot of error checking.</p>
+<ul class="alternate"><li>source code
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 
1px;"><b>GroovyResult.java</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
+public class GroovyResult implements Result {
+
+       public final static String GROOVY_DIR_NAME = "groovy";
+
+       private final static Logger logger = 
Logger.getLogger(GroovyResult.class);
+       //our groovy source file name
+       private String file;
+       //a groovy shell
+       private GroovyShell shell;
+       //our parsed script
+       private Script script;
+       //the outputstream that will replace the 'out' in our groovy stream
+       private OutputStream out;
+       //directory containing groovy scripts
+       private String scriptDirectory;
+       /*
+        * (non-Javadoc)
+        *
+        * @see 
com.opensymphony.xwork.Result#execute(com.opensymphony.xwork.ActionInvocation)
+        */
+       public void execute(ActionInvocation inv) {
+
+               //check the scriptDirectory - if it doesn't exists, use the 
default one
+               //WEBAPP + Groovy files directory
+               if (scriptDirectory == null) {
+                       //not pretty, but this allows us to get the app root 
directory
+                       String base = 
ServletActionContext.getServletContext().getRealPath(
+                                       "/");
+                       //if for some reason (.war, apache connector, ..) we 
can't get the
+                       // base path
+                       if (base == null) {
+                               logger
+                                               .warn("Could not translate the 
virtual path \"/\" to set the default groovy script directory");
+                               return;
+                       }
+                       scriptDirectory = base + GROOVY_DIR_NAME;
+                       //issue a warning that this directory should NOT be 
world readable
+                       // !!
+                       logger
+                                       .warn("Please make sure your script 
directory is NOT world readable !");
+               }
+
+               // first of all, make sure our groovy file exists, is readable, 
and is
+               // an actual file
+
+               File groovyFile = new File(scriptDirectory, file);
+               if (!groovyFile.exists()) {
+                       //log an error and return
+                       logger.warn("Could not find destination groovy file: "
+                                       + groovyFile.getAbsolutePath());
+                       return;
+               }
+               if (!groovyFile.isFile()) {
+                       //log an error and return
+                       logger.warn("Destination is not a file: "
+                                       + groovyFile.getAbsolutePath());
+                       return;
+               }
+               if (!groovyFile.canRead()) {
+                       //log an error and return
+                       logger.warn("Can not read file: " + 
groovyFile.getAbsolutePath());
+                       return;
+               }
+
+               if (logger.isDebugEnabled())
+                       logger.debug("File " + groovyFile.getPath()
+                                       + " found, going to parse it ..");
+
+               /*
+                * Here we create a Binding object which we populate with the 
webwork
+                * stack
+                */
+               Binding binding = new Binding();
+
+               binding.setVariable("context", ActionContext.getContext());
+
+               /*
+                * We replace the standard OutputStream with our own, in this 
case the
+                * OutputStream from our httpResponse
+                */
+               try {
+                       //the out will be stored in an OutputStream
+                       out = 
ServletActionContext.getResponse().getOutputStream();
+               } catch (IOException e1) {
+                       logger.error("Could not open outputstream", e1);
+               }
+               if (out != null){
+                       binding.setVariable("out", out);
+               }
+               else {
+                       logger
+                                       .warn("OutputStream not available, 
using default System.out instead");
+                       binding.setVariable("out", System.out);
+               }
+
+               //create a new shell to parse and run our groovy file
+               shell = new GroovyShell(binding);
+               try {
+                       //try to parse the script - the returned script could 
be cached for
+                       //performance improvent
+                       script = shell.parse(groovyFile);
+               } catch (CompilationFailedException e) {
+                       logger.error("Could not parse groovy script", e);
+                       return;
+               } catch (IOException e) {
+                       logger.error("Error reading groovy script", e);
+                       return;
+               }
+               //the binding is set, now run the script
+               Object result = script.run();
+
+               if (logger.isDebugEnabled()) {
+                       logger.debug("Script " + groovyFile.getName()
+                                       + " executed, and returned: " + result);
+               }
+               try {
+                       out.flush();
+               } catch (IOException e2) {
+                       logger.error("Could not flush the outputstream", e2);
+               }
+       }
+
+       /**
+        * @return Returns the script.
+        */
+       public Script getScript() {
+               return script;
+       }
+       /**
+        * @param file
+        *            The file to set.
+        */
+       public void setFile(String file) {
+               this.file = file;
+       }
+       /**
+        * @param out
+        *            The out to set.
+        */
+       public void setOut(OutputStream out) {
+               this.out = out;
+       }
+</pre>
+</div></div></li></ul>
+
+
+<h2 id="GroovyResult-Explanation">Explanation</h2>
+
+<p>The first part of the result is little more than:</p>
+<ul class="alternate"><li>determining the script directory - defaults to 
<code>MYWEBAPP/groovy/</code></li><li>checking the file - make sure it exists, 
is readable, ..
+<div class="confluence-information-macro 
confluence-information-macro-note"><span class="aui-icon aui-icon-small 
aui-iconfont-warning confluence-information-macro-icon"></span><div 
class="confluence-information-macro-body"><p>Make sure the groovy scripts 
directory is not world readable !</p></div></div></li></ul>
+
+
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeHeader 
panelHeader pdl" style="border-bottom-width: 1px;"><b>The groovy 
part</b></div><div class="codeContent panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
+Binding binding = new Binding();
+binding.setVariable("context", ActionContext.getContext());
+</pre>
+</div></div>
+<p>A Binding object allows us to 'bind' objects to a groovy script, so they 
can be used as variables. In this case, I took the ActionContext and exposed it 
as 'context'.</p>
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
+out = ServletActionContext.getResponse().getOutputStream();
+...
+binding.setVariable("out", out);
+</pre>
+</div></div>
+<p>We also bind an OutputStream to the groovy script (as 'out') - it simply 
serves as a replacement for the standard System.out, so any printing goes 
directly to the http response outputstream.</p>
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
+shell = new GroovyShell(binding);
+</pre>
+</div></div>
+<p>Next step; we create a GroovyShell, and pass our populated Binding to the 
constructor. Any script ran by this shell will have access to the passed 
variables (ActionContext and OutputStream).</p>
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
+script = shell.parse(groovyFile);
+</pre>
+</div></div>
+<p>Before you can run a groovyFile, you need to parse it. Any syntax errors 
will be reported here - I also suggest adding a better error reporting in this 
case if you actually want to use this Result.<br clear="none">
+Upon successful parsing, a Script is returned (which could be cached if you 
want to increase performance) which will be run by our Shell.</p>
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
+Object result = script.run();
+</pre>
+</div></div>
+<p>As a test, you might want to create a little 'groovy' script to test our 
Result.<br clear="none">
+test.groovy - a simple groovy script</p>
+<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent 
panelContent pdl">
+<pre class="brush: java; gutter: false; theme: Default" 
style="font-size:12px;">
+for (item in context.contextMap){
+       println "item: ${item}"
+}
+</pre>
+</div></div>
+<p>Place the test.groovy file in your groovy scripts directory. You should now 
see the result when you invoke MyAction.action in your browser.</p>
+
+<p>Possible improvements are binding all objects on the stack so they become 
available to the groovy script, refactoring to an InputStream instead of a 
File, etc .. Comments welcome !</p></div>
+        </div>
+
+        
+    </div>
+</div>
+<div class="footer">
+    Generated by CXF SiteExporter
+</div>
+</body>
+</html>

Reply via email to