"ClassNotFound" Exception while dynamically loading .dex file in Android

551 views Asked by At

I am trying to learn dynamically loading classes (.dex/.jar) in Android. I assembled the basic ideas from tutorials and Stack Overflow questions (tutorial, this, and this), but I am failing to fulfill my purpose of dynamically loading class files and constantly giving the ClassNotFound exception.

My steps in brief:

  1. Created a Java file as given in the article.

     public class DynamicClass {
         public static void main(String[] args){
             print();
         }
    
         public static void print() {
             System.out.println("Hello Dynamic");
         }
     }
    
  2. Converted java source to .class (result = DynamicClass.class)

     javac DynamicClass.java
    
  3. Created jar file using dx tool from Android SDK. (result = dynamic.jar with classes.dex in it)

     dx --dex --output=dynamic.jar DynamicClass.class
    

    Once I got the .jar file, I pushed it to /sdcard/ (tested on both, emulator as well as device)

    Emulator : Android 6.0 and Device : Android 11.0

    Brief code for loading the class:

     try {
             String dexPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "dynamic.jar";
             Log.d("DYNAMIC_TEST","dexPath: "+dexPath);
             final File tmpDir = getDir("dex", 0);
    
             // temporary file creation for .exists() check
             File dexFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "dynamic.jar");
    
             if (dexFile.exists()){ // dexFile location is same as dexPath location
                 Log.d("DYNAMIC_TEST", "File Found");
                 DexClassLoader dexClassLoader = new DexClassLoader(dexPath,
                         tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());
    
                 Class dynamicClass = dexClassLoader.loadClass("DynamicClass");
                 Method printMethod = dynamicClass.getMethod("print");
                 printMethod.invoke(dynamicClass.newInstance());
                 Log.d("DYNAMIC_TEST","Success");
             }
             else {
                 Log.d("DYNAMIC_TEST", "File NOT Found");
             }
    
         }catch (Exception e){
             Log.d("DYNAMIC_TEST", "Exception: "+ e.toString());
         }
    

I am constantly getting the ClassNotFound Exception.

What am I missing? Why is it that am not able to load this simple class file :(?

My checklist:

  1. Made sure that code is able to get the loaded file (<File>.exists()). Code is able to get the file. Only not able to load the class.
  2. Made sure dynamic.jar contains a classes.dex entry inside it. (This is because DexClassLoader wants a .jar/.apk file with the classes.dex entry in it)
  3. Tried running code on emulator as well as device (both having different Android versions).

Exception description:

Exception: java.lang.ClassNotFoundException: Didn't find class "DynamicClass" on path: DexPathList[[zip file "/storage/emulated/0/dynamic.jar"],nativeLibraryDirectories=[/system/lib64, /vendor/lib64]]

Exception after including package.

Exception: java.lang.ClassNotFoundException: Didn't find class "mypack.DynamicClass" on path: DexPathList[[zip file "/storage/emulated/0/mypack.jar"],nativeLibraryDirectories=[/system/lib64, /vendor/lib64]]

0

There are 0 answers