2017-07-26 52 views
1

在新的App Engine标准Java 8环境中,尝试发布到PubSub主题时出现以下错误:

io.grpc.internal.ChannelExecutor drain: Runnable threw exception in ChannelExecutor (ChannelExecutor.java:89) 
java.lang.NullPointerException 
    at com.google.apphosting.runtime.ApiProxyImpl$CurrentRequestThreadFactory.newThread(ApiProxyImpl.java:1267) 
    at com.google.common.util.concurrent.ThreadFactoryBuilder$1.newThread(ThreadFactoryBuilder.java:162) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.<init>(ThreadPoolExecutor.java:612) 
    at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:925) 
    at java.util.concurrent.ThreadPoolExecutor.ensurePrestart(ThreadPoolExecutor.java:1587) 
    at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:336) 
    at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:555) 
    at io.grpc.internal.ManagedChannelImpl.rescheduleIdleTimer(ManagedChannelImpl.java:334) 
    at io.grpc.internal.ManagedChannelImpl.exitIdleMode(ManagedChannelImpl.java:299) 
    at io.grpc.internal.ManagedChannelImpl$4$1.run(ManagedChannelImpl.java:357) 
    at io.grpc.internal.ChannelExecutor.drain(ChannelExecutor.java:87) 
    at io.grpc.internal.ManagedChannelImpl$4.get(ManagedChannelImpl.java:359) 
    at io.grpc.internal.ClientCallImpl.start(ClientCallImpl.java:218) 
    at io.grpc.ForwardingClientCall.start(ForwardingClientCall.java:47) 
    at com.google.api.gax.grpc.HeaderInterceptor$1.start(HeaderInterceptor.java:62) 
    at io.grpc.stub.ClientCalls.startCall(ClientCalls.java:276) 
    at io.grpc.stub.ClientCalls.asyncUnaryRequestCall(ClientCalls.java:252) 
    at io.grpc.stub.ClientCalls.futureUnaryCall(ClientCalls.java:186) 
    at com.google.pubsub.v1.PublisherGrpc$PublisherFutureStub.publish(PublisherGrpc.java:460) 
    at com.google.cloud.pubsub.v1.Publisher.publishOutstandingBatch(Publisher.java:329) 
    at com.google.cloud.pubsub.v1.Publisher.publishAllOutstanding(Publisher.java:304) 
    at com.google.cloud.pubsub.v1.Publisher.access$500(Publisher.java:79) 
    at com.google.cloud.pubsub.v1.Publisher$5.run(Publisher.java:283) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:295) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 

相关的问题是这里多一点信息:https://github.com/GoogleCloudPlatform/google-cloud-java/issues/2275

这是一个摇篮项目具有以下依存关系:

dependencies { 
    providedCompile 'javax.servlet:javax.servlet-api:3.1.0' 
    providedCompile 'com.google.appengine:appengine:+' 
    testCompile 'org.eclipse.jetty:jetty-server:9.+' 
    testCompile 'org.eclipse.jetty:jetty-servlet:9.+' 
    compile group: 'com.google.guava', name: 'guava', version: '19.+' 
    compile group: 'com.google.inject', name: 'guice', version: '4.+' 
    compile 'com.google.appengine:appengine-api-1.0-sdk:1.+' 
    compile 'com.google.cloud:google-cloud-storage:1.2+' 
    compile group: 'com.google.cloud', name: 'google-cloud-pubsub', version: '0.20+' 
    compile ('com.google.cloud:google-cloud-datastore:1.2+') 
    compile('com.google.apis:google-api-services-cloudkms:v1-rev15-1.22.0') { 
    exclude(group: 'com.google.guava', module: 'guava-jdk5') 
    } 
    compile(group: 'com.google.api-client', name: 'google-api-client', version: '1.+') { 
    exclude(group: 'com.google.guava', module: 'guava-jdk5') 
    } 
    compile(group: 'com.google.api-client', name: 'google-api-client-appengine', version: '1.+') { 
    exclude(group: 'com.google.guava', module: 'guava-jdk5') 
    } 
} 

我通过将war文件传递到appcfg.sh来部署,而不是使用App Engine Gradle插件。我的Java 8 灵活的环境中使用较旧的PubSub库(0.11系列),但是由于使用较新的PubSub库(0.20系列)切换到Java 8标准环境,我每次都会遇到此错误。

