【问题标题】:java.lang.NoClassDefFoundError: com/google/appengine/api/urlfetch/HTTPMethodjava.lang.NoClassDefFoundError: com/google/appengine/api/urlfetch/HTTPMethod
【发布时间】:2018-12-29 17:58:44
【问题描述】:

我正在尝试使用后端服务器验证 Google ID 令牌:

https://developers.google.com/identity/sign-in/android/backend-auth

令牌最初由安卓应用程序检索,然后通过尝试验证的套接字传递到后端登录服务器。就目前情况而言,我正在导入的 GoogleIdTokenVerifier 代码在运行时抛出了一个错误。

ServerThread.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 调用的线程有关的问题。

【问题讨论】:

    标签: java google-app-engine google-api google-api-client urlfetch


    【解决方案1】:

    尝试在您的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>
    

    Link to the docs

    【讨论】:

    • 嗯,这肯定有助于取得一些进展 - 谢谢!现在出现了新的堆栈跟踪错误(请参阅上面的更新)。
    【解决方案2】:

    根据上面 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>
    

    解决 "Can't make API call urlfetch.Fetch in a thread that is not the original request thread 也不是由 ThreadManager 创建的线程" appengine API,我不得不将使用的 HttpTransport 从 UrlFetchTransport.getDefaultInstance() 更改为 GoogleNetHttpTransport.newTrustedTransport()

    即:

        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() 是线程安全的/最好的选择,但它在这里对我不起作用。

    【讨论】:

      猜你喜欢
      • 2014-12-04
      • 2017-12-15
      • 1970-01-01
      • 1970-01-01
      • 2012-10-09
      • 2023-03-03
      • 2023-03-05
      • 2012-06-01
      • 1970-01-01
      相关资源
      最近更新 更多