viromedia / viro

ViroReact: AR and VR using React Native
MIT License
2.3k stars 482 forks source link

Unable to run android debug after attempt to integrate with existing project #402

Open alexborton opened 6 years ago

alexborton commented 6 years ago
  1. Development OS: Mac
  2. Device OS & Version: Android 7.0
  3. Version: Viro: 2.9.1. RN 0.55.3
  4. Device(s): Samsung Galaxy S7 edge

Description

I am trying to integrate Viro with my existing app for Android having already completed the integration with iOS (with a working example).

I have followed these instructions where applicable, but now get the following error when trying to compile Android debug;

To run dex in process, the Gradle daemon needs a larger heap.
It currently has 1024 MB.
For faster builds, increase the maximum heap size for the Gradle daemon to at least 3072 MB (based on the dexOptions.javaMaxHeapSize = 2560m).
To do this set org.gradle.jvmargs=-Xmx3072M in the project gradle.properties.
For more information see https://docs.gradle.org/current/userguide/build_environment.html

PARSE ERROR:
class name (com/google/ar/core/A) does not match path (com/google/ar/core/a.class)
...while parsing com/google/ar/core/a.class
PARSE ERROR:
class name (com/google/ar/core/B) does not match path (com/google/ar/core/b.class)
...while parsing com/google/ar/core/b.class
2 errors; aborting
:app:transformClassesWithDexForDebug FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:transformClassesWithDexForDebug'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException

The same error occurs during a release build.

My Gradle looks like this (android/app/build.gradle);

apply plugin: "com.android.application"
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
apply plugin: "com.google.firebase.firebase-perf"

import com.android.build.OutputFile

/**
 * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
 * and bundleReleaseJsAndAssets).
 * These basically call `react-native bundle` with the correct arguments during the Android build
 * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
 * bundle directly from the development server. Below you can see all the possible configurations
 * and their defaults. If you decide to add a configuration block, make sure to add it before the
 * `apply from: "../../node_modules/react-native/react.gradle"` line.
 *
 * project.ext.react = [
 *   // the name of the generated asset file containing your JS bundle
 *   bundleAssetName: "index.android.bundle",
 *
 *   // the entry file for bundle generation
 *   entryFile: "index.android.js",
 *
 *   // whether to bundle JS and assets in debug mode
 *   bundleInDebug: false,
 *
 *   // whether to bundle JS and assets in release mode
 *   bundleInRelease: true,
 *
 *   // whether to bundle JS and assets in another build variant (if configured).
 *   // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
 *   // The configuration property can be in the following formats
 *   //         'bundleIn${productFlavor}${buildType}'
 *   //         'bundleIn${buildType}'
 *   // bundleInFreeDebug: true,
 *   // bundleInPaidRelease: true,
 *   // bundleInBeta: true,
 *
 *   // whether to disable dev mode in custom build variants (by default only disabled in release)
 *   // for example: to disable dev mode in the staging build type (if configured)
 *   devDisabledInStaging: true,
 *   // The configuration property can be in the following formats
 *   //         'devDisabledIn${productFlavor}${buildType}'
 *   //         'devDisabledIn${buildType}'
 *
 *   // the root of your project, i.e. where "package.json" lives
 *   root: "../../",
 *
 *   // where to put the JS bundle asset in debug mode
 *   jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
 *
 *   // where to put the JS bundle asset in release mode
 *   jsBundleDirRelease: "$buildDir/intermediates/assets/release",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in debug mode
 *   resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in release mode
 *   resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
 *
 *   // by default the gradle tasks are skipped if none of the JS files or assets change; this means
 *   // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
 *   // date; if you have any other folders that you want to ignore for performance reasons (gradle
 *   // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
 *   // for example, you might want to remove it from here.
 *   inputExcludes: ["android/**", "ios/**"],
 *
 *   // override which node gets called and with what additional arguments
 *   nodeExecutableAndArgs: ["node"],
 *
 *   // supply additional arguments to the packager
 *   extraPackagerArgs: []
 * ]
 */

apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"

