Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues in release build when minifyEnabled is set to true #739

Closed
ArmorDarks opened this issue Aug 15, 2018 · 27 comments · Fixed by #5048
Closed

Issues in release build when minifyEnabled is set to true #739

ArmorDarks opened this issue Aug 15, 2018 · 27 comments · Fixed by #5048
Labels
enhancement needs investigation needs further investigation before deciding platform: android

Comments

@ArmorDarks
Copy link

ArmorDarks commented Aug 15, 2018

Capacitor version

1.0.0-beta.4

Platform

Android

Issue

Strangely, many Capacitor elements behave differently in release build.

For instance, with debug we don't have any issues, while release builds getting few crashes during testing all the time:

image

For instance, my friend's Galaxy S6 Android 6.0 (debloated, not stock) always crashing on launch with release version, but not with debug.

Another issue with navigator.geolocation described in #738

And we noticed that for some reason Plugins.App.openUrl stops to work in release version. It just doing nothing.

I'm sure there also other issues specific to the release build. It makes me feel there some kind of global issue with release build in Capacitor.

What can I do to help debug those issues?

@ArmorDarks ArmorDarks changed the title Behavior differs in release and debug build versions Issues in release build Aug 15, 2018
@solojuve1897
Copy link
Contributor

solojuve1897 commented Aug 16, 2018

@ArmorDarks

"And we noticed that for some reason Plugins.App.openUrl stops to work in release version. It just doing nothing."

Interesting since I have an issue opened regarding openUrl.
#674

@ArmorDarks
Copy link
Author

@solojuve1897 did you try it with debug or release build? Our issue happens only with release

@solojuve1897
Copy link
Contributor

In release also

@ArmorDarks
Copy link
Author

Turned out that issues disappear if set in build.gradle minify to false.

I can only wonder why minification of the APK results in such issues.

@jcesarmobile
Copy link
Member

Are you talking about minifyEnabled? or just minify?
Default value for minifyEnabled in the template is false (https://github.com/ionic-team/capacitor/blob/master/android-template/app/build.gradle#L15)
Cordova has always had problems with minification/proguard, but not really sure why. But I don't think this is related to the Cordova compat as your problem was with Capacitor Plugins, not with Cordova ones.

@ArmorDarks
Copy link
Author

Yes, I meant minifyEnabled, sorry for the confusion.

We've set it to true because it was logical to do so, it just wasn't clear that it will lead to such issues.

But I don't think this is related to the Cordova compat as your problem was with Capacitor Plugins, not with Cordova ones.

yeap, we do not use any Cordova plugins. Only pure Capacitor, without any additions

@jcesarmobile jcesarmobile changed the title Issues in release build Issues in release build when minifyEnabled is set to true Aug 21, 2018
@jcesarmobile
Copy link
Member

It's probably related to minifyEnabled enabling proguard, which obfuscates the code and that can make the plugin execution code not work.
We can test this also setting minifyEnabled to true in debug mode too and then configure proguard to not obfuscate the classes related to plugin execution.

@nadhir-falta
Copy link

First, thank you Capacitor team for the amazing work you guys do!!
Secondly, I faced this issue last couple days, and the problem truly was minifyEnabled: true
setting that as false makes it all good.

@Rajarml
Copy link

Rajarml commented Mar 11, 2020

Here my proguard-rules.pro configuration which seems to ensure that any plugin is preserved during minification (tested with plugins: byteowls-capacitor-oauth2, capacitor-fcm, capacitor-secure-storage-plugin and those of capacitor-android):

-keep,allowobfuscation @interface com.getcapacitor.NativePlugin,com.getcapacitor.PluginMethod
-keep @com.getcapacitor.NativePlugin class * { *; }
-keepclasseswithmembernames class * {
  @com.getcapacitor.PluginMethod public *;
}

It could be put here and, as an embedded library proguard file, should be handled by any android/capacitor project.

Maybe it could be optimized but it does the job for me 😄!

@kyleabens
Copy link

kyleabens commented Oct 23, 2020

@Rajarml How would you allow for a Cordova plugin in proguard-rules.pro? Would adding this work?

-keep class org.apache.cordova.** { *; }
-keep public class * extends org.apache.cordova.CordovaPlugin

@distante
Copy link

distante commented Oct 26, 2020

@Rajarml How would you allow for a Cordova plugin in proguard-rules.pro? Would adding this work?

-keep class org.apache.cordova.** { *; }
-keep public class * extends org.apache.cordova.CordovaPlugin

I would also like to know this. I moved my project from Cordova to Capacitor and it is something like 2.5MB bigger than the Cordova version. I would really like to be able to enable minifying.

@Zapominacz
Copy link
Contributor

I had a similar issue. I mixed the above solutions to make my application work with the minifyEnabled. I will test this solution heavily.

Probably public <fields>; is not needed here. Thanks to specifying only public methods, the rest of the code is obfuscated.

-keep public class * extends org.apache.cordova.* {
    public <methods>;
    public <fields>;
}

-keep @com.getcapacitor.NativePlugin public class * {
    @com.getcapacitor.PluginMethod public <methods>;
}

@hschindler
Copy link

I have build problems too, with 'minifyEnabled=true'.

I working on Capacitor version 3 with Ionic (V5) and Angular (V11).

E/Capacitor: Error loading plugins. com.getcapacitor.q0: Could not find class by class path: com.capacitorjs.plugins.app.AppPlugin at com.getcapacitor.r0.a(Unknown Source:67) at com.getcapacitor.y.onStart(Unknown Source:18) at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1333) at android.app.Activity.performStart(Activity.java:6992) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2868) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2983) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1668) at android.os.Handler.dispatchMessage(Handler.java:108) at android.os.Looper.loop(Looper.java:206) at android.app.ActivityThread.main(ActivityThread.java:6760) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:845)

