![](/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.