Google App Engine for Java 常见问题

我可以在 App Engine 上使用我最喜欢的框架吗?

App Engine 运行时环境强加了一些约束,以确保可在 App Engine 的分布式基础架构上将应用程序扩展为多个实例。许多框架可在 App Engine 服务器运行时环境内实现无缝工作,但有些不能。其他的可能需要进行某些修改。

因为存在大量的框架,因此我们使用面向社区的方法在此处提供了一个协作页面:是否可在 App Engine 中运行 (Will it Play in App Engine)。请搜索该页面以检查您最喜欢的框架的状态,如果未列出您的框架或您有更新或修正,请提交评论。

我可以在 App Engine 应用程序中使用哪些 JVM 语言?

许多设计为可在 JVM 中运行的语言(如 JRuby、Jython、Scala 以及 Groovy 等)都可在 App Engine 上使用。目前并不是所有这些语言都经过了完整的测试,因此我们使用面向社区的方法在此处提供了一个协作页面:是否可在 App Engine 中运行 (Will it Play in App Engine)。请在测试过您选择的运行时语言后添加相关信息。

为什么我不能从该文件读取?

如果作为应用程序的一部分上传的文件位于以下位置,则可从该文件读取:

  • war/WEB-INF
  • 与 appengine-web.xml 中的 <resource-files> 模式匹配的位置(默认情况下包括一切)

 

如果文件位置没有问题,则问题可能是您用于从文件读取的方法未列入白名单。您的应用程序可使用任何可用于从文件系统读取的 IO 类,例如 FileFileInputStreamFileReaderRandomAccessFile。有关白名单上列出的类的完整列表,请参阅 JRE 类白名单

如果您需要获得您自己的资源(如属性文件)的文件访问权限,可将这些文件放入 jar 中,并使用 ClassClassLoader 将其载入。

为什么我不能写入到该文件?

由于应用程序的分布式性质,在 App Engine 中不支持写入到本地文件。因此,应将必须保存的数据存储在分布式数据存储区中。有关详细信息,请参阅关于运行时沙盒的文档。

我可以在应用程序中创建新线程吗?

不可以,App Engine 应用程序无法生成新线程。有关详细信息,请参阅关于运行时沙盒的文档。

我有现有的 Python 应用程序,可以访问现有的 Python 数据存储区吗?

可以,可将 Java 代码上传到您的应用程序(建议指定一个新的版本号),然后您的 Java 代码即可访问数据存储区中的数据。类型名称和属性名称在不同的语言间是一致的。

请注意确保能够将 Python 模型实体中使用的数据类型载入 Java 代码中。

我可以在同一应用程序中运行 Java 和 Python 代码吗?

可以,应用程序的各个版本都必须指定运行时语言,因此可以实现版本 x 运行 Java,而版本 y 运行 Python。还可以使用 Jython。

为什么在试图登录应用程序时会出现 UserServiceFailureException?

如果您将应用程序与 Google 企业应用套件域相关联,则必须在 Google 企业应用套件帐户的子域上访问该应用程序。例如,如果 example.com 是您的 Google 企业应用套件域,则您必须创建一个子域(在此例中使用 www)并将其指向 App Engine 上运行的应用程序。然后您可以从 www.example.com 登录到您的应用程序。如果您尝试通过 app-id.appspot.com 网址访问应用程序,则将无法使用 Google 企业应用套件帐户登录。本限制仅对限制到 Google 企业应用套件域的应用程序适用。

我看到所有请求处理程序均出现初始化失败异常。

您的某个过滤条件、servlet 或 JSP 可能出现错误,阻止了应用程序中所有处理程序的正常初始化。

如果预编译 JSP,可能会引发初始化问题。作为更新过程的一部分,appcfg 命令可为您预编译 JSP,因此您不必进行预编译。

如果出于某种原因需要自己对它们进行预编译,则解决方法是把所有的 JSP 库与应用程序捆绑在一起。其中包括:

  • Jasper 运行时和编译器(假设您使用其进行预编译)。
  • 所有所需的标签库(包括 JSTL)。
  • EL 实现(如果您要使用它)。

 

在 appcfg 执行离线 JSP 编译的过程中,会将这些库添加到每个应用程序,因此,如果您要自己进行 JSP 编译,则需要做同样的事情。

如果您有使用 Jasper 的预编译 JSP,则必须在 WEB-INF/lib 中包含以下 jar:

  • commons-logging-api-1.1.1.jar(或更高版本)
  • commons-el.jar
  • jasper-runtime.jar

 

请注意,实际上即使您未使用 EL 和 logging,它们也是必需的。

App Engine 是否支持 Java 企业版?

虽然我们不支持全部 Java EE 规范,但支持其中很多单个组件。有关特定的支持组件和不支持组件列表,请参阅我们用于跟踪框架、语言和库兼容性的协作编辑页面:是否可在 App Engine 中运行 (Will it Play in App Engine)

如何处理多部分格式数据?或如何处理应用程序的文件上传?

您可以使用 Apache Commons 文件上传包中的类从多部分格式发布中获取上传的文件数据。特别是,您可以如下使用 FileItemStreamFileItermIteratorServletFileUpload

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); 
    } 
  } 
}

我一直使用端口 8080,如何更改开发应用程序服务器的端口?

如果您看到以下错误消息:

Could not open the requested socket: Address already in use

您可以更改开发服务器监听传入连接的端口。可通过以下参数设置端口:

--port=desired-port-number

如果您使用的是带有 dev_appserver 元素的 ant 目标,则可通过如下方式添加 port 属性指定端口参数。

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

我可以在 App Engine 上使用 Google 数据 API 库吗?

可以,Google 数据 Java 客户端库可在 App Engine 中使用,但必须设置配置选项,以免发生运行时权限错误。请将以下内容添加到 appengine-web.xml 文件:

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

如果未包括以上内容,则可能会出现以下异常:

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

Eclipse 插件不能正常运行。

如果您遇到 Google Eclipse 插件或 Eclipse 本身相关的意外问题,可从查看“错误日志”视图开始解决问题。在 Eclipse 菜单上选择“窗口”->“显示视图”->“其他...”,然后选择“常规”->“错误日志”。可双击各个条目以获取详细信息。此外,还可在名为 your-eclipse-workspace-directory/.metadata/.log 的文件中找到这些问题的文本版本。

我在试图上传时收到“指定的运行时无效”。

在试图使用 appcfg 更新应用程序时,服务器将检查您的帐户以查看您是否有权上传使用 Java 运行时的应用程序。如果您的帐户没有权限,将会显示下列错误消息:

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.

要请求获得上传使用 Java 运行时的应用程序的权限,请在以下网址注册:http://appengine.google.com/promo/java_runtime。目前,访问权限仅限于前 10000 个注册的帐户。

appcfg 中的电子邮件参数似乎无法工作。

必须在进行 appcfg 操作之前指定电子邮件命令行参数。例如,下列命令是正确的:

appcfg.sh -e youremail@example.com update app_directory/war
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值