"projectId must match the following pattern" 运行 在 Google Eclipse 云工具上进行对象化时出现异常

"projectId must match the following pattern" exception when running Objectify on Google Cloud tools for Eclipse

我正在尝试 运行 在 Google Cloud 上使用 objectify 创建一个非常简单的 hello world 应用程序,但是在尝试访问数据存储以保存实体时出现异常。

我正在使用最新的 Google Cloud Tools (1.6.1) for eclipse (Oxygen 4.7.3a) 和 Java 8。 按照官方 Google quick star 指南,我能够在我的本地服务器上从 eclipse 创建一个标准 java 项目和 运行 hello word 示例应用程序。由于该插件允许您将 Objectify 库添加到项目中,因此我决定尝试一下。这是我编写的用于定义实体并尝试将其保存到数据存储区的代码。

//HelloAppEngine.java
package app;

import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.googlecode.objectify.ObjectifyService;
import static com.googlecode.objectify.ObjectifyService.ofy;

@WebServlet(
    name = "HelloAppEngine",
    urlPatterns = {"/hello"}
)
public class HelloAppEngine extends HttpServlet {

  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws IOException {
      
      Car porsche = new Car("2FAST", 4);
      ofy().save().entity(porsche).now();    // async without the now()

      assert porsche.id != null;    // id was autogenerated

      Car fetched2 = ofy().load().type(Car.class).id(porsche.id).now();
      
    response.setContentType("text/plain");
    response.setCharacterEncoding("UTF-8");

    response.getWriter().print("Hello App Engine!\r\n");
    
    response.getWriter().print(porsche.id);
  }
  
  public void init()  {
      ObjectifyService.init();
      ObjectifyService.register(Car.class);
  }
}

//Car.java
package app;

import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index;

@Entity
public class Car {
    @Id Long id;
    @Index String license;
    int color;
    
    Car(String lic, int c) {
        license = lic;
        color = c;
    }
}

当 运行在本地主机上将项目作为 App Engine 标准时,我遇到了以下异常:

java.lang.IllegalArgumentException: projectId must match the following pattern: ([a-z\d\-]{1,100}~)?([a-z\d][a-z\d\-\.]{0,99}:)?([a-z\d][a-z\d\-]{0,99})
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
at com.google.cloud.datastore.Validator.validateDatabase(Validator.java:42)
at com.google.cloud.datastore.BaseKey$Builder.<init>(BaseKey.java:58)
at com.google.cloud.datastore.KeyFactory.<init>(KeyFactory.java:35)
at com.google.cloud.datastore.DatastoreHelper.newKeyFactory(DatastoreHelper.java:58)
at com.google.cloud.datastore.DatastoreImpl.newKeyFactory(DatastoreImpl.java:466)
at com.googlecode.objectify.impl.Keys.createRawIncomplete(Keys.java:179)
at com.googlecode.objectify.impl.KeyMetadata.getIncompleteKey(KeyMetadata.java:184)
at com.googlecode.objectify.impl.KeyMetadata.setKey(KeyMetadata.java:153)
at com.googlecode.objectify.impl.KeyPopulator.save(KeyPopulator.java:29)
at com.googlecode.objectify.impl.translate.ClassPopulator.save(ClassPopulator.java:156)
at com.googlecode.objectify.impl.translate.ClassTranslator.saveSafe(ClassTranslator.java:131)
at com.googlecode.objectify.impl.translate.NullSafeTranslator.save(NullSafeTranslator.java:31)
at com.googlecode.objectify.impl.EntityMetadata.save(EntityMetadata.java:113)
at com.googlecode.objectify.impl.WriteEngine.save(WriteEngine.java:69)
at com.googlecode.objectify.impl.SaverImpl.entities(SaverImpl.java:60)
at com.googlecode.objectify.impl.SaverImpl.entity(SaverImpl.java:35)
at app.HelloAppEngine.doGet(HelloAppEngine.java:26)

知道我在这里错过了什么吗? 据我所知,只要我 运行 在本地开发服务器上,我就不需要项目 ID。

首先,正如您发现的那样,您在使用本地模拟器时确实需要提供项目 ID。你不能简单地省略它。在 Eclipse 中转到 运行 > 运行 配置 > App Engine > App Engine 本地服务器 和 select 云平台 选项卡您的 运行 配置。在该选项卡中,select 一个项目。这将分配一个要在本地 运行 中使用的项目 ID。 select 哪个项目并不重要。您实际上不会连接到它。

如果您没有登录或没有 Cloud Project,您可以将 GOOGLE_CLOUD_PROJECT 环境变量设置为合法字符串,例如 [的环境选项卡中的 MyProjectId =39=]配置。

除此之外,Objectify 6.0 在使用 dev_appserver 中的捆绑数据存储模拟器时似乎存在问题。它确实适用于基于测试版 gcloud 的数据存储模拟器。要改用它,请启动终端并 运行

$ gcloud beta emulators datastore start

当模拟器启动时,您会看到如下消息:

[datastore] API endpoint: http://localhost:8081
[datastore] If you are using a library that supports the DATASTORE_EMULATOR_HOST environment variable, run:
[datastore] 
[datastore]   export DATASTORE_EMULATOR_HOST=localhost:8081
[datastore] 
[datastore] Dev App Server is now running.

您需要将 DATASTORE_EMULATOR_HOST 环境变量添加到环境选项卡中的 Eclipse 运行 配置中。在此示例中,您将名称设置为 DATASTORE_EMULATOR_HOST 并将值设置为 localhost:8081.