Red Hat

CapeDwarf User Guide

CapeDwarf User Guide

This is an in-depth guide on how to configure and use pre-compiled versions of CapeDwarf. If, for any reason, you need to build CapeDwarf from scratch, please refer to the project’s README on GitHub.

1. Running CapeDwarf

For information on how to download and install CapeDwarf, please refer to the Getting Started Guide. Once installed, there are several ways to run CapeDwarf:

  • Running <path to app>

    CapeDwarf will deploy the application located at <path to app> under the ROOT servlet context, just like GAE development server.

  • Running without specifying the path to the application and then copying the application’s war file into %CAPEDWARF_HOME%/standalone/deployments/.

    To deploy the app to the root servlet context, the name of the war should be ROOT.war. Unlike GAE, you can also deploy your app under any servlet context you like. You can even deploy more than one app on the same server (each under its own context).

    You can deploy your apps in either compressed war files or in exploded war directories. When deploying your app in an exploded directory, the directory name must include a .war extension and you must add a myapp.war.dodeploy' file, where +myapp.war matches the name of the directory your app is located in.

  • Running -c standalone-capedwarf-modules.xml

    This is basically the same as running, but with one significant caveat. See [faq/bytecode] for details. It also includes simple App Engine modules support.

  • Running -c standalone-capedwarf.xml

    This runs CapeDwarf w/o App Engine modules support enabled.

CapeDwarf can be run on a single node or on many nodes in a cluster.

1.1. Running in standalone mode

Once unzipped into %CAPEDWARF_HOME%, you can run CapeDwarf by simply running %CAPEDWARF_HOME%/bin/ or capedwarf.bat. The last line of the console output should look something like this:

13:50:38,085 INFO  [] (Controller Boot Thread) JBAS015874: JBoss Capedwarf 2.0.0.Beta2 (WildFly 8.0.0.Final-SNAPSHOT)
started in 3885ms - Started 213 of 525 services (350 services are lazy, passive or on-demand)

Assuming you already have an existing GAE application, you can deploy it on CapeDwarf by simply copying the WAR file to %CAPEDWARF_HOME%/standalone/deployments/ROOT.war. By naming the war ROOT.war, CapeDwarf will deploy the app to the / context path.

1.2. Running in a cluster

Running CapeDwarf in a cluster is not much different to running it in standalone mode. As soon as you run or capedwarf.bat on two computers in the same network, CapeDwarf will join both of them in the same cluster, simple as that.

For more information regarding clustering, see the WildFly 8 High Availability Guide

1.3. Running two server instances on the same computer

When testing, you may want to run two or more instances on the same computer. There are two things that are needed for this to work:

  • each instance must use its own set of TCP/IP ports. This is achieved by using JVM option -Djboss.socket.binding.port-offset=100

  • each instance must use its own data and temp dir. This is also achieved through JVM options:${jboss_home}/standalone/dataB -Djboss.server.temp.dir=${jboss_home}/standalone/tmpB

2. Production vs. development

Unlike Google App Engine, where the development server is completely separated from the production environment (Aappspot), CapeDwarf is only available in one single form - you always install the same CapeDwarf version/package, regardless of where you are installing it to - a production or a development server. In order to distinguish between development and production modes, CapeDwarf looks at the system property. To run your apps on CapeDwarf in development mode, set the system property to Development, and to run your app in production mode, set the system property to Production.

In CapeDwarf, like in Google App Engine, the type of environment (development/production) has an effect on whether datastore indexes are auto-generated and whether the User service’s login url presents the user with a mock or the real login form.

3. Configuring custom CapeDwarf stuff (inbound mail, xmpp, …)

Unlike Google AppSpot which has Google’s while infrastructure at its disposal, CapeDwarf can run on your local server and therefore cannot simply send and receive emails or XMPP messages without a few custom configuration settings.

You configure CapeDwarf through capedwarf-web.xml (in addition to the usual appengine-web.xml).

3.1. Admin Email

The first thing you will need to set up is the admin email.

<?xml version="1.0" encoding="utf-8"?>

CapeDwarf will use this to determine whether the currently logged in user is the application admin or not.

3.2. Sending e-mail messages

In order to be able to send emails through the Mail Service API, you need to specify properties that will be used by JavaMail when obtaining the mail session.

If you have a GMail account that you would like to use to send emails from your app, you should add the following properties to capedwarf-web.xml:

<?xml version="1.0" encoding="utf-8"?>
        <property name="mail.transport.protocol">smtp</property>
        <property name="mail.smtp.auth">true</property>
        <property name="mail.smtp.starttls.enable">true</property>
        <property name=""></property>
        <property name="mail.smtp.port">587</property>
        <property name="mail.smtp.user"></property>
        <property name="mail.smtp.password">your.password</property>

3.3. Receiving e-mail messages

If your application needs to process inbound e-mail messages, you need to set up an IMAP/POP3 account where CapeDwarf will poll for messages and deliver them to your application in the standard GAE way. NOTE: Don’t forget to also enable the inbound mail service in appengine-web.xml.

To poll for messages on your application’s GMail account, add this to capedwarf-web.xml:

<?xml version="1.0" encoding="utf-8"?>

