Google Drive API nie gra dobrze z ProGuard (NPE)
Obecnie mam doświadczenie, że kawałek kodu, który korzysta z Google Drive API działa dobrze bez wprowadzania ProGuard.
Jednak po wprowadzeniu ProGuard, dostaję następujący błąd czasu wykonania.
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.NullPointerException
at com.google.api.client.util.Types.getActualParameterAtPosition(Types.java:329)
at com.google.api.client.util.Types.getIterableParameter(Types.java:309)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:546)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:350)
at com.google.api.client.json.JsonParser.parseValue(JsonParser.java:586)
at com.google.api.client.json.JsonParser.parse(JsonParser.java:289)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:76)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:71)
at com.google.api.client.http.HttpResponse.parseAs(HttpResponse.java:491)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:456)
at com.jstock.c.b.a(CloudFile.java:136)
Uwaga, awaria dzieje się na moim kodzie (który jest com.jstock.c. b. a jeśli odtworzę za pomocą mapowania.txt)
// request is Files.List
FileList files = request.execute();
W moim proguard, myślałem, że mając następujące 2 Kluczowe instrukcje, w stanie zapobiec awarii od: mówię ProGuard nigdy nie dotykać jackson i Google libraries.
-keep class org.codehaus.** { *; }
-keep class com.google.** { *; }
-keep interface org.codehaus.** { *; }
-keep interface com.google.** { *; }
Ale to nie działa. NPE nadal występują w typach .java
Zauważ, że miałem kolejną próbę, myślałem, że obfuscate proces powoduje, że NPE się dzieje. Dlatego staram się go wyłączyć za pomocą -dontobfuscate
. Ale tym razem Nie będę w stanie wygenerować pliku APK i uzyskać popularnego Komunikatu o błędzie: Konwersja do formatu Dalvik nie powiodła się z błędem 1
Oto konfiguracja proguard powodująca NPE w Google Drive API.
-optimizationpasses 1
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
# Comment out the following line, will cause popular "Conversion to Dalvik format failed with error 1"
##-dontobfuscate
-dontwarn sun.misc.Unsafe
-dontwarn com.google.common.collect.MinMaxPriorityQueue
-dontwarn javax.swing.**
-dontwarn java.awt.**
-dontwarn org.jasypt.encryption.pbe.**
-dontwarn java.beans.**
-dontwarn org.joda.time.**
-dontwarn com.google.android.gms.**
-dontwarn org.w3c.dom.bootstrap.**
-dontwarn com.ibm.icu.text.**
-dontwarn demo.**
# Hold onto the mapping.text file, it can be used to unobfuscate stack traces in the developer console using the retrace tool
-printmapping mapping.txt
# Keep line numbers so they appear in the stack trace of the develeper console
-keepattributes *Annotation*,EnclosingMethod,SourceFile,LineNumberTable
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }
# https://sourceforge.net/p/proguard/discussion/182456/thread/e4d73acf
-keep class org.codehaus.** { *; }
-keep class com.google.** { *; }
-keep interface org.codehaus.** { *; }
-keep interface com.google.** { *; }
-assumenosideeffects class android.util.Log {
public static int d(...);
public static int i(...);
public static int e(...);
public static int v(...);
}
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
public static *** i(...);
}
-keepclasseswithmembers class com.google.common.base.internal.Finalizer{
<methods>;
}
Czy Mogę spróbować czegoś jeszcze?
Nie jestem pewien, czy może to być spowodowane kombinacją bibliotek. (Chociaż wszystko działa całkiem dobrze bez wprowadzenia ProGuard)
Jeśli spojrzę na miejsce awarii NPE (typy.getActualParameterAtPosition(Typ.java:329))
private static Type getActualParameterAtPosition(Type type, Class<?> superClass, int position) {
ParameterizedType parameterizedType = Types.getSuperParameterizedType(type, superClass);
Type valueType = parameterizedType.getActualTypeArguments()[position];
// this is normally a type variable, except in the case where the class of iterableType is
// superClass, e.g. Iterable<String>
if (valueType instanceof TypeVariable<?>) {
Type resolve = Types.resolveTypeVariable(Arrays.asList(type), (TypeVariable<?>) valueType);
if (resolve != null) {
return resolve;
}
}
return valueType;
}
Podejrzewam Types.getSuperParameterizedType
powrót null
. Więc dalej przyglądam się Types.getSuperParameterizedType
.
public static ParameterizedType getSuperParameterizedType(Type type, Class<?> superClass) {
if (type instanceof Class<?> || type instanceof ParameterizedType) {
outer: while (type != null && type != Object.class) {
Class<?> rawType;
if (type instanceof Class<?>) {
// type is a class
rawType = (Class<?>) type;
} else {
// current is a parameterized type
ParameterizedType parameterizedType = (ParameterizedType) type;
rawType = getRawClass(parameterizedType);
// check if found Collection
if (rawType == superClass) {
// return the actual collection parameter
return parameterizedType;
}
if (superClass.isInterface()) {
for (Type interfaceType : rawType.getGenericInterfaces()) {
// interface type is class or parameterized type
Class<?> interfaceClass =
interfaceType instanceof Class<?> ? (Class<?>) interfaceType : getRawClass(
(ParameterizedType) interfaceType);
if (superClass.isAssignableFrom(interfaceClass)) {
type = interfaceType;
continue outer;
}
}
}
}
// move on to the super class
type = rawType.getGenericSuperclass();
}
}
return null;
}
Jaka jest możliwa przyczyna, która może spowodować getSuperParameterizedType
powrót null
, po przetworzeniu przez ProGuard?
6 answers
Dla mnie zadziałała kombinacja:
-keep class com.google.** { *;}
-keep interface com.google.** { *;}
-dontwarn com.google.**
-dontwarn sun.misc.Unsafe
-dontwarn com.google.common.collect.MinMaxPriorityQueue
-keepattributes *Annotation*,Signature
-keep class * extends com.google.api.client.json.GenericJson {
*;
}
-keep class com.google.api.services.drive.** {
*;
}
To zapewniło działające rozwiązanie zgodne z proguard dla niedawnego projektu Dysku Google.
Nie można jednak przypisać sobie całego uznania za to rozwiązanie, pierwotnie znalezione pod tym linkiem tutaj
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-24 15:13:33
Właściwa kombinacja to:
- keepattributes Signature,RuntimeVisibleAnnotations, AnnotationDefault
Jest konfiguracja proguard przygotowana przez Google dla projektu google-api-java-client
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-19 13:16:07
Pierwsze-prowadzenie klasy nie oznacza nie dotykania jej. Oznacza to, że nie zmieniaj jej nazwy i używaj jej jako podstawy do określania, czy inne klasy nie są odwołane i można je usunąć.
Optymalizacja nadal występuje, co jest prawdopodobnie Twoim problemem. Następnym krokiem, który chciałbym zrobić, to spróbować z: -dontoptimize
To powinno spowodować, że inne optymalizacje będą ignorowane.
BTW, Nie wiem, jakiej wersji SDK używasz. Używam 15, 20 jest najnowsze, i proguard-projekt.plik txt jest tworzenie wraz z projektem. Stosowane opcje optymalizacji to:
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
Jeśli wyłączenie optymalizacji powoduje, że działa, może wyłączenie wszystkich optymalizacji (o to chodzi ! czy) SDK robi, pozwoli Ci zrobić optymalizację, jak również.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-21 20:57:42
Typy metod.getSuperParameterizedType opiera się na informacjach o generykach. Generyczne są usuwane w Javie. Kompilator dodaje je tylko jako atrybuty adnotacji, JVM je ignoruje, a ProGuard je odrzuca, chyba że każesz mu tego nie robić. To może pomóc:
-keepattributes *Annotation*
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-21 23:52:45
Czy twój kod używa czegoś, co implementuje Serializable? Wszystkie one również muszą zostać wykluczone.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-22 20:45:55
Ostatnio było kilka aktualizacji do GooglePlayServices. Nie podoba mi się nowe API. Miałem te same problemy.
Nie mogłem skompilować podpisanej aplikacji z proguard. Szablon Proguard od Google nie działał dla mnie.
Dodaję te cztery linie do mojego ProGuard config i działa:
-dontwarn com.google.android.gms.**
-keep interface com.google.** { *; }
-keep class * extends com.google.api.client.json.GenericJson {*;}
-keep class com.google.api.services.drive.** {*;}
To dziwne. Poprzednia wersja google-api-services-drive-v2 skompilowana bez żadnych problemów.
Używam najnowszej wersji w tej chwili: google-api-services-drive-v2-rev47-1.12.0-beta.jar
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-08 09:44:25