34

I'm converting my app to use gradle, and I'm trying to use the buildTypes. I have a Constants class which I wish to modify for my release build. So I have a file at src/main/java/my/package/name/Constants.java and at src/release/java/my/package/name/Constants.java.

When I try to build this, gradle tells me the build failed on the Constants file in my release buildtype, with the error that it's a duplicate class.

I also tried adding a different sourceSet for this in my build.gradle like this:

sourceSets {
    main {
        java.srcDirs = ['src/main/java'];
        //...
    }
    release {
        java.srcDirs = ['src/release/java'];
    }
}

But this still gives me the same error. So I'm wondering, what am I doing wrong here?

Arne517
  • 805
  • 2
  • 8
  • 14

2 Answers2

80

You can not have a class in main and release. You need to split it into something like debug and release.

gradle will merge the source sets for each buildType with main.
This is the reason, why the class gets duplicated in your release build.

So the rule is: put a class into main, or in every buildType but not both.

Adinia
  • 3,603
  • 5
  • 38
  • 56
flx
  • 13,818
  • 11
  • 51
  • 69
  • 2
    If one put class A in buildType paid and free, main complains about missing class A. How do one handle it? – powder366 Nov 24 '13 at 14:54
  • 1
    Documentation says it possible to override class with same package name and class name https://developer.android.com/tools/building/configuring-gradle.html#workBuildVariants but it's not working :( – jaumard Apr 01 '15 at 09:12
  • Unless I'm missing something, the docs say that you can have same class with same class name/ package name **if they are in different flavors**. Not so if one is in `main` and another is in a flavor. – tir38 Apr 20 '16 at 05:13
  • @tir38 The docs here are clear [about the flavors and duplicate classes](https://developer.android.com/studio/build/build-variants.html#sourceset-build). – miensol May 25 '16 at 14:54
  • 1
    Use dynamic class loading and an interface to load the class if it exists on the flavor. – Pellet Aug 30 '16 at 06:32
  • There are ways to replace the main sourceset(main dir) for different build types? – xxxzhi Nov 05 '16 at 03:24
0

The answer from "fix" helped me on the way, but I got an error from the main Gradle, saying a constant was missing (in my class Config). This since I had my class only in paid and free version and not in main. Could not find the Config class. Im not sure if this is a bug in Studio... I finally solved it with the following:

buildTypes {

    release {
        ...
        buildConfig "public static final boolean XYZ = false;"
    }

}

And the instead of using my Config.XYZ class constant I used buildConfig.XYZ

powder366
  • 3,907
  • 6
  • 44
  • 76