发现了google-api-java-clien的一个BUG

今天我用google-api-java-client做基于servlet的oauth授权流程,但是遇到了一个奇怪的异常:

java.lang.ClassCastException: com.google.api.client.auth.oauth2.AuthorizationCodeResponseUrl cannot be cast to com.google.api.client.auth.oauth2.AuthorizationCodeRequestUrl
com.google.api.client.auth.oauth2.AuthorizationCodeResponseUrl.set(AuthorizationCodeResponseUrl.java:222)
com.google.api.client.auth.oauth2.AuthorizationCodeResponseUrl.set(AuthorizationCodeResponseUrl.java:58)
com.google.api.client.http.UrlEncodedParser.parse(UrlEncodedParser.java:182)
com.google.api.client.http.UrlEncodedParser.parse(UrlEncodedParser.java:96)
com.google.api.client.http.GenericUrl.\(GenericUrl.java:153)
com.google.api.client.http.GenericUrl.\(GenericUrl.java:117)
com.google.api.client.http.GenericUrl.\(GenericUrl.java:106)
com.google.api.client.auth.oauth2.AuthorizationCodeResponseUrl.\(AuthorizationCodeResponseUrl.java:99)
com.google.api.client.extensions.servlet.auth.oauth2.AbstractAuthorizationCodeCallbackServlet.doGet(AbstractAuthorizationCodeCallbackServlet.java:115)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

这个stacktrace中找不到我的代码。看样子像是google的代码内部的问题。于是我翻源代码,从AuthorizationCodeResponseUrl类中找到了出错的那一行:

@Override
 public AuthorizationCodeRequestUrl set(String fieldName, Object value) {
 return (AuthorizationCodeRequestUrl) super.set(fieldName, value);
 }

AuthorizationCodeResponseUrl类继承自GenericUrl继承自GenericData。

    public GenericData set(String fieldName, Object value) {
    FieldInfo fieldInfo = classInfo.getFieldInfo(fieldName);
    if (fieldInfo != null) {
      fieldInfo.setValue(this, value);
    } else {
      if (classInfo.getIgnoreCase()) {
        fieldName = fieldName.toLowerCase();
      }
      unknownFields.put(fieldName, value);
    }
    return this;
  }

由此可见,set方法应该是永远返回this对象。那么AuthorizationCodeResponseUrl的set方法返回的也应该永远是AuthorizationCodeResponseUrl的实例,而不是AuthorizationCodeRequestUrl的实例。

于是我就去翻这个文件的改动历史,发现这些set方法是一次性批量添加的,应该是copy-paste的时候忘了改了。

但是有个问题,如果这确实是一个bug,那么任何依赖于Authorization Code Flow的webapp都无法走完最基本的认证流程,每个用到AbstractAuthorizationCodeServlet的程序都应该会失败。这个代码改动是在4个月前了,难道就一直没有人更新、测试过吗?

update: 我通过Code Review Tool联系上了改动这行代码的人,他们确认这确实是一个BUG。然后他们建了issue并fix了,参见https://codereview.appspot.com/9782046/https://codereview.appspot.com/7095052/ 。这个更改将会发布在1.15.1或者1.16版本中。

此博客中的热门博文

在windows下使用llvm+clang

少写代码,多读别人写的代码

tensorflow distributed runtime初窥