Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proguard removing annotations in Android application

I have included a project using gradle in my app:

compile group: 'org.bytedeco', name: 'javacv', version: '0.11'

Which builds fine. But whenever I run the app with proguard enabled, it apparently removes the @Platform annotation from the jars that get included then.

I tried using the following based on http://proguard.sourceforge.net/manual/examples.html#annotations

-keepattributes *Annotation*

-keep @org.bytedeco.javacpp.annotation interface * {
    *;
}

I also tried the following based on http://proguard.sourceforge.net/manual/troubleshooting.html#notkept

-keep @interface *

But that doesn't work either. What else can I try to prevent proguard from removed these annotations? I was thinking about using -injars or -libraryjars but I believe gradle handles that for you.


The solution:

So the solution is as follows:

I have included the following in my proguard rules:

# JavaCV
-keep @org.bytedeco.javacpp.annotation interface * {
    *;
}

-keep @org.bytedeco.javacpp.annotation.Platform public class *

-keepclasseswithmembernames class * {
    @org.bytedeco.* <fields>;
}

-keepclasseswithmembernames class * {
    @org.bytedeco.* <methods>;
}

-keepattributes EnclosingMethod
-keep @interface org.bytedeco.javacpp.annotation.*,javax.inject.*

-keepattributes *Annotation*, Exceptions, Signature, Deprecated, SourceFile, SourceDir, LineNumberTable, LocalVariableTable, LocalVariableTypeTable, Synthetic, EnclosingMethod, RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations, AnnotationDefault, InnerClasses
-keep class org.bytedeco.javacpp.** {*;}
-dontwarn java.awt.**
-dontwarn org.bytedeco.javacv.**
-dontwarn org.bytedeco.javacpp.**

# end javacv

And the following lines in my gradle (these are the most recent versions at date 7/5/2015 (dd/mm/yyyy)):

compile group: 'org.bytedeco', name: 'javacv', version: '0.11'
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '2.4.11-0.11', classifier: 'android-arm'
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '2.4.11-0.11', classifier: 'android-x86'
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '2.6.1-0.11', classifier: 'android-arm'
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '2.6.1-0.11', classifier: 'android-x86'

I am quite sure that some proguard rules are a bit overkill, but I have not yet tested which are redundant. You may want to figure this out yourself if you run into this issue.

like image 964
Gooey Avatar asked May 06 '15 13:05

Gooey


People also ask

Does ProGuard remove unused classes?

ProGuard Facts:Helps to remove unused classes, members & fields. It removes unused codes from your libraries as well. (Which means, any method or field that is not referenced anywhere will be removed by ProGuard Shrinker). Helps to reduce the build size by obfuscating the classes, methods, & fields with short names.

Is minifyEnabled true?

Code shrinking with R8 is enabled by default when you set the minifyEnabled property to true .


2 Answers

I'm also using javacv and here's how my proguard file looks:

## JavaCV
-keepattributes *Annotation*, Exceptions, Signature, Deprecated, SourceFile, SourceDir, LineNumberTable, LocalVariableTable, LocalVariableTypeTable, Synthetic, EnclosingMethod, RuntimeVisibleAnnotations, RuntimeInvisibleAnnotations, RuntimeVisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations, AnnotationDefault, InnerClasses
-keep class org.bytedeco.javacpp.** {*;}
-dontwarn java.awt.**
-dontwarn org.bytedeco.javacv.**
-dontwarn org.bytedeco.javacpp.**

It may be somewhat excessive, but it is what finally got it working for me. Hope it helps you.

You also don't need to add any extra jar files if you add the following lines to your gradle file:

compile group: 'org.bytedeco.javacpp-presets', name: <module>, version: <module-version>, classifier: <your-platform>

To get the available modules, search for javacpp in jcenter and you'll see them as org.bytedeco.javacv-presets:<module>.

Clicking any of them will enable you to get the version that matches your javacv version. So if you're using javacv 0.11 and wants to add the opencv module, you'll need to use 2.4.11-0.11 version of the javacpp-preset.

Finally, just add the platform of your choice android-arm or android-x86 or both for that matter and you should be good to go.

Finally, as an example, here's the javacv import would look like for opencv and ffmpeg for the arm platform:

compile group: 'org.bytedeco', name: 'javacv', version: '0.11'
compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '2.4.11-0.11', classifier: 'android-arm'
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '2.6.1-0.11', classifier: 'android-arm'
like image 70
Edson Menegatti Avatar answered Oct 11 '22 16:10

Edson Menegatti


Maybe this can help.

-keep @org.bytedeco.javacpp.annotation.Platform public class *

-keepclasseswithmembernames class * {
    @org.bytedeco.* <fields>;
}

-keepclasseswithmembernames class * {
    @org.bytedeco.* <methods>;
}
like image 20
Sal Avatar answered Oct 11 '22 16:10

Sal