Dakusan Dakusan - 11 months ago 47
Java Question

Gradle exclude java class from lib replaced by own class to avoid duplicate

In Android Studio, there is a specific file (

) that I need to overwrite from a package that is pulled in via Gradle (
dependencies {compile 'org.luaj:luaj-jse:3.0.1'}

I copied the file into my source directory with the exact same path and made my changes to it. This was working fine for an individual JUnit test case that was using it. It also looks like it is working for a normal compile of my project (unable to easily confirm at the moment).

However, when I try to run all my tests at once via a configuration of ProjectType="Android Tests", I get
Error:Error converting bytecode to dex:
Cause: com.android.dex.DexException: Multiple dex files define Lorg/luaj/vm2/lib/jse/JavaMethod$Overload;

Is there a specific task or command that I need to add to my Gradle file to make sure the project selects the file in my local source directory? I tried the Copy task and the
command, but neither seemed to work (I may have done them wrong). I also tried the "exclude module/group" directive under "compile" from this post.

The non-default settings for the Run/Debug Confirmation:

  • Type=Android Tests

  • Module=My module

  • Test: All in package

  • Package: "test"

All my JUnit test cases are in the "test" package.

Any answer that gets this to work is fine. If not Gradle, perhaps something in the android manifest or the local source file itself.

[Edit on 2016-07-24]
The error is also happening on a normal compile when my android emulator is running lower APIs. API 16 and 19 error out, but API 23 does not.


This is what I ended up adding after Fabio's suggestion:

//Get LUAJ
buildscript { dependencies { classpath 'de.undercouch:gradle-download-task:3.1.1' }}
apply plugin: 'de.undercouch.download'
task GetLuaJ {
    def JARDownloadURL='http://central.maven.org/maven2/org/luaj/luaj-jse/3.0.1/luaj-jse-3.0.1.jar' //compile 'org.luaj:luaj-jse:3.0.1'
    def BaseDir="$projectDir/luaj"
    def ExtractToDir='class'
    def ConfirmAlreadyDownloadedFile="$BaseDir/$ExtractToDir/lua.class"
    def JarFileName=JARDownloadURL.substring(JARDownloadURL.lastIndexOf('/')+1)
    def ClassesToDeleteDir="$BaseDir/$ExtractToDir/org/luaj/vm2/lib/jse"
    def ClassNamesToDelete=["JavaMethod", "LuajavaLib"]

    //Only run if LuaJ does not already exist
    if (!file(ConfirmAlreadyDownloadedFile).exists()) {
        //Download and extract the source files to /luaj
        println 'Setting up LuaJ' //TODO: For some reason, print statements are not working when the "copy" directive is included below
        mkdir BaseDir
        download {
            src JARDownloadURL
            dest BaseDir
        copy {

        //Remove the unneeded class files
        file(ClassesToDeleteDir).listFiles().each {
            if(it.getPath().replace('\\', '/').matches('^.*?/(?:'+ClassNamesToDelete+')[^/]*\\.class$')) {
                println "Deleting: $it"

I'll upload a version that works directly with the jar later.