The properties should all be self-explanatory. One thing to note is that CapeDwarf will not delete the messages from IMAP/POP3 account, but will only mark them as read. Also, during startup, it will process all unread messages and deliver them to your application.

3.4. Sending and receiving XMPP messages

CapeDwarf currently includes limited support for sending XMPP messages. It does not support receiving XMPP messages yet. If you would like to be able to send XMPP messages from your application, you need to configure the following XMPP settings in capedwarf-web.xml:

<?xml version="1.0" encoding="utf-8"?>

4. Compatibility options

CapeDwarf aims to be fully compatible with Google App Engine, but in certain situations, you may wish to explicitly disable certain compatibility features in order to use additional benefits that the WildFly Application Server has to offer. Turning features on or off can come in handy when porting a non-GAE application to GAE or vice-versa.

You can turn compatibility options on or off in three ways:

  • through system properties

  • through capedwarf.conf in %CAPEDWARF_HOME%/bin

  • through placed on the class path

Here’s a list of all the available options and what they do:

  • disable.entity.groups

    Datastore transactions operate only on entities belonging to the same entity group. By disabling this compatibility option, CapeDwarf allows you to operate on different entity groups in the same transaction.

  • disable.query.inequality.filter.check

    GAE does not allow specifying more than one inequality condition in the filter of a datastore query. By default, CapeDwarf does not allow it also, but you can disable this check through this option.


    GAE stores Integer, Short and Byte entity properties as Long; it also stores Float as Double; it stores empty collections as null. This means entities that are read from the datastore may not have the same property types as the original entity before it was stored in the datastore. In order to be compatible with GAE, CapeDwarf also performs these conversions, but you can disable them with this option.

  • ignore.logging

    As the name itself suggests, enabling this options disables logging completely. Since log lines are stored in the datastore, disabling logging may increase performance when logging is not needed. We disable logging in all of our tests except logging tests.

  • async.logging

    By default, storing of log records is performed synchronously. This means when the log record will definitely already be written to the datastore by the time the log statement completes. By turning on async logging, the records will be written asynchronously.

  • enable.eager.datastore.stats=(sync|async)

    Datastore statistics are turned OFF by default. To turn the stats on, you must specify whether they should be written to the datastore synchronously or asynchronously.

  • enable.globalTimeLimit

    All front-end requests are limited to 60 seconds. You can disable this time limit through this option.

  • disable.blacklist

    GAE only allows you to use JRE classes that are white-listed (see By enabling this option, CapeDwarf will allows you to use any JRE class.

  • disable.metadata

    Disable processing and storing of Datastore metadata information (see If your application does not need to perform any metadata queries, disabling this may bring some performance improvements.

  • enabled.subsystems

    Specify all the WildFly subsystems that are not enabled by default, but you want them to be enabled..

  • disabled.subsystems

    Specify all the WildFly subsystems that are enabled by default, but you don’t want them to be.

  • force.async.datastore

    Forces async cache mode on infinispan caches used by the datastore implementation.


    In certain situations you may wish the log to be written to a file (probably mostly during development or debugging). Even if logging is disabled with ignore.logging, CapeDwarf will still log to a file.

  • enable.socket.options

    GAE does not allow you to set certain socket options. With this option enabled, CapeDwarf does not impose any restrictions on what options you are allowed to set.

  • ignore.capedwarf.sockets

    By default, CapeDwarf’s socket factory wraps all sockets in a CapeDwarfSocket. When this option is enabled, the socket factory returns the original socket instance - it does not wrap it.


    CapeDwarf uses its own URLStreamHandler. You can disable this through this option.

  • channel.default.duration.minutes

    Determines how many minutes before the channel expires.


    Sets the default Google Cloud Service bucket name. If not set, the default used by CapeDwarf is CAPEDWARF_GCS_BUCKET.


    The Channel API implementation uses WebSockets if the browser supports them and falls back to a XmlHttpRequest implementation if it doesn’t. You can disable the usage of WebSockets through this option. In that case, CapeDwarf will always use the XmlHttpRequest channel implementation.

  • taskqueue.roles

    By default, all requests to Push Task Queue servlets are made with the “admin” role. You can change the roles through this option.

  • force.standalone.tx.tracker

    Force in-memory transaction tracking, instead of global/clustered tracking. This should optimize things a bit, but it can only be used standalone.

  • enable.all

    Instead of separately enabling all of the above options, you can enable all of them simply with enable.all

5. Compatibility with the real Google App Engine

It is our aim to be fully compatible with Google App Engine. That is the reason why we started the Google App Engine TCK project together with Google.

6. Supported APIs and caveats

7. What to do if you encounter a bug

If you encounter any bugs, please check if you’re using the latest version of CapeDwarf. If you are, please check if there’s a similar bug filed in our Issue tracking System ( If there isn’t, please file a new issue and if possible, either add a WAR that replicates the problem or, even better, add a new Arquillian test case to either the CapeDwarf project or the AppEngine TCK. Adding a new test is really not as hard as you may think. All you need to do is: Adding GAE TCK test

8. Differences between Google App Engine and CapeDwarf

  • no multiple versions

  • different http session handling; enabled (GAE-like), disabled (Stub), none / default (WildFly’s default)

back to top