Error compiling because "The number of method references in a .dex file cannot exceed 64K."

Hi there.
I have this project which I use for some leds:

import java.io.File;
import android.os.Environment;
import android.Manifest; 
import android.os.Build;  
import processing.core.PConstants;
PImage img1;
PImage img2;
PImage img3;
PImage img4;
PImage img5;
PImage img6;
PImage img7;
PImage img8;
PImage img9;
PImage img10;
PImage img11;
String typing = "";
String saved = "";
boolean sett = false; 
String folder_name = "Tiraled";
String text_file = "mac.txt";
int si = 0;
int igri = 0;
String elstr="";
boolean keyboard = false;
boolean interm = false;
boolean error = false;
import ketai.net.bluetooth.*;
import android.os.Bundle;
String device_name = "ESP32";
String device_mac = "";
KetaiBluetooth bt;
void setup() {
  String[] lines = loadStrings("mac.txt");
  device_mac = lines.toString();
  img1 = loadImage("img1.png");
  img2 = loadImage("img2.png");
  img3 = loadImage("img3.png");
  img4 = loadImage("img4.png");
  img5 = loadImage("img5.png");
  img6 = loadImage("img6.png");
  img7 = loadImage("img7.png");
  img8 = loadImage("img8.png");
  img9 = loadImage("img9.png");
  img10 = loadImage("img10.png");
  img11 = loadImage("img11.png");
  fullScreen();
  orientation(LANDSCAPE); 
  noStroke();
  fill(0);
  bt = new KetaiBluetooth(this);
  bt.getPairedDeviceNames();
  bt.start();
  bt.connectToDeviceByName(device_name);
  String awewo = lines[0].toString();
  boolean porque = awewo.contains(":");
  if(porque){
    error=false;
  }
  else{
    error=true;
  }
  print(lines);
  print(porque);
  print(awewo);
}
/*String str = "igri";
      byte[] data = str.getBytes();
      bt.writeToDeviceName(device_name, data);
      delay(1000);
      background(255,0,0);
      image(led1, 670, 100,130,100);
*/

void draw(){
  if(!sett){
  drawmenu();}
  else{setting();}
  int indent = 25;
  if(mousePressed){
  si = mouseX;
  igri = mouseY;
  print(si," ",igri);
  matense(si,igri);
}
  }
void drawmenu(){
  if(error){
    background(255,0,0);
    text("No hay una direccion MAC puesta!",100,300);
    setting();
  }
  else{
  fill(255,255,255);
  background(75,59,59);
  textSize(60);
text("Control", 70, 70);
text("Paleta de colores", 500, 70);
text("Extras", 1200, 70);
  image(img1,100,80,130,130);
  image(img2,100,230,130,130);
  if(interm){
    image(img7,100,370,130,130);
  image(img8,100,510,130,130);
  }
  else{
  image(img3,100,370,130,130);
  image(img4,100,510,130,130);
  }
  image(img5,1200,80,130,130);
  image(img6,1200,230,130,130);
  image(img9,1200,370,130,130);
  image(img10,1200,510,130,130);
  image(img11,1400,30,100,100);
  fill(255,0,0);
  rect(350,80,130,130);
  fill(0,255,0);
  rect(350,230,130,130);
  fill(0,0,255);
  rect(350,370,130,130);
  fill(255,255,255);
  rect(350,510,130,130);
  //a
  fill(247,105,10);
  rect(490,80,130,130);
  fill(31,240,81);
  rect(490,230,130,130);
  fill(31,85,240);
  rect(490,370,130,130);

  //b
  fill(240,167,31);
  rect(630,80,130,130);
  fill(31,172,240);
  rect(630,230,130,130);
  fill(165,23,116);
  rect(630,370,130,130);
  //c
  fill(255,175,0);
  rect(775,80,130,130);
  fill(8,188,206);
  rect(775,230,130,130);
  fill(232,12,133);
  rect(775,370,130,130);

  //d
  fill(234,255,15);
  rect(915,80,130,130);
  fill(9,107,180);
  rect(915,230,130,130);
  fill(255,3,167);
  rect(915,370,130,130);
}
}

