Quiet Punch
Quiet Punch

Reputation: 31

YouTube API Exception In Initializer Error

So I have been using the YouTube API successfully for the past few months in Android Studio. I went to update my app and as of today the app keeps crashing when it is trying to initialize the YouTube builder. Has anyone else experienced this problem?

mYoutubeDataApi = new YouTube.Builder(mTransport, mJsonFactory, null)
                                .setApplicationName(getResources().getString(R.string.app_name))
                                .build();

The app crashes with the following output:

2019-12-09 01:38:06.443 17937-17937/ E/AndroidRuntime: FATAL EXCEPTION: main

    java.lang.ExceptionInInitializerError
        at com.google.api.services.youtube.YouTube.<clinit>(YouTube.java:44)
        at com.google.api.services.youtube.YouTube$Builder.build(YouTube.java:16644)

Line 44 in the YouTube.java file is:

public class YouTube extends com.google.api.client.googleapis.services.json.AbstractGoogleJsonClient {

  // Note: Leave this static initializer at the top of the file.
  static {
    com.google.api.client.util.Preconditions.checkState(
        com.google.api.client.googleapis.GoogleUtils.MAJOR_VERSION == 1 &&
        com.google.api.client.googleapis.GoogleUtils.MINOR_VERSION >= 15,
        "You are currently running with version %s of google-api-client. " +
        "You need at least version 1.15 of google-api-client to run version " +
        "1.30.1 of the YouTube Data API library.", com.google.api.client.googleapis.GoogleUtils.VERSION);
  }

Upvotes: 1

Views: 725

Answers (3)

AndroidEngineX
AndroidEngineX

Reputation: 1451

In the latest version, they have added the library proguard file, which keeps the the GoogleUtils.java and hence keeps the google-api-client.properties which gets generated in build time.

Initially they used to update the string literal for version name for each release hence that time parsing of version name done in GoogleUtils.java was crash free.

But later on they shifted to parsing the version from google-api-client.properties at GoogleUtils.java which started giving error as proguard started removing the generated google-api-client.properties file.

Later on after release, 1.30.9 at this commit id the started using the embedded proguard rule to keep the GoogleUtils.java file

They actually fixed the issue at release, 1.30.8 at the commit, 1.30.9 release just does the same fix in more android recommended way.

Although the final adopted version uses GoogleUtils.class.getResourceAsStream("google-api-client.properties") which is Java api and returns the InputStream to read the google-api-client.properties file. Since these stream may not work perfectly in some devices they still crash but with lesser frequency(as we still see the crashes with the fixed present in the release 1.30.9).

Created an issue to track this

Upvotes: 0

Elliotte Rusty Harold
Elliotte Rusty Harold

Reputation: 991

This bug is fixed in com.google.api-client:google-api-client:1.30.7. Upgrading to that version or later will fix it.

Upvotes: 1

Samikay
Samikay

Reputation: 64

In 1.30.6, they added this: https://github.com/googleapis/google-api-java-client/pull/1419

To fix, edit your build.gradle back down to 1.30.5

dependencies {
  implementation ('com.google.api-client:google-api-client:1.30.5')
  implementation ('com.google.api-client:google-api-client-android:1.30.5')
}

If there's a better solution, I'd like to hear it!


To further explain why that change in 1.30.6 causes the crash, here's some more info.

Specifically, the issue is coming from this file: https://github.com/googleapis/google-api-java-client/blob/master/google-api-client/src/main/java/com/google/api/client/googleapis/GoogleUtils.java

     Caused by: java.lang.IllegalStateException: No successful match so far
        at java.util.regex.Matcher.ensureMatch(Matcher.java:1116)
        at java.util.regex.Matcher.group(Matcher.java:382)
        at com.google.api.client.googleapis.GoogleUtils.<clinit>(Unknown Source:26)

Here is the relevant code

  public static final String VERSION = getVersion();

  static final Pattern VERSION_PATTERN = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(-SNAPSHOT)?");

  static {
    Matcher versionMatcher = VERSION_PATTERN.matcher(VERSION);
    versionMatcher.find();
    MAJOR_VERSION = Integer.parseInt(versionMatcher.group(1));
    MINOR_VERSION = Integer.parseInt(versionMatcher.group(2));
    BUGFIX_VERSION = Integer.parseInt(versionMatcher.group(3));
  }

private static String getVersion() {
    String version = GoogleUtils.class.getPackage().getImplementationVersion();
    // in a non-packaged environment (local), there's no implementation version to read
    if (version == null) {
      // fall back to reading from a properties file - note this value is expected to be cached
      try (InputStream inputStream =
          GoogleUtils.class.getResourceAsStream("google-api-client.properties")) {
        if (inputStream != null) {
          Properties properties = new Properties();
          properties.load(inputStream);
          version = properties.getProperty("google-api-client.version");
        }
      } catch (IOException e) {
        // ignore
      }
    }
    return version;
  }

Presumably, getVersion is returning null, although I can't say why. Seeing as how this recently happened for me 2-3 days ago also, something we updated must be conflicting.

Upvotes: 3

Related Questions