/**
 * Set this to true to create two separate APKs instead of one:
 *   - An APK that only works on ARM devices
 *   - An APK that only works on x86 devices
 * The advantage is the size of the APK is reduced by about 4MB.
 * Upload all the APKs to the Play Store and people will download
 * the correct one based on the CPU architecture of their device.
 */
def enableSeparateBuildPerCPUArchitecture = false

/**
 * Run Proguard to shrink the Java bytecode in release builds.
 */
def enableProguardInReleaseBuilds = false

android {
    compileSdkVersion rootProject.compileSdkVersion
    buildToolsVersion rootProject.buildToolsVersion

    def buildPropsFile = file('build.properties')

    def code = "1"

    if (buildPropsFile.canRead()) {
        def Properties buildProps = new Properties()

        buildProps.load(new FileInputStream(buildPropsFile))

        code = buildProps['BUILD_NUMBER'].toInteger() + 1
        buildProps['BUILD_NUMBER']=code.toString()
        buildProps.store(buildPropsFile.newWriter(), null)
    } else {
        throw new GradleException("Could not read build.properties!")
    }

    defaultConfig {
    applicationId project.env.get("BUNDLE_ID")
    minSdkVersion rootProject.minSdkVersion
    targetSdkVersion rootProject.targetSdkVersion
    versionCode code
    versionName project.env.get("VERSION_NUMBER")
    setProperty("archivesBaseName", "xx-xx-$versionName-$versionCode")
    ndk {
        abiFilters "armeabi-v7a", "x86"
    }
    multiDexEnabled true
    }

    dexOptions {
      javaMaxHeapSize "3584m"
      preDexLibraries = false
    }

    signingConfigs {
        release {
            storeFile file(MYAPP_RELEASE_STORE_FILE)
            storePassword MYAPP_RELEASE_STORE_PASSWORD
            keyAlias MYAPP_RELEASE_KEY_ALIAS
            keyPassword MYAPP_RELEASE_KEY_PASSWORD
        }
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86"
        }
    }
    buildTypes {
        debug {
            signingConfig signingConfigs.release
        }
        release {
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    }
    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
            def versionCodes = ["armeabi-v7a":1, "x86":2]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }
        }
    }
}

repositories {
    flatDir {
        dirs "../../node_modules/react-native-background-geolocation/android/libs"
    }
}

dependencies {
    compile "com.android.support:appcompat-v7:$rootProject.supportLibVersion"
    compile project(':react-native-code-push')
    compile project(':react-native-config')
    compile project(':react-native-audio-streamer')
    compile project(':react-native-device-info')
    compile project(':react-native-vector-icons')
    compile(project(':react-native-maps')){
        exclude group: 'com.google.android.gms', module: 'play-services-base'
        exclude group: 'com.google.android.gms', module: 'play-services-maps'
    }
    compile(project(':react-native-background-geolocation')) {
        exclude group: 'com.google.android.gms', module: 'play-services-location'
    }
    compile fileTree(dir: "libs", include: ["*.jar"])
    compile "com.facebook.react:react-native:+"  // From node_modules
    compile(project(':react-native-firebase')) {
    transitive = false
    }

    compile "com.google.firebase:firebase-core:11.8.0"
    compile "com.google.firebase:firebase-messaging:11.8.0"
    compile "com.google.firebase:firebase-crash:11.8.0"
    compile "com.google.firebase:firebase-perf:11.8.0"
    compile 'com.google.android.gms:play-services-base:11.8.0'
    compile 'com.google.android.gms:play-services-maps:11.8.0'
    compile 'com.google.android.gms:play-services-location:11.8.0'

    compile project(':gvr_common')
    compile project(':arcore_client')
    compile project(path: ':react_viro')
    compile project(path: ':viro_renderer')
    compile 'com.google.android.exoplayer:exoplayer:r2.2.0'
    compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7'
    compile 'com.amazonaws:aws-android-sdk-core:2.2.+'
    compile 'com.amazonaws:aws-android-sdk-ddb:2.2.+'
    compile 'com.amazonaws:aws-android-sdk-ddb-mapper:2.2.+'
    compile 'com.amazonaws:aws-android-sdk-cognito:2.2.+'
    compile 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.2.+'
}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

apply plugin: "com.google.gms.google-services"

Plus this build gradle (andoird/build.gradle);

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
        classpath 'com.google.gms:google-services:3.0.0'
        classpath 'com.google.firebase:firebase-plugins:1.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            url 'https://maven.google.com'
        }
         //start here
            configurations.all {
        resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        def requested = details.requested
            if (requested.group == 'com.google.android.gms') {
                details.useVersion '11.8.0'
            }
            if (requested.group == 'com.google.firebase') {
                details.useVersion '11.8.0'
                }
            }
            }
            //end
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
        maven {
            url "$rootDir/../node_modules/react-native-background-geolocation/android/libs"
       }
       maven {
           url "$rootDir/../node_modules/react-native-background-fetch/android/libs"
       }
    }
}

ext {
    minSdkVersion = 23
    compileSdkVersion   = 26
    targetSdkVersion    = 26
    buildToolsVersion   = "26.0.2"
    supportLibVersion   = "26.1.0"
    googlePlayServicesVersion = "11.0.4"
}
dthian commented 6 years ago

Hey @alexborton, thanks for reaching out.

Could you confirm the version number of arcore in the diectory "../node_modules/react-viro/android/arcore_client"? Ideally this should be core-1.3.0.aar. If they do match, then the classes that Android Studio is complaining about should be there and match.

After which, try cleaning and re-syncing your project.

If it still fails, then one possibility is that Android studio is running into dex issues resulting in incomplete compiled classes. Thus, those classes are incomplete and do not match, resulting in a build failure. Due to the I'm wondering if it's still because the heap size is still not large enough. If so could you try:


dexOptions {
    javaMaxHeapSize "4g"
    preDexLibraries = false
}

Looks like @variux encountered this issue as well here.

variux commented 6 years ago

Hi @dthian as I told in the last post the solution was to deactivate instant run, cause I didn't read carefully the instructions

alexborton commented 6 years ago

@dthian Thanks for your feedback.

arcore_client is core-1.4.0.aar

I'm sorry but i don't know what you mean by this part;

If they do match, then the classes that Android Studio is complaining about should be there and match

@variux is there a way of disabling instant run through the gradle/files rather than android studio as i am not using android studio.

I did manage to get builds running using Jack; i had to add the following to my build.gradle

defaultConfig {
    ...
    jackOptions {
        enabled true
    }
    ...
}
compileOptions {
  sourceCompatibility 1.8
  targetCompatibility 1.8
}

This does work but is very slow and it seems that Jack is deprecated.... If there is a better way then i would like to know it.

dam00n commented 6 years ago

@alexborton is there a reason you are not using Android Studio? We are not familiar with Jack and if it is deprecated not sure how much we can assist.

dthian commented 6 years ago

Hey @alexborton, that's interesting - it looks like you are using some java code that uses Java 8 APIs, potentially causing the build failure? Was the sourceCompatibility 1.8 options listed before when the build was failing? Also, does it work without Jack as Google mentions here?

chancehudson commented 6 years ago

@alexborton I was hitting the same issue in a project that previously had react-viro working. I downgraded to react-viro@2.6.1 and Android builds now work. Version 2.7 seems to introduce the issue.

VikAdvani commented 6 years ago

Hi @JChanceHud, @alexborton, Perhaps another thing to try is to upgrade your gradle plugin to 3.0.1.

So in your android/build.gradle change:

 classpath 'com.android.tools.build:gradle:2.2.3'

to:

 classpath 'com.android.tools.build:gradle:3.0.1'

As I understand gradle 3.0 supports Java 8, so if you use it, you shouldn't need Jack.

KirkBallou commented 5 years ago

This issue still exist in 2.11.0 on Android. Downgrading to 2.6.1 fixes it.. downside you get ARCore 1.1.0 and autofocus doesn't work for Android. @dthian @variux This is with instant run off & dexOptions { javaMaxHeapSize "4g" preDexLibraries = false } also tried jumboMode but no dice.

VikAdvani commented 5 years ago

Hi @KirkBallou, What gradle version are you using?

jdohgamer commented 5 years ago

@VikAdvani In reference to the question you asked @KirkBallou, we are currently on gradle version 3.0.1.