English | Site Directory

Google App Engine for Java Questions

Can I use my favorite framework on App Engine?

The App Engine runtime environment imposes some constraints to ensure that your app can be scaled to multiple instances on App Engine's distributed infrastructure. Many frameworks will work seamlessly within the App Engine server runtime environment but some of them will not. Others may require some modification.

There are quite a few frameworks available, so we're using a community oriented approach with a collaborative page here: Will it Play in App Engine Please search this page to check on the status of your favorite framework, and write a comment if your framework is not listed or if you have updates or fixes.

Which JVM languages can I use in my App Engine app?

Many of the languages designed to run in the JVM (like JRuby, Jython, Scala, and Groovy just to name a few) can be used on App Engine. At this point not all of these languages have been fully tested, so we're using a community oriented approach with a collaborative page here: Will it Play in App Engine. Please add information as you try out the runtime language of your choice.

Why can't I read from this file?

It is possible to read from a file which is uploaded as part of your application provided that it is in the following locations:

  • war/WEB-INF
  • in a location matching the <resource-files> pattern in appengine-web.xml (which by default includes everything)

If the file location is not the issue, the problem may be that the method you are using to read from the file is not whitelisted. Your application can use any IO classes that are useful for reading from the file system, such as File, FileInputStream, FileReader, or RandomAccessFile. For a full list of whitelisted classes, please see the JRE Class White List.

If you need to get file access to your own resources (such as properties files), you could put these files inside of jars and use Class or ClassLoader to load them.

Why can't I write to this file?

Writing to local files is not supported in App Engine due to the distributed nature of your application. Instead, data which must be persisted should be stored in the distributed datastore. For more information see the documentation on the runtime sandbox.

Can I create new threads in my app?

No, an App Engine app may not spawn new threads. For more information see the documentation on the runtime sandbox.

I have an exising Python app, is it possible to access the existing Python data store?

Yes, you can upload Java code to your app (I recommend specifying a new version number) and your Java code will have access to the data in the datastore. The kind names and property names are consistent across languages.

Be careful to ensure that the data types used in your model entities in Python can be loaded into your Java code.

Can I run Java and Python code in the same app?

Yes, each version of the app must specify a runtime language and it is possible to have version x of your app running Java, while version y is running Python. It would also be possible to use Jython.

Why do I get a UserServiceFailureException when I try to log in to my app?

If you associated your application with a Google Apps domain, you must access the application on a subdomain of your Google Apps account. For example, if example.com is your Google Apps domain, you must create a subdomain (we'll use www for this example) and point it at your app running on App Engine. You would then sign in to your app at www.example.com. If you try to access app through the app-id.appspot.com URL, you will not be able to sign in using your Google Apps account. This restriction applies only to apps which are restricted to a Google Apps domain.

I'm seeing an Initialization failed exception for all of my request handlers.

One of your filters, servlets, or JSPs likely has an error which prevents all of the handlers in the app from being properly initialized.

One possible cause for an initialization problem could arise if you are precompiling JSPs. The appcfg command precompiles the JSPs for you as part of the update process, so you probably do not need to precompile.

If you need to precompile them yourself for some reason, the fix is to bundle any JSP libraries along with the application. This includes:

  • Jasper runtime and the compiler, assuming that's what you used to do the precompilation.
  • Any tag libraries (including JSTL) that you need.
  • An EL implementation, if you're using it.

These libraries are added to each application as part of our offline JSP compilation which is done by appcfg, so if you are doing your own JSP compilation, you need to do the same thing.

If you have precompiled JSPs using Jasper, you will need to include the following jars in WEB-INF/lib:

  • commons-logging-api-1.1.1.jar (or later)
  • commons-el.jar
  • jasper-runtime.jar

Note that EL and logging are actually required even if you're not using them.

Does App Engine support Java Enterprise Edition?

While we do not support the entirety of the Java EE specification, we support many of its individual components. For a specific list of which components are and are not supported, see our collaboratively edit page for tracking framework, language, and library compatibility: Will it Play in App Engine.

How do I handle multipart form data? or How do I handle file uploads to my app?

You can obtain the uploaded file data from a multipart form post using classes from the Apache Commons file upload package. Specifically you may want to use FileItemStream, FileItermIterator and ServletFileUpload as illustrated below.

import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import java.io.InputStream;
import java.io.IOException;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FileUpload extends HttpServlet {
  private static final Logger log =
      Logger.getLogger(FileUpload.class.getName());

  public void doPost(HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
    try {
      ServletFileUpload upload = new ServletFileUpload();
      res.setContentType("text/plain");

      FileItemIterator iterator = upload.getItemIterator(req);
      while (iterator.hasNext()) {
        FileItemStream item = iterator.next();
        InputStream stream = item.openStream();

        if (item.isFormField()) {
          log.warning("Got a form field: " + item.getFieldName());
        } else {
          log.warning("Got an uploaded file: " + item.getFieldName() +
                      ", name = " + item.getName());

          // You now have the filename (item.getName() and the
          // contents (which you can read from stream).  Here we just
          // print them back out to the servlet output stream, but you
          // will probably want to do something more interesting (for
          // example, wrap them in a Blob and commit them to the
          // datastore).
          int len;
          byte[] buffer = new byte[8192];
          while ((len = stream.read(buffer, 0, buffer.length)) != -1) {
            res.getOutputStream().write(buffer, 0, len);
          }
        }
      }
    } catch (Exception ex) {
      throw new ServletException(ex);
    }
  }
}

I'm already using port 8080, how do I change the dev appserver's port?

If you are seeing the following error message:

Could not open the requested socket: Address already in use

You may want to change the port on which the dev server will listen for incoming connections. You can set the port with the following argument:

--port=desired-port-number

If you are using an ant target with a dev_appserver element, you can specify the port argument by adding the port attribute as follows.

<dev_appserver war="war" port="desired-port-number"/>

Can I use the Google Data API library on App Engine?

Yes, the Google Data Java client library can be used in App Engine, but you need to set a configuration option to avoid a runtime permissions error. Add the following to your appengine-web.xml file:

<system-properties>
  <property name="com.google.gdata.DisableCookieHandler" value="true"/>
</system-properties>

If the following is not included, you may see the following exception:

java.security.AccessControlException: access denied (java.net.NetPermission getCookieHandler)

The Eclipse plugin is not working.

If you are running into unexpected issues with the Google Eclipse Plugin or even with Eclipse itself, a good place to start looking is the 'Error Log' view. From the Eclipse menu select 'Window -> Show View -> Other...' and then select 'General -> Error Log'. You can double-click on individual entries to get more information. Alternatively, you can find a text version of these issues in a file called your-eclipse-workspace-directory/.metadata/.log.

I'm getting "Invalid runtime specified." when I try to upload.

When you attempt to update your application using appcfg, the server will check your account to see if you have permission to upload an app using the Java runtime. If your account does not have permissions, you will see the following error message:

java.io.IOException: Error posting to URL: http://appengine.google.com/api/appversion/...
400 Bad Request
Invalid runtime specified.

Unable to upload app: Error posting to URL: http://appengine.google.com/api/appversion/...
400 Bad Request
Invalid runtime specified.

To request permission to upload an app which uses the Java runtime, sign up at the following URL: http://appengine.google.com/promo/java_runtime . For now, access will be limited to the first 10,000 to sign up.

The email argument in appcfg doesn't seem to work.

The email command line argument must be specified before the appcfg operation. For example, the following is correct:

appcfg.sh -e youremail@example.com update app_directory/war