Reputation: 31
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
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
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
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