2015-07-20 16 views
8

Ich habe ein Google AppEngine Java-Projekt eingerichtet, das BigQuery aufruft, um die Ergebnisse eines Abfrageauftrags anzuzeigen. Der Beispielcode und die Anweisungen, die ich verwendet habe, finden Sie unter here. Die App wird ausgeführt und ruft die Abfrage von meinem Entwicklungscomputer ab. Wenn ich sie jedoch auf appspot.com auf AppEngine hochlade, wird die client_secrets.json-Datei (unterschiedliche Datei für dev und appspot.com aufgrund der JavaScript-URL-Autorisierung) nicht geladen der folgende Ausschnitt:Lesen von Java-Ressourcendateien in Google AppEngine

static GoogleClientSecrets getClientCredential() throws IOException { 
if (clientSecrets == null) { 

    clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, 
      new InputStreamReader(new FileInputStream(
       new File("WEB-INF/client_secrets.json")))); 

    Preconditions.checkArgument(!clientSecrets.getDetails().getClientId().startsWith("Enter ") 
     && !clientSecrets.getDetails().getClientSecret().startsWith("Enter "), 
     "Enter Client ID and Secret from https://code.google.com/apis/console/?api=bigquery " 
     + "into bigquery-appengine-sample/src/main/resources/client_secrets.json"); 
} 
return clientSecrets; 

}

Hier ist meine appengine-web.xml-Ressource-Datei Definition:

<resource-files> 
    <include path="**" /> 
    </resource-files> 

die client_secrets.json Datei richtig in meiner Krieg-Datei verpackt. Der Fehler, den ich bekommen ist:

>/
Uncaught exception from servlet 
java.io.FileNotFoundException: /base/data/home/apps/s~tactile-reason-849/1.385872137632330782/WEB-INF/client_secrets.json (No such file or directory) 
    at java.io.FileInputStream.open(Native Method) 
    at java.io.FileInputStream.<init>(FileInputStream.java:171) 
    at com.google.api.client.sample.bigquery.appengine.dashboard.ServiceUtils.getClientCredential(ServiceUtils.java:71) 
    at com.google.api.client.sample.bigquery.appengine.dashboard.ServiceUtils.newFlow(ServiceUtils.java:103) 
    at com.google.api.client.sample.bigquery.appengine.dashboard.MainServlet.initializeFlow(MainServlet.java:125) 
    at com.google.api.client.extensions.servlet.auth.oauth2.AbstractAuthorizationCodeServlet.service(AbstractAuthorizationCodeServlet.java:124) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166) 
    at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43) 
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157) 
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388) 
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) 
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) 
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) 
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418) 
    at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:257) 
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) 
    at org.mortbay.jetty.Server.handle(Server.java:326) 
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) 
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923) 
    at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76) 
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) 
    at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:146) 
    at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:482) 
    at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437) 
    at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444) 
    at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:230) 
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308) 
    at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300) 
    at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441) 
    at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:234) 
    at java.lang.Thread.run(Thread.java:745) 

ich versuchen kann, mit ServletContext.getResourceAsStream() statt, aber die Klasse, die zu BigQuery in dem Beispiel-App verbindet, ist kein Servletklasse, so dass dies eine Reorganisation des Code erforderlich richtig zu implementieren, und Google's instructions scheinen zu zeigen, dass mein Code funktionieren sollte. Jede Hilfe wird geschätzt, danke!

+0

Sind Sie Maven/Gradle mit? Wenn dies der Fall ist, ziehen Sie die Datei in das Verzeichnis src/main/resources und versuchen Sie sie zu laden, wie @NamshubWriter zeigt – zaratustra

Antwort

9

Ressourcendateien sind nicht auf dem Dateisystem, so new File("/WEB-INF/client_secrets.json") gewöhnlichen würde nicht funktionieren. Stattdessen müssen Sie in der Regel als eine Ressource laden:

InputStream resourceStream = Thread.currentThread().getContextClassLoader() 
    .getResourceAsStream("/WEB-INF/client_secrets.json"); 

Aus irgendeinem Grund AppEngine werden Sie Ressourcen unter WEB-INF mit dem Klassenlader nicht zulassen, laden (Sie können mit den oben genannten Ressourcen in JAR-Dateien laden Technik).

Sie können die Datei-API verwenden, um auf Pfade in WEB-INF in App zuzugreifen, aber die Pfade müssen relativ sein. Unter der Annahme, dass die Datei client_secrets.json im WEB-INF Ordner vorhanden ist, sollte diese Arbeit:

clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, 
    new InputStreamReader(new FileInputStream(
     new File("WEB-INF/client_secrets.json")))); 

die File APIs Zur Nutzung von Ressourcen unter WEB-INF zu lesen, auch müssen Sie auch sicherstellen, dass Ihre appengine-web.xml Datei, die Ressourcen enthält in Ihrem WEB-INF:

<resource-files> 
    <include path="/**.json" /> 
</resource-files> 

Siehe Configuring appengine-web.xml und Why can't I read from this file

+0

Danke für die schnelle Antwort @NamshubWriter. Ich habe die von Ihnen vorgeschlagene Änderung angewendet. Jetzt erhalte ich einen neuen Fehler: Uncaught-Ausnahme von Servlet java.io.FileNotFoundException: /base/data/home/apps/s~tactile-reason-849/1.385858979910614152/WEB- INF/client_secrets.json (Keine solche Datei oder Verzeichnis) –

+0

@ChrisLumpkin Ihr appengine-web.xml-Snippet bedeutet, dass diese Datei unter "Klassen" steht, aber Ihr Java-Code-Snippet versucht direkt unter WEB-INF darauf zuzugreifen. Wo ist diese Ressource? Kommt es von einer Ihrer JAR-Dateien? Kannst du in deiner WAR-Datei nachsehen, wo genau sie ist? – NamshubWriter

+0

Ich habe gerade die obigen Snippets aktualisiert, um die Änderungen wiederzugeben, die ich vorgenommen habe. Die WAR-Datei hat WEB-INF/client_secrets.json. –

Verwandte Themen