2

I have an existing Hybrid Remote app built with an older version of the SDK. I need to update it due to known vulnerabilities in the included version of Cordova. After experimenting with updating the existing app in place, I decided to just start fresh with a new forcehybrid project. After some work (outlined below), I am able to build a debug version of the app, which runs in the the emulator and on device successfully. However, when I try to build the release version, I get the following failure:

> Task :app:mergeDexRelease FAILED                                                                                 
D8: Program type already present: org.apache.cordova.AuthenticationToken                                    
com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:                    
Program type already present: org.apache.cordova.AuthenticationToken                                  
Learn how to resolve the issue at https://developer.android.com/studio/build/dependencies#duplicate_classes.                                                                                                                          
        at com.android.builder.dexing.D8DexArchiveMerger.getExceptionToRethrow(D8DexArchiveMerger.java:131)
        <SNIP>

I have reviewed the "learn how to resolve" link in the error message; it discusses having a dependency which is also included by another dependency. However, I'm unable to find such a dependency. Google has turned up a number of "Program type already present" errors, but they all seem to be specific to other libraries. I've tried building from command line and from Android Studio, with the same result. I've run the androidDependency gradle task from Android Studio, but cannot see a duplicated dependency. I have no idea how to determine which modules/plugins/whatever are trying to include org.apache.cordova.AuthenticationToken.

These are the steps I followed to get a working debug build:

  1. Installed latest Cordova (cordova --version reports 9.0.0 (cordova-lib@9.0.1))
  2. installed forcehybrid (forcehybrid@8.0.0)
  3. Created a new project with forcehyrbid.
  4. Added my existing bootconfig.xml and updated config.xml with settings from my existing project.
  5. Added cordova plugins. I went through the list of plugins in the old project and found the modern equivalents, nearly all cordova-plugin-X versions.
    • cordova-plugin-badge
    • cordova-plugin-calendar
    • cordova-plugin-camera
    • cordova-plugin-contacts
    • cordova-plugin-device
    • cordova-plugin-inappbrowser
    • cordova-plugin-network-information
    • cordova-plugin-splashscreen
    • cordova-plugin-statusbar
    • cordova-plugin-app-version
    • cordova-plugin-ionic-keyboard
    • phonegap-plugin-push@1.11.1 (to keep existing GCM config, this may not be needed/correct)
  6. Removed and re-added the MobileSDK Cordova Plugin as outlined in the docs after adding other plugins
  7. Updated icon & splash files, and added custom servers.xml file
  8. Updated icon names (via search/replace) from @drawable/sf__icon to @mipmap/ic_launcher, since I rely on cordova to create various sizes of icons from app/resources/icon, and I can't figure out how to change the generated file names. I've always had to do this in older builds as well.
  9. At this point, I thought I was ready, but I was getting some build errors regarding android support libraries; googling suggested adding the plugin cordova-plugin-androidx-adapter. This fixed the build errors. I then removed and re-added the MobileSDK Cordova Plugin again, and fixed the icon names again.
  10. At this point, the app would build, but would crash in the emulator. Debugging via Android Studio showed that the app couldn't find the SalesforceSDK module. A good bit of research and experimentation led to me updating platforms/android/project.properties to add android.library.reference.# entries for SalesforceAnalytics, SalesforceSDK, SmartStore, MobileSync, and SalesforceHybrid. Adding only SalesforceSDK (for example) led to another missing module; in the end I added them all. Prior to my changes, only CordovaLib and app (my app directory name) were included. With this change, I was able to build a working debug APK.
  11. I tried to build a release apk, and got the error found above. While researching, I found several different "Program type already present" error reports which were allegedly fixed by adding cordova-plugin-androidx and cordova-plugin-androidx-adapter. Since I had already added cordova-plugin-androidx-adapter, I went ahead and added cordova-plugin-androidx (and removed/re-added the SF Mobile plugin again), but it didn't change anything.

So at this point I can build the debug APK, but not the release APK. I cannot figure out how to track down the source of the error. How can I fix, or at least find the root cause?

0

I have found a solution. As I mentioned in step #10 above, in order to build a working app at all, I had to modify platforms/android/project.properties. It originally (as created by forcehybrid) contained two library references:

 android.library.reference.1=CordovaLib
 android.library.reference.2=app

This would build, but the app would crash; the log showed that the system couldn't locate the class com.salesforce.androidsdk.phonegap.app.HybridApp. Eventually I was able to build a debug apk that would run by adding the Salesforce modules to project.properties:

android.library.reference.1=CordovaLib
android.library.reference.2=SalesforceAnalytics
android.library.reference.3=SalesforceSDK
android.library.reference.4=SmartStore
android.library.reference.5=MobileSync
android.library.reference.6=SalesforceHybrid
android.library.reference.7=app

Eventually I suspected that the duplicate reference was caused by these references; I found that I could remove the reference to CordovaLib (I'm guessing SalesforceSDK already includes it) and successfully build (and run) both debug and release apks; my final library references are:

android.library.reference.1=SalesforceAnalytics
android.library.reference.2=SalesforceSDK
android.library.reference.3=SmartStore
android.library.reference.4=MobileSync
android.library.reference.5=SalesforceHybrid
android.library.reference.6=app
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.