void matense(int x, int y){
  String str = "";
  if(x>=100 && x<=230){
  if(y>=80 && y<=220){str="a";}
  if(y>=230 && y<=360){str="b";}
  if(y>=370 && y<=500){if(interm){str="5";}else{str="c";}}
  if(y>=510 && y<=640){if(interm){str="7";}else{str="d";}}
}
  if(x>=490 && x<=620){
    interm = false;
  if(y>=80 && y<=220){str="e";}
  if(y>=230 && y<=360){str="f";}
  if(y>=370 && y<=500){str="g";}
  if(y>=510 && y<=640){str="h";}
}
  if(x>=630 && x<=760){
    interm = false;
  if(y>=80 && y<=220){str="i";}
  if(y>=230 && y<=360){str="j";}
  if(y>=370 && y<=500){str="k";}
  if(y>=510 && y<=640){str="l";}
}
  if(x>=775 && x<=905){
    interm = false;
  if(y>=80 && y<=220){str="m";}
  if(y>=230 && y<=360){str="n";}
  if(y>=370 && y<=500){str="o";}
  if(y>=510 && y<=640){str="p";}
}
  if(x>=915 && x<=1045){
    interm = false;
  if(y>=80 && y<=220){str="q";}
  if(y>=230 && y<=360){str="r";}
  if(y>=370 && y<=500){str="s";}
  if(y>=510 && y<=640){str="t";}
}
  if(x>=350 && x<=480){
    interm = false;
  if(y>=80 && y<=220){str="v";}
  if(y>=230 && y<=360){str="w";}
  if(y>=370 && y<=500){str="x";}
  if(y>=510 && y<=640){str="y";}
}
  if(x>=1200 && x<=1330){
    interm = true;
  if(y>=80 && y<=220){str="2";}
  if(y>=230 && y<=360){str="3";}
  if(y>=370 && y<=500){str="4";}
  if(y>=510 && y<=640){str="8";}
}
if(x>=1400 && x<=1500){
if(y>=30 && y<=130){
  sett = true;
}}
print(str);

      byte[] data = str.getBytes();
      bt.writeToDeviceName(device_name, data);
      delay(100);
}
void setting(){
  int indent = 25;
  fill(0,0,255);
  rect(230,80,815,560);
  fill(255,255,255);
  fill(255,255,0);
  rect(250,200,50,50);
  fill(0,255,0);
  rect(250,150,50,50);
  fill(255,0,0);
  rect(995,150,50,50);
  text("Configuracion",230,140);
  textSize(40);
  fill(0,255,0);
  text("Introduce la nueva Direccion MAC en \n minuscula para conectarse al ESP32. \n La MAC puede ser vista en el \n menu de la pantalla en 'CON' ",230,470);
  textSize(60);
  fill(255,255,255);
  text("Atras",900,600);
  text("Nueva mac: "+ saved,230,400);
  text("<-- Abrir teclado",300,250);
  text("<-- Borrar          Guardar -->",300,200);
  textSize(60);
  text("MAC:" + typing,230,300);
    if(mousePressed){
  si = mouseX;
  igri = mouseY;
}
if(mouseX >= 995 && mouseX <= 1040 && mouseY >= 150 && mouseY <= 200){
  String[] list = split(saved, ' ');

// Writes the strings to a file, each on a separate line
saveStrings("mac.txt", list);
  print("Guardado: "+list[0]);
  String[] sis = loadStrings("mac.txt");
  String awewo = sis[0].toString();
  print(awewo);

}
if (mouseX >= 250 && mouseX <= 300){
  if(mouseY >= 200 && mouseY <= 250){
    if (!keyboard) {
    openKeyboard();
    keyboard = true;   
  }
  }
  if(mouseY >= 150 && mouseY <= 200){
    typing = "";
    saved = "";
    mouseY = mouseY + 100;
  }
}
else {
    closeKeyboard();
    keyboard = false;
  }
if(si>=900&&si<=1045){
  if(igri>=580&&igri<=600){
    sett=false;
  }
}

}