and than:

java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx/xxx.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void g.a.a.g.q(java.lang.String, g.a.a.e, g.a.a.j, g.a.a.h)' on a null object reference

@Zapominacz
Copy link
Contributor

Zapominacz commented Jun 7, 2021

Hi @hschindler

Native api in capacitor has changed.
For Capacitor v3 (ionic and angular version does not matter) with minifyEnabled true we should write in proguard-rules.pro:

-keep @com.getcapacitor.annotation.CapacitorPlugin public class * {
    @com.getcapacitor.PluginMethod public <methods>;
}

EDIT: Added directives for permissions and activities result:

-keep @com.getcapacitor.annotation.CapacitorPlugin public class * {
    @com.getcapacitor.annotation.PermissionCallback <methods>;
    @com.getcapacitor.annotation.ActivityCallback <methods>;
    @com.getcapacitor.PluginMethod public <methods>;
}

If older (v2) plugins are present, this also should be added:

-keep @com.getcapacitor.NativePlugin public class * {
    @com.getcapacitor.PluginMethod public <methods>;
}

And, if Cordova plugins are still present:

-keep public class * extends org.apache.cordova.* {
    public <methods>;
    public <fields>;
}

Tested on fresh project created with ionic cli with Capacitor v3, angular v12 and ionic v5

@Jesspu
Copy link

Jesspu commented Jun 24, 2021

@Zapominacz yep this works. Just upgraded our app from capacitor 2 to 3. Ran into the white screen of death when doing a release build on android with minifyEnabled. After updating the proguard-rules.pro with the v3 version, it now works fine.

@Jesspu
Copy link

Jesspu commented Jun 24, 2021

Hmm, the app builds, and the plugins work, but on fresh install, the app no longer prompts for permissions. The error I am seeing in logcat is There is no PermissionCallback method registered for the name: completeWatchPosition. Please define a callback method annotated with @PermissionCallback that receives arguments: (PluginCall)

