2015-07-20 50 views
8

我有一個Google AppEngine Java項目設置,它調用BigQuery來顯示查詢作業的結果。我使用的示例代碼和說明可以在here找到。應用程序運行並從我的開發機器中檢索查詢,但是當我上傳到AppEngine以在appspot.com上測試時,它顯示爲client_secrets.json文件(由於JavaScript URL授權,dev和appspot.com的不同文件)無法使用下面的代碼片段:讀取Google AppEngine中的Java資源文件

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; 

}

這裏是我的AppEngine-web.xml中的資源文件的定義:

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

的client_secrets.json檔案的妥善包裝在我的戰爭文件。我得到的錯誤是:

>/
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) 

我可以嘗試使用ServletContext.getResourceAsStream()來代替,但它連接至BigQuery在示例應用程序的類不是一個Servlet類,所以這將需要一些代碼重組正確實施,Google's instructions似乎表明我的代碼應該工作。任何幫助表示讚賞,謝謝!

+0

?如果是這樣,請考慮將該文件放在src/main/resources目錄中並嘗試加載它,如@NamshubWriter顯示 – zaratustra

回答

9

資源文件不在文件系統上,所以new File("/WEB-INF/client_secrets.json")普通不起作用。相反,你通常需要加載它作爲一種資源:

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

出於某種原因,AppEngine上不會讓你使用類加載器加載在WEB-INF資源(可以加載在jar文件的資源與上述技術)。

您可以使用File API訪問App中WEB-INF中的路徑,但路徑需要是相對的。假設文件client_secrets.json是在WEB-INF文件夾,這應該工作:

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

要使用File API來讀取WEB-INF下的資源,你也還需要確保您appengine-web.xml文件包括資源在WEB-INF:

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

你使用Maven /搖籃見Configuring appengine-web.xmlWhy can't I read from this file

+0

感謝您的快速響應@NamshubWriter。我應用了您建議的更改,現在我得到一個新錯誤: 未從servlet中發現異常 java.io.FileNotFoundException:/base/data/home/apps/s~tactile-reason-849/1.385858979910614152/WEB- INF/client_secrets.json(沒有這樣的文件或目錄) –

+0

@ChrisLumpkin您的appengine-web.xml代碼片段暗示此文件位於「類」下,但您的Java代碼段正試圖直接在WEB-INF下訪問它。這個資源在哪裏?它來自你的一個jar文件嗎?你能看看你的WAR文件,看看它究竟在哪裏嗎? – NamshubWriter

+0

我剛剛更新了上面的代碼片段以反映我所做的更改。 war文件確實有WEB-INF/client_secrets.json。 –