![](/img/trans.png)
[英]java.lang.NoClassDefFoundError: com/google/appengine/api/datastore/AsyncDatastoreService
[英]java.lang.NoClassDefFoundError: com/google/appengine/api/urlfetch/HTTPMethod
我正在嘗試按照以下方式使用后端服務器驗證 Google ID 令牌:
https://developers.google.com/identity/sign-in/android/backend-auth
令牌最初由 android 應用程序檢索,然后通過嘗試驗證的套接字傳遞到后端登錄服務器。 就目前情況而言,在我導入的 GoogleIdTokenVerifier 代碼中在運行時拋出了一個錯誤。
服務器線程.java:
GoogleIdToken idToken = GoogleAuthenticator.authenticateToken(tokenJson.getToken());
GoogleAuthenticator.java:
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.Properties;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.extensions.appengine.http.UrlFetchTransport;
public class GoogleAuthenticator {
public GoogleAuthenticator(){
}
public static Properties prop;
public static GoogleIdToken authenticateToken(String inputToken) throws IOException{
final JacksonFactory jacksonFactory = new JacksonFactory();
prop = new Properties();
prop.load(GoogleAuthenticator.class.getClassLoader().getResourceAsStream("config.properties"));
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(UrlFetchTransport.getDefaultInstance(), jacksonFactory)
// Specify the CLIENT_ID of the app that accesses the backend:
.setAudience(Collections.singletonList(prop.getProperty("google.web.client.id")))
// Or, if multiple clients access the backend:
//.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
.build();
GoogleIdToken idToken;
try {
idToken = verifier.verify(inputToken);
return idToken;
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
pom.xml
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.25.0</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client-appengine</artifactId>
<version>1.25.0</version>
</dependency>
我目前看到以下堆棧跟蹤:
Exception in thread "Thread-0" java.lang.NoClassDefFoundError: com/google/appengine/api/urlfetch/HTTPMethod
at com.google.api.client.extensions.appengine.http.UrlFetchTransport.buildRequest(UrlFetchTransport.java:118)
at com.google.api.client.extensions.appengine.http.UrlFetchTransport.buildRequest(UrlFetchTransport.java:50)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:872)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.refresh(GooglePublicKeysManager.java:172)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.getPublicKeys(GooglePublicKeysManager.java:140)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:174)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:192)
at com.omarhegazi.login.GoogleAuthenticator.authenticateToken(GoogleAuthenticator.java:40)
at com.omarhegazi.login.ServerThread.run(ServerThread.java:45)
看起來依賴項中沒有可用的 HTTPMethod 類。 有什么想法嗎?
更新1:
添加下面的 appengine 依賴項已經取得了一些進展。 我現在有以下堆棧跟蹤錯誤:
Exception in thread "Thread-0" com.google.apphosting.api.ApiProxy$CallNotFoundException: The API package 'urlfetch' or call 'Fetch()' was not found.
at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:98)
at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:37)
at com.google.api.client.extensions.appengine.http.UrlFetchRequest.execute(UrlFetchRequest.java:74)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.refresh(GooglePublicKeysManager.java:172)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.getPublicKeys(GooglePublicKeysManager.java:140)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:174)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:192)
at com.omarhegazi.login.GoogleAuthenticator.authenticateToken(GoogleAuthenticator.java:40)
at com.omarhegazi.login.ServerThread.run(ServerThread.java:45)
這是使用 v1.6.1
我還嘗試使用 v1.9.70,結果如下:
Exception in thread "Thread-0" com.google.apphosting.api.ApiProxy$CallNotFoundException: Can't make API call urlfetch.Fetch 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:800)
at com.google.apphosting.api.ApiProxy.makeSyncCall(ApiProxy.java:112)
at com.google.appengine.api.urlfetch.URLFetchServiceImpl.fetch(URLFetchServiceImpl.java:40)
at com.google.api.client.extensions.appengine.http.UrlFetchRequest.execute(UrlFetchRequest.java:74)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.refresh(GooglePublicKeysManager.java:172)
at com.google.api.client.googleapis.auth.oauth2.GooglePublicKeysManager.getPublicKeys(GooglePublicKeysManager.java:140)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:174)
at com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier.verify(GoogleIdTokenVerifier.java:192)
at com.omarhegazi.login.GoogleAuthenticator.authenticateToken(GoogleAuthenticator.java:40)
at com.omarhegazi.login.ServerThread.run(ServerThread.java:45)
看起來 fetch 包被包含在 1.6.1 之后,但存在一些與進行 API 調用的線程相關的問題。
嘗試在pom.xml
包含appengine
依賴項:
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>1.6.1</version> <!-- Check your version -->
</dependency>
根據上面 ngueno 的帖子,我需要 appengine-api-1.0-sdk v1.9.70 才能使其正常工作:
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>1.9.70</version>
</dependency>
要解決此版本的 appengine API 引發的“無法在既不是原始請求線程也不是 ThreadManager 創建的線程的線程中進行 API 調用 urlfetch.Fetch”錯誤,我必須更改使用的 HttpTransport從UrlFetchTransport.getDefaultInstance()到GoogleNetHttpTransport.newTrustedTransport()
IE:
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
prop = new Properties();
prop.load(GoogleAuthenticator.class.getClassLoader().getResourceAsStream("config.properties"));
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(httpTransport, gsonFactory)
// Specify the CLIENT_ID of the app that accesses the backend:
.setAudience(Collections.singletonList(prop.getProperty("google.client.id")))
.setIssuer("https://accounts.google.com")
// Or, if multiple clients access the backend:
//.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3, etc))
.build();
// (Receive idTokenString by HTTPS POST)
GoogleIdToken idToken;
idToken = verifier.verify(inputToken);
使用的所有參考資料和指南都指出 UrlFetchTransport.getDefaultInstance() 是線程安全的/使用的最佳選擇,但它在這里對我不起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.