If I set minifyEnabled false, it prompts for permissions as expected

@Zapominacz
Copy link
Contributor

Ok, it looks I need to add proguard directive for one more annotation - will look at it shortly

@Jesspu
Copy link

Jesspu commented Jun 24, 2021

So, it looks like if you manually request permissions for geolocation it works fine.

However, if you do NOT manually request, and try to use geolocation, it will just fail.

Looks like that is the same with file permissions. I have not tried manually requesting that yet, but guessing it will be the same.

So if minifyEnable is true, you want to make sure to manually request permissions.

If this can be resolved due to a proguard change, that would be preferable, just so you would not have to change any code, but it looks like there is a way around it.

@Jesspu
Copy link

Jesspu commented Jun 24, 2021

Looks like I found another one, looks like it may be multiple call back methods, not just related to permissions.

Just dropping this here as it may be relevant. This was triggered using capacitor camera plugin on capacitor 3, trying to select image from gallery.

There is no ActivityCallback method registered for the name: processPickedImage. Please define a callback method annotated with @ActivityCallback that receives arguments: (PluginCall, ActivityResult)

This was after manually requesting, and granting permissions.

@Zapominacz
Copy link
Contributor

Zapominacz commented Jun 24, 2021

@Jesspu This should do the job for v3 - I will test it soon. I forgot about two added annotations. @Permission probably can be omited.

Replace the "v3 part" of the solution above for this:

-keep @com.getcapacitor.annotation.CapacitorPlugin public class * {
    @com.getcapacitor.annotation.PermissionCallback <methods>;
    @com.getcapacitor.annotation.ActivityCallback <methods>;
    @com.getcapacitor.PluginMethod public <methods>;
}

@Zapominacz
Copy link
Contributor

Zapominacz commented Jun 24, 2021

Ok, i removed public constraint as these methods can be private. Tested on fresh project located here: https://github.com/Zapominacz/issue_capacitor_739 Hope it will work now :)

@Jesspu
Copy link

Jesspu commented Jun 24, 2021 via email

@Jesspu
Copy link

Jesspu commented Jun 25, 2021

@Zapominacz works great. Thanks so much!

@krisloekkegaard
Copy link

We still had issues with some plugins (e.g. Geolocation) after applying the fix suggested by @Zapominacz. Adding this line to our proguard-rules.pro fixed it:

-keep public class * extends com.getcapacitor.Plugin

So the full file looks like this:

-keep public class * extends com.getcapacitor.Plugin

-keep @com.getcapacitor.annotation.CapacitorPlugin public class * {
    @com.getcapacitor.annotation.PermissionCallback <methods>;
    @com.getcapacitor.annotation.ActivityCallback <methods>;
    @com.getcapacitor.PluginMethod public <methods>;
}

@lubomirblazekcz
Copy link

The proguard-rules should be added by default maybe? Or atleast added to the docs? Seems like a common issue on Android

@carlpoole
Copy link
Member

The proguard rules that were added to Capacitor should cover proguard issues with Capacitor core and the plugin interfaces. If we missed one of those plugin interfaces in the Core project then we could get that fixed. If there is a specific Capacitor core plugin that needs a rule added, we are interested in resolving that issue with a particular plugin in the https://github.com/ionic-team/capacitor-plugins repo, but this issue was focusing on addressing proguard rules for Capacitor core only.

-keep public class * extends com.getcapacitor.Plugin is a liberal rule that prevents any Capacitor plugin from being processed by proguard and is a heavy handed approach to preventing proguard issues in all plugins. If you are willing to add this to your project to avoid any proguard issues with any Capacitor plugin (core, community, or custom) and don't mind that any Plugin code will not be processed by proguard, then feel free to use it.

@ionitron-bot
Copy link

ionitron-bot bot commented Nov 10, 2022

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators Nov 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement needs investigation needs further investigation before deciding platform: android
Projects
None yet