14

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.

Edson Menegatti
  • 4,006
  • 2
  • 25
  • 40
Gooey
  • 4,740
  • 10
  • 42
  • 76
  • which proguard version you are using – amodkanthe May 08 '15 at 18:36
  • @apk, I have the version shipped with the latest release of AS. It is proguard version 4.7 – Gooey May 08 '15 at 18:44
  • Please do not edit your question to include a solution, instead post this as an answer (you can post answers to your own questions). – Philipp Wendler May 10 '15 at 10:23
  • No, me and Edson has a discussion on the chat and he had to leave at one point. Since he ran on version 0.10 and I am on 0.11, which requires different gradle statements, and the face that he was offline made me resume my answer in my post. He DID ANSWER the question and hence I accepted that answer and assigned the bounty. For convenience I added it to my post since I had gone trough the trouble of making it up-to-date. I consider it a pleasant thing. – Gooey May 10 '15 at 11:56

4 Answers4

6

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'
Edson Menegatti
  • 4,006
  • 2
  • 25
  • 40
  • Hmmm I get a different error now, about missing a .so file. Have you added additional jars? If I do so i get duplicate zip warnings in Proguard – Gooey May 08 '15 at 18:38
  • Did you added the natives prest files? If not, you need to add the following lines to the gradle file: compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '2.4.10-0.10', classifier: 'your_platform' compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '2.5.1-0.10', classifier: 'your_platform' – Edson Menegatti May 08 '15 at 18:45
  • So you do not include any addition jars? – Gooey May 08 '15 at 18:47
  • No, those line already do the job for you... Just try to get the most recent version of them. I'm still using 0.10, but I'm sure there are presets available for 0.11 – Edson Menegatti May 08 '15 at 18:48
  • Just another thing, so it doesn't get confusing. Replace "your_platform" with "android-arm" or "android-x86" depending on what your using or add lines for both of them based on what kind of hardware you want to support. – Edson Menegatti May 08 '15 at 18:53
  • Ah thanks for present info, I didn't try that before. I indeed use 0.11, so I'll try to find the presets for 0.11. – Gooey May 08 '15 at 18:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/77348/discussion-between-edson-menegatti-and-gooey). – Edson Menegatti May 08 '15 at 18:57
1

Maybe this can help.

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

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

-keepclasseswithmembernames class * {
    @org.bytedeco.* <methods>;
}
Sal
  • 1,230
  • 13
  • 21
1

The following could help:

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

You could use:

-keepattributes *Annotation*

-keep @org.bytedeco.javacpp.annotation.Platform interface * {
    *;
}
-keepclassmembers,allowobfuscation class * {
    @org.bytedeco.javacpp.annotation.Platform <fields>;
    @org.bytedeco.javacpp.annotation.Platform <init>(...);
}
ugo
  • 2,705
  • 2
  • 30
  • 34