我正在使用ServletContextListener来做后台线程。我设计了这个线程,称为每小时。我测试了本地文件,一切正常。
但是当更改为使用Google App Engine在Google云存储中读取/写入文件时,我收到了NullPointerException:
java.lang.NullPointerException:在既不是原始请求线程也不是ThreadManager创建的线程的线程中不允许进行操作 [INFO] com.google.appengine.api.NamespaceManager.set(NamespaceManager.java:90) [INFO] com.google.appengine.tools.cloudstorage.dev.LocalRawGcsService.makeKey(LocalRawGcsService.java:311) [INFO] com.google.appengine.tools.cloudstorage.dev.LocalRawGcsService.makeKey(LocalRawGcsService.java:305) [INFO] com.google.appengine.tools.cloudstorage.dev.LocalRawGcsService.getObjectMetadata(LocalRawGcsService.java:397) [INFO] com.google.appengine.tools.cloudstorage.dev.LocalRawGcsService.readObjectAsync(LocalRawGcsService.java:459) [INFO] com.google.appengine.tools.cloudstorage.PrefetchingGcsInputChannelImpl.requestBlock(PrefetchingGcsInputChannelImpl.java:107) [INFO] com.google.appengine.tools.cloudstorage.PrefetchingGcsInputChannelImpl。(PrefetchingGcsInputChannelImpl.java:88) [INFO] com.google.appengine.tools.cloudstorage.GcsServiceImpl.openPrefetchingReadChannel(GcsServiceImpl.java:126) [INFO] com.lottery.base.Utils.getGCPInputStream(Utils.java:458)
函数getGCPInputStream(String file)如下:
public static InputStream getGCPInputStream(String file) {
GcsFilename fileName = new GcsFilename(Constant.BUCKET_NAME, file);
GcsInputChannel readChannel = gcsService.openPrefetchingReadChannel(fileName, 0, BUFFER_SIZE);
return Channels.newInputStream(readChannel);
}
我还对示例代码进行了测试,并且可以正常工作。
谁能告诉我我的问题是什么?我花了很多时间研究,但是没有运气。
答案 0 :(得分:0)
这是由于App Engine标准Java环境中的当前限制。当前,如果您要调用App Engine API(com.google.appengine.api。*,根据您提供的堆栈跟踪,在这种情况下就是这种情况),则必须从请求线程或通过使用创建的线程中调用这些API ThreadManager API。已记录在here中。
要从后台线程将文件读/写到Cloud Storage,您需要通过ThreadManager API创建它。