void keyPressed() {
  // If the return key is pressed, save the String and clear it
  if (key == '\n' ) {
    String my_new_str = typing.replace(",", ":");
    saved = my_new_str;
    // A String can be cleared by setting it equal to ""
    typing = ""; 
  } else {
    // Otherwise, concatenate the String
    // Each character typed by the user is added to the end of the String variable.
    typing = typing + key; 
  }
}

And it was working and compiling without a problem a few days. However, today when I needed to make a correction and uploaded it again, it showed this:

> Task :app:mergeExtDexDebug FAILED
ERROR:D8: Cannot fit requested classes in a single dex file (# methods: 114913 > 65536)
com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
The number of method references in a .dex file cannot exceed 64K.
Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html
	at com.android.builder.dexing.D8DexArchiveMerger.getExceptionToRethrow(D8DexArchiveMerger.java:151)
	at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:138)
	at com.android.build.gradle.internal.tasks.DexMergingWorkAction.merge(DexMergingTask.kt:859)
	at com.android.build.gradle.internal.tasks.DexMergingWorkAction.run(DexMergingTask.kt:805)
	at com.android.build.gradle.internal.profile.ProfileAwareWorkAction.execute(ProfileAwareWorkAction.kt:74)
	at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:66)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:62)
	at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:97)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:62)
	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:79)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:79)
	at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
	at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:59)
	at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$2(DefaultWorkerExecutor.java:206)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:214)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:131)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:61)
	at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: com.android.tools.r8.CompilationFailedException: Compilation failed to complete, position: null
	at Version.fakeStackEntry(Version_3.1.51.java:0)
	at com.android.tools.r8.internal.oO0.a(SourceFile:68)
	at com.android.tools.r8.internal.oO0.a(SourceFile:28)
	at com.android.tools.r8.internal.oO0.a(SourceFile:27)
	at com.android.tools.r8.internal.oO0.b(SourceFile:3)
	at com.android.tools.r8.D8.run(D8.java:11)
	at com.android.builder.dexing.D8DexArchiveMerger.mergeDexArchives(D8DexArchiveMerger.java:136)
	... 35 more
Caused by: com.android.tools.r8.internal.b: Cannot fit requested classes in a single dex file (# methods: 114913 > 65536)
	at com.android.tools.r8.internal.il1.a(SourceFile:14)
	at com.android.tools.r8.internal.il1.a(SourceFile:22)
	at com.android.tools.r8.dex.T.a(SourceFile:58)
	at com.android.tools.r8.dex.O.a(SourceFile:7)
	at com.android.tools.r8.dex.e.a(SourceFile:14)
	at com.android.tools.r8.dex.e.c(SourceFile:36)
	at com.android.tools.r8.D8.d(D8.java:187)
	at com.android.tools.r8.D8.b(D8.java:1)
	at com.android.tools.r8.internal.oO0.a(SourceFile:24)
	... 38 more


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:mergeExtDexDebug'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.DexMergingTaskDelegate
   > There was a failure while executing work items
      > A failure occurred while executing com.android.build.gradle.internal.tasks.DexMergingWorkAction
         > com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives: 
           The number of method references in a .dex file cannot exceed 64K.
           Learn how to resolve this issue at https://developer.android.com/tools/building/multidex.html

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

Can someone explain me what is happening? Apparently, something is using more than the designated 64K on a .DEX file, but I dont have any idea of what that means, or what is a DEX file. Thanks for your help

Hi @a_random_cat,

I am not really familiar with this topic but you can take a look at the documentation link provided in the above error message:

Android app (APK) files contain executable bytecode files in the form of Dalvik Executable (DEX) files, which contain the compiled code used to run your app. The Dalvik Executable specification limits the total number of methods that can be referenced within a single DEX file to 65,536—including Android framework methods, library methods, and methods in your own code. In the context of computer science, the term Kilo, K, denotes 1024 (or 2^10). Because 65,536 is equal to 64 X 1024, this limit is referred to as the ‘64K reference limit’.

Also searching for previous threads on the forum that might help you solve your issue:

Hope it helps! :wink: