DexGuard version 7.0.19 throwring error "java.lang.NoSuchMethodError: No static method setAnnotationDatabasePackageNames" in RoboGuice. (Code working fine for DexGuard versions below 7).
I have tried followings in my dexguard-project.txt
-keepattributes *Annotation*
-keepclassmembers class com.google.inject.Guice {
public static void setAnnotationDatabasePackageNames(java.lang.String[]); }
-keep public class com.google.inject.Guice
Please Suggest.
Related
After a while trying some solutions here I'm still facing the problem of getting NullPointerException, apparently when using Jackson library, after trying to shrink my jar file using Proguard.
This is what I had defined to my Proguard config file:
-injars <my_raw_filejar>.jar
-outjars <shrunk_filejar>.jar
-libraryjars <JAVA_HOME>/lib/rt.jar
-keep public class packagename.MainClass{
public static void main(java.lang.String[]);
}
-keepnames class org.codehaus.jackson.** { *; }
-keepattributes *Annotation*
-keepattributes EnclosingMethod
-keepattributes Signature
-dontobfuscate
-optimizations !code/allocation/variable
-dontoptimize
-dontwarn
-ignorewarnings
But I'm getting the error below, once I run my generated shrunk jar:
Exception in thread "main" java.lang.ExceptionInInitializerError
at com.fasterxml.jackson.databind.ObjectMapper.<init>(ObjectMapper.java:535)
at com.fasterxml.jackson.databind.ObjectMapper.<init>(ObjectMapper.java:452)
at org.apache.beam.sdk.options.PipelineOptionsFactory.<clinit>(PipelineOptionsFactory.java:450)
at skry.tech.terbium.pipelines.TerbiumFeedBigTablePipeline.main(TerbiumFeedBigTablePipeline.java:30)
Caused by: java.lang.NullPointerException
at com.fasterxml.jackson.databind.cfg.MapperConfig.collectFeatureDefaults(MapperConfig.java:99)
at com.fasterxml.jackson.databind.cfg.MapperConfigBase.<clinit>(MapperConfigBase.java:31)
... 4 more
Is there any clue of what is happening and how to solve this error?
I had the same problem here.
Since the issue seemed to be based on an Enum being null. I added the following code to my proguard.conf
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
I am using ProGuard from the command line like this:
java -jar $PRO_GUARD_HOME/proguard.jar #proguard-rules.pro > usage.log
Here is my proguard-rules.pro rules file:
-injars build/libs/test-main-1.0.jar
-libraryjars /System/Library/Frameworks/JavaVM.framework/Classes/classes.jar
-dontoptimize
-dontobfuscate
-dontpreverify
-printusage
-dontnote
-keep public class com.foo.app.Main {
public static void main(java.lang.String[]);
}
-keepclassmembers class * {
static final % *;
static final java.lang.String *;
}
When I run the command above I get the following error:
Error: The output jar is empty. Did you specify the proper '-keep' options?
How do resolve this error?
Don't shrink library files. This worked for me;
# Keep - Library. Keep all public and protected classes, fields, and methods.
-keep public class * {
public protected <fields>;
public protected <methods>;
}
I'm using proguard to shrink a shaded jar for use as a command line tool. The shaded jar works fine but I'm getting an exception when running the jar created by proguard. The app uses Guice injection and I added configuration that I found on SO, mostly in this answer.
This is the Exception:
Exception in thread "main" java.lang.reflect.MalformedParameterizedTypeException
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.validateConstructorArguments(ParameterizedTypeImpl.java:60)
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.<init>(ParameterizedTypeImpl.java:53)
at sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.make(ParameterizedTypeImpl.java:95)
at sun.reflect.generics.factory.CoreReflectionFactory.makeParameterizedType(CoreReflectionFactory.java:105)
at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:140)
at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
at sun.reflect.generics.repository.ClassRepository.getSuperclass(ClassRepository.java:84)
at java.lang.Class.getGenericSuperclass(Class.java:696)
at com.google.inject.internal.MoreTypes.getGenericSupertype(MoreTypes.java:273)
at com.google.inject.TypeLiteral.getSupertype(TypeLiteral.java:257)
at com.google.inject.spi.InjectionPoint.hierarchyFor(InjectionPoint.java:755)
at com.google.inject.spi.InjectionPoint.getInjectionPoints(InjectionPoint.java:635)
at com.google.inject.spi.InjectionPoint.forInstanceMethodsAndFields(InjectionPoint.java:356)
at com.google.inject.internal.ConstructorBindingImpl.getInternalDependencies(ConstructorBindingImpl.java:151)
at com.google.inject.internal.InjectorImpl.getInternalDependencies(InjectorImpl.java:585)
at com.google.inject.internal.InjectorImpl.cleanup(InjectorImpl.java:543)
at com.google.inject.internal.InjectorImpl.initializeJitBinding(InjectorImpl.java:529)
at com.google.inject.internal.InjectorImpl.createJustInTimeBinding(InjectorImpl.java:847)
at com.google.inject.internal.InjectorImpl.createJustInTimeBindingRecursive(InjectorImpl.java:772)
at com.google.inject.internal.InjectorImpl.getJustInTimeBinding(InjectorImpl.java:256)
at com.google.inject.internal.InjectorImpl.getBindingOrThrow(InjectorImpl.java:205)
at com.google.inject.internal.InjectorImpl.getInternalFactory(InjectorImpl.java:853)
at com.google.inject.internal.FactoryProxy.notify(FactoryProxy.java:46)
at com.google.inject.internal.ProcessedBindingData.runCreationListeners(ProcessedBindingData.java:50)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:133)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106)
at com.google.inject.Guice.createInjector(Guice.java:95)
at com.google.inject.Guice.createInjector(Guice.java:72)
at com.google.inject.Guice.createInjector(Guice.java:62)
at com.acme.ui.cli.Main.main(Main.java:44)
And this the configuration that's producing it:
-injars acme-cli-0.2.1-SNAPSHOT.jar
-outjars target/acme-cli-0.2.1-SNAPSHOT.jar
-libraryjars /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre/lib/jce.jar
-libraryjars /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre/lib/jsse.jar
-libraryjars /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/jre/lib/rt.jar
-dontobfuscate
-dontpreverify
-dontoptimize
-printmapping mapping.map
-ignorewarnings
-keepattributes *Annotation*,Signature
# Keep - Applications. Keep all application classes, along with their 'main' methods.
-keep public class com.acme.ui.cli.Main {
public static void main(java.lang.String[]);
}
# Keep Guice-related classes
-keep public class javax.inject.**
-keep class com.google.inject**
-keep class * extends com.google.inject.AbstractModule
# keeps all fields and Constructors annotated with #Inject and #AssistedInject
-keepclasseswithmembers class * {
#com.google.inject.Inject <fields>;
#com.google.inject.Inject <init>(...);
}
-keepclasseswithmembers class * {
#com.google.inject.assistedinject.AssistedInject <fields>;
#com.google.inject.assistedinject.AssistedInject <init>(...);
}
When I add this the problem goes away:
-keep class * {
<init>(...);
}
But it keeps many more classes and doubles the size of the jar. I'm using proguard 4.10 and tried 4.9 too. These are some of the option I've experimented with that seemed most relevant:
-keepattributes *
-keepparameternames
-keep class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl {
<init>(...);
}
Since it's seems related to Guice and keeping all constructors solves the problem, I've also experimented with the various ways you can configure the keep options without results. But I must say that I don't understand them fully.
I'm not sure if it's related to the problem, but what looks odd is that the only constructor in the class ParameterizedTypeImpl has a signature like this: private ParameterizedTypeImpl(java.lang.Class<?> aClass, java.lang.reflect.Type[] types, java.lang.reflect.Type type), but the signature in the stacktrace looks like it's accepting ParameterizedTypeImpl itself: ParameterizedTypeImpl.<init>(ParameterizedTypeImpl.java:53).
Now I'm stuck; Any suggestions that could help me further are very appreciated.
This is a known bug that was fixed in Proguard 5.0. See https://sourceforge.net/p/proguard/bugs/518/
I have an app that uses ActiveAndroid, a database ORM library, that relies on annotations.
#Table(name="test")
public class DatabaseItem extends ActiveRecordBase<DatabaseItem> {
public DatabaseItem(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
#Column(name="counter")
public int counter;
}
How do I get Proguard working nicely with this? Currently, I get errors about not finding a column name by ActiveAndroid when using Proguard. I guess it somehow mangles the annotation.
My relevant Proguard configuration:
#ActiveAndroid
-keep public class com.activeandroid.**
-keep public class * extends com.activeandroid.ActiveRecordBase
-keepattributes Column
-keepattributes Table
Column and Table aren't existing java class file attributes. You'll at least have to specify
-keepattributes *Annotation*
Cfr. the ProGuard manual.
In March 2013, Proguard version 4.9 was released, one of the fixes were:
Fixed overly aggressive shrinking of class annotations.
So make sure that your Proguard version is up to date and then use Eric Lafortune's solution:
-keepattributes *Annotation*
You can also use this configuration to store all class members that has a specific annotation:
-keepclassmembers class * {
#fully.qualified.package.AnnotationType *;
}
Solution was to keep all members of the library and the database classes
-keep class com.activeandroid.**
{
*;
}
-keep public class my.app.database.**
{
*;
}
-keepattributes Column
-keepattributes Table
For those only using Gradle, the solution is very similar (note the single quotes around the Annotation):
keep 'public class java.package.** { *; }'
keepattributes '*Annotation*'
This is especially useful if you are using JSON serialization annotations (e.g., Jackson or the like) in a vanilla Gradle project.
This what worked in my case:
-keep class com.activeandroid.** { *; }
-keep class com.activeandroid.**.** { *; }
-keep class * extends com.activeandroid.Model
-keep class * extends com.activeandroid.serializer.TypeSerializer
-keep public class * extends com.activeandroid.ActiveRecordBase
-keepattributes Column
-keepattributes Table
-keepattributes *Annotation*
-keepclasseswithmembers class * { #com.activeandroid.annotation.Column <fields>; }
I use in my project a piece of code as described here
http://lexandera.com/2009/01/extracting-html-from-a-webview/
I create the .apk file, install it on my device and it correctly works. If I try to use the obfuscation with proguard the project fails, the method showHTML(String html) of MyJavaScriptInterface is not reached.
My proguard configuration regarding that
-keep public class com.mypackage.MyClass.MyJavaScriptInterface
-keep public class * implements com.mypackage.MyClass.MyJavaScriptInterface
-keepclassmembers class * implements com.mypackage.MyClass.MyJavaScriptInterface {
<methods>;
}
according to this this answer Android proguard Javascript Interface problem.
SOLVED.
As Eric suggested, I changed the Proguard configuration file like this:
-keep public class com.mypackage.MyClass$MyJavaScriptInterface
-keep public class * implements com.mypackage.MyClass$MyJavaScriptInterface
-keepclassmembers class com.mypackage.MyClass$MyJavaScriptInterface {
<methods>;
}
Now my project works perfectly.
For API 17+ you also need to preserve the #JavascriptInterface annotations:
-keepattributes JavascriptInterface
http://developer.android.com/reference/android/webkit/JavascriptInterface.html
If MyJavaScriptInterface is an inner class of MyClass, ProGuard expects a fully qualified name com.mypackage.MyClass$MyJavaScriptInterface. The naming convention with $ is used in the compiled class files on which ProGuard operates. Note that ProGuard mentions class names in the configuration that it can't find in the input jar, suggesting that these names may have been misspelled.
-keepclassmembers class com.mypackage.MyClass$JavaScriptInterface {
public *;
}
Use only this. It works for me.
Those Who are laze to provide the entire package path.
-keepclassmembers class **.*$PaymentJavaScriptInterface{
public *;
}
As suggested by edit in question,
out of those suggestions,
only using
-keepclassmembers class com.mypackage.MyClass$MyJavaScriptInterface {
public *;
}
with Important -
For API 17+ to preserve #JavascriptInterface annotations:
-keepattributes JavascriptInterface
(Which was stopping my app to work on Marshmallow)