其他唯一的参考这个错误我已经看到了在这个谷歌网上论坛讨论:https://groups.google.com/d/msg/google-appengine/2UTg4Eqskyk/PbqYEK3GAAAJ

更新1:

尝试真正可怕的工作后,在周围,谷歌组线程以上建议( https://gist.github.com/cmaan/7752e3c4fd0b1ba90a745cb6db232206)NPE已停止发生。但是,现在有一个新的问题:

Caused by: io.grpc.StatusRuntimeException: UNAUTHENTICATED 
    at io.grpc.Status.asRuntimeException(Status.java:543) ~[grpc-core-1.4.0.jar:1.4.0] 
    at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:442) ~[grpc-stub-1.4.0.jar:1.4.0] 
    at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:426) ~[grpc-core-1.4.0.jar:1.4.0] 
    at io.grpc.internal.ClientCallImpl.access$100(ClientCallImpl.java:76) ~[grpc-core-1.4.0.jar:1.4.0] 
    at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:512) ~[grpc-core-1.4.0.jar:1.4.0] 
    at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$700(ClientCallImpl.java:429) ~[grpc-core-1.4.0.jar:1.4.0] 
    at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:544) ~[grpc-core-1.4.0.jar:1.4.0] 
    at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:52) ~[grpc-core-1.4.0.jar:1.4.0] 
    at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:117) ~[grpc-core-1.4.0.jar:1.4.0] 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_112-google-v7] 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_112-google-v7] 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_112-google-v7] 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:295) ~[na:1.8.0_112-google-v7] 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_112-google-v7] 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_112-google-v7] 
    ... 1 common frames omitted 
Caused by: java.io.IOException: Could not get the access token. 
    at com.google.auth.oauth2.AppEngineCredentials.refreshAccessToken(AppEngineCredentials.java:136) ~[google-auth-library-oauth2-http-0.7.0.jar:na] 
    at com.google.auth.oauth2.OAuth2Credentials.refresh(OAuth2Credentials.java:149) ~[google-auth-library-oauth2-http-0.7.0.jar:na] 
    at com.google.auth.oauth2.OAuth2Credentials.getRequestMetadata(OAuth2Credentials.java:135) ~[google-auth-library-oauth2-http-0.7.0.jar:na] 
    at io.grpc.auth.GoogleAuthLibraryCallCredentials$1.run(GoogleAuthLibraryCallCredentials.java:110) ~[grpc-auth-1.4.0.jar:1.4.0] 
    ... 7 common frames omitted 
Caused by: java.lang.reflect.InvocationTargetException: null 
    at sun.reflect.GeneratedMethodAccessor60.invoke(Unknown Source) ~[na:na] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112-google-v7] 
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112-google-v7] 
    at com.google.auth.oauth2.AppEngineCredentials.refreshAccessToken(AppEngineCredentials.java:131) ~[google-auth-library-oauth2-http-0.7.0.jar:na] 
    ... 10 common frames omitted 
Caused by: com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call memcache.Get in a thread that is neither the original request thread nor a thread created by ThreadManager 
    at com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:844) ~[runtime-shared.jar:na] 
    at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:183) ~[runtime-shared.jar:na] 
    at com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:180) ~[runtime-shared.jar:na] 
    at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:93) ~[appengine-api.jar:na] 
    at com.google.appengine.api.memcache.MemcacheServiceImpl.quietGet(MemcacheServiceImpl.java:28) ~[appengine-api.jar:na] 
    at com.google.appengine.api.memcache.MemcacheServiceImpl.get(MemcacheServiceImpl.java:51) ~[appengine-api.jar:na] 
    at com.google.appengine.api.appidentity.AppIdentityServiceImpl.getAccessToken(AppIdentityServiceImpl.java:300) ~[appengine-api.jar:na] 
    ... 14 common frames omitted 

回答

1

我能找到一个解决才能够发布到Java 8标准环境PubSub的话题,直到一个长期解决方案发布:https://github.com/GoogleCloudPlatform/google-cloud-java/issues/2275

首先需要从App Engine请求线程获取凭证。然后,将这些凭据传递给在非请求线程(例如由Java ExecutorService创建的线程)内创建的新发布服务器。这种结合起作用但效率不高。