Skip to content

Known caveats

Gautam Korlam edited this page Jan 15, 2018 · 30 revisions

Dependency Conflicts

When trying to build android apps with the BUCK files generated by okbuck, you may sometime see errors during dexing

There was an error in smart dexing step.
com.facebook.buck.step.StepFailedException: Failed on step dx with an exception:
Multiple dex files define Lcom/foo/Bar;
com.android.dex.DexException: Multiple dex files define Lcom/foo/Bar;

or

There was an error in smart dexing step.
com.facebook.buck.step.StepFailedException: Program type already present: com.squareup.duktape.BuildConfig
  When running <d8>.
com.facebook.buck.step.StepFailedException: Program type already present: com.squareup.duktape.BuildConfig
  When running <d8>.

or when processing resources

buck-out/bin/.okbuck/cache/__unpack_com.android.support.appcompat-v7-25.4.0.aar#aar_unzip__/res/values/values.xml:73: Original attribute defined here.
buck-out/bin/.okbuck/cache/__unpack_com.android.support.appcompat-v7-23.1.1.aar#aar_unzip__/res/values/values.xml:85: error: Attribute "displayOptions" already defined with incompatible format.

This usually occurs when there are conflicting versions of external dependencies being used in various sub projects.

For example, there can an App A depend on two modules X and Y like so

A 
- X
|-- com.foo:bar:1.0
- Y
|-- com.foo:bar:1.1

Both X and Y depend on two different versions of com.foo:bar. This will lead to buck complaining that there are duplicate class entries in dex files. To workaround this, find which two dependencies are bringing in the same class by searching for the class com/foo/Bar in buck-out/**/*classes.txt files. This will give you an idea of where the dependency conflict is occurring. You can then pursue a few options like

  • Exclude com.foo:bar from being exported transitively to A and provide a version in A to satisfy the dependency
  • Edit X or Y to make the versions equal
  • Add forced versions in okbuck via
dependencies {
  forcedOkbuck "com.foo:bar:1.1"
}
  • If you have many sub projects relying on different versions, you can also do in your root project build.gradle for convenience. This is slower than the forced versions approach provided by okbuck as gradle performance tends to degrade with many dependency substitution rules
subprojects {
    project.configurations.all {
            resolutionStrategy {
                dependencySubstitution {
                    substitute module('com.foo:bar') with module('com.foo:bar:1.1')
                }
            }
        }
    }
}

This approach is flexible for having multiple versions of a dependency in multiple apps while preventing conflicts.

Butterknife

To use butterknife with buck, you need to use R2 instead of R in all (library & app) android gradle modules.

  • Apply the Butterknife Gradle Plugin
  • Change @BindView(R.id.foo) to @BindView(R2.id.foo).

AIDL

If you implement parcelable in your aidl, you need create a separate gradle library module containing those custom implementations, otherwise BUCK build will fail. See the example of common module and parcelable module.

IntelliJ Auto Generated Classes

In order to configure IntelliJ to set up a correct project with OkBuck, you'll need to apply a patch to buck and point your buck wrapper to it.

Apply the diff here: https://github.com/facebook/buck/issues/1156 Then add this inside the okbuck{} part of your build.gradle with the url of your buck fork.

wrapper {
  repo = 'https://github.com/facebook/buck.git'
}

Fabric

Fabric crash report gradle plugin will generate an unique uuid during the gradle build and will upload this uuid to its server. This uuid will be used at runtime of your application. More details can be found at #10. To work around it,

  • Do not use Fabric in debug builds i.e do not call Fabric.with(...) method
  • Use buck for debug builds and gradle for release builds

Could not resolve all dependencies for configuration

* What went wrong:
Execution failed for task ':setupOkbuck'.
> Could not resolve all dependencies for configuration ':buckLint_deps'.
   > Cannot resolve external dependency com.android.tools.lint:lint:25.3.2 because no repositories are defined.
     Required by:
         project :

This means that you likely need a repositories block in the root project project: which in this case is the root build.gradle where the okbuck plugin is applied. An example would be:

repositories {
  google()
  jcenter()
}

or

allprojects { 
  repositories {
    google()
    jcenter()
  }
}

this would not work because it doesn't add a repositories block to the root project

subprojects {
  repositories {
    google()
    jcenter()
  }
}

Other

  • Incompatible with AndroidAnnotations
  • Sub modules must be located inside root project dir