使用proGuard时如何保持java.lang.reflect?
How to keep java.lang.reflect when use proGuard?
在我的应用程序中,我想使用这个 库 :https://github.com/xmuSistone/AndroidPileLayout
我想在我的项目中使用 proguard
,当 proguard
我的项目向我显示可能存在错误时。
对于修复 proguard
,库开发人员说:
proguard works wrong when you are using java.lang.reflect api, please
check your own code.
我的混淆器规则:
#--------Glide--------
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
#--------Glide transformations--------
-dontwarn jp.co.cyberagent.android.gpuimage.**
#--------Retrofit--------
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-dontwarn com.squareup.retrofit2.**
-dontwarn retrofit2.Platform$Java8
#--------Gson--------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
#--------ButterKnife--------
# Retain generated class which implement Unbinder.
-keep public class * implements butterknife.Unbinder { public <init>(**, android.view.View); }
# Prevent obfuscation of types which use ButterKnife annotations since the simple name
# is used to reflectively look up the generated ViewBinding.
-keep class butterknife.*
-keepclasseswithmembernames class * { @butterknife.* <methods>; }
-keepclasseswithmembernames class * { @butterknife.* <fields>; }
#--------MyCustomViews--------
-keep class com.app.app.view.** { *; }
-keep class com.app.app.api.models.** { *; }
-keep class java.lang.reflect.** { *; }
-keepclassmembers public class java.lang.reflect.**
如何修复它并保留 java.lang.reflect
?
请帮帮我
请帮帮我
问题不是您需要将 classes 保留在 java.lang.reflect
中,而是您的代码反射中的某处被用于加载、访问和可能修改 class es 在运行时。
因为 ProGuard 和其他混淆器重命名您的 classes 以使逆向工程更难,所以在字符串中使用硬编码的 classname 将会失败。例如考虑这个代码:
com.acme.Acme acme = Class.forName("com.acme.Acme").newInstance();
现在考虑在 com.acme.Acme
上 运行 Proguard 之后,它可能已重命名为 a.a.A
。该代码将有效地读取:
a.a.A acme = Class.forName("com.acme.Acme").newInstance();
这将在运行时导致 ClassNotFoundException
,这就是 ProGuard 会根据其配置发出警告或错误的原因。
解决方案是仔细调查您是否以及在何处可能在自己的代码中使用反射,是否可以避免该反射,是否可以忽略它,或者是否需要保留 classes 正在反映。
在我上面的示例中,您可以通过指定 -keepnames com.acme.Acme
来避免麻烦。如果反射用于检测 class 成员,您可能需要考虑 -keep
ing 整个 class 及其所有成员。
但本质上,根据定义混淆和反射并不能很好地混合。
获取运行时异常的原因可能因您实施的代码而异。
获得异常背后的原因之一可能是使用反射依赖代码中的 field/classes/method 名称 - ProGuard 在混淆时重命名您的 classes 因此为了在混淆后可以访问它们,它们需要明确防止混淆。
-keep app.package.FancyClass { *; }
如果是库本身导致混淆后的应用程序崩溃,那么我建议找到确切的位置并明确保留发生异常的 class 所依赖的 classes。
最简单的情况可能是保留整个库:
-keep com.stone.pile.** { *; }
但您通常可以将 ProGuard 配置得比这更激进。不过,这是一个很好的起点。
我认为 -keep java.lang.reflect.**
规则在这里没有多大帮助。根本原因在于代码依赖于 class 需要从混淆中排除的内部结构。
找到易受攻击的代码并尝试保持classes/methods/internals通过反射访问。
编辑:
如果您将 class 文件粘贴到抛出异常的位置,将会有很大的帮助。异常消息也会添加到上下文中。你能做到吗?
在我的应用程序中,我想使用这个 库 :https://github.com/xmuSistone/AndroidPileLayout
我想在我的项目中使用 proguard
,当 proguard
我的项目向我显示可能存在错误时。
对于修复 proguard
,库开发人员说:
proguard works wrong when you are using java.lang.reflect api, please check your own code.
我的混淆器规则:
#--------Glide--------
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
#--------Glide transformations--------
-dontwarn jp.co.cyberagent.android.gpuimage.**
#--------Retrofit--------
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-dontwarn com.squareup.retrofit2.**
-dontwarn retrofit2.Platform$Java8
#--------Gson--------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
#--------ButterKnife--------
# Retain generated class which implement Unbinder.
-keep public class * implements butterknife.Unbinder { public <init>(**, android.view.View); }
# Prevent obfuscation of types which use ButterKnife annotations since the simple name
# is used to reflectively look up the generated ViewBinding.
-keep class butterknife.*
-keepclasseswithmembernames class * { @butterknife.* <methods>; }
-keepclasseswithmembernames class * { @butterknife.* <fields>; }
#--------MyCustomViews--------
-keep class com.app.app.view.** { *; }
-keep class com.app.app.api.models.** { *; }
-keep class java.lang.reflect.** { *; }
-keepclassmembers public class java.lang.reflect.**
如何修复它并保留 java.lang.reflect
?
请帮帮我
请帮帮我
问题不是您需要将 classes 保留在 java.lang.reflect
中,而是您的代码反射中的某处被用于加载、访问和可能修改 class es 在运行时。
因为 ProGuard 和其他混淆器重命名您的 classes 以使逆向工程更难,所以在字符串中使用硬编码的 classname 将会失败。例如考虑这个代码:
com.acme.Acme acme = Class.forName("com.acme.Acme").newInstance();
现在考虑在 com.acme.Acme
上 运行 Proguard 之后,它可能已重命名为 a.a.A
。该代码将有效地读取:
a.a.A acme = Class.forName("com.acme.Acme").newInstance();
这将在运行时导致 ClassNotFoundException
,这就是 ProGuard 会根据其配置发出警告或错误的原因。
解决方案是仔细调查您是否以及在何处可能在自己的代码中使用反射,是否可以避免该反射,是否可以忽略它,或者是否需要保留 classes 正在反映。
在我上面的示例中,您可以通过指定 -keepnames com.acme.Acme
来避免麻烦。如果反射用于检测 class 成员,您可能需要考虑 -keep
ing 整个 class 及其所有成员。
但本质上,根据定义混淆和反射并不能很好地混合。
获取运行时异常的原因可能因您实施的代码而异。 获得异常背后的原因之一可能是使用反射依赖代码中的 field/classes/method 名称 - ProGuard 在混淆时重命名您的 classes 因此为了在混淆后可以访问它们,它们需要明确防止混淆。
-keep app.package.FancyClass { *; }
如果是库本身导致混淆后的应用程序崩溃,那么我建议找到确切的位置并明确保留发生异常的 class 所依赖的 classes。
最简单的情况可能是保留整个库:
-keep com.stone.pile.** { *; }
但您通常可以将 ProGuard 配置得比这更激进。不过,这是一个很好的起点。
我认为 -keep java.lang.reflect.**
规则在这里没有多大帮助。根本原因在于代码依赖于 class 需要从混淆中排除的内部结构。
找到易受攻击的代码并尝试保持classes/methods/internals通过反射访问。
编辑: 如果您将 class 文件粘贴到抛出异常的位置,将会有很大的帮助。异常消息也会添加到上下文中。你能做到吗?