So i'm trying to load a class that i wrote from my application, but im receiving ClassNotFound exception.
class:
public class myclass{
public String doSomething()
{
return "Hello from myclass";
}
}
I than creates a jar file using the following commands:
javac myclass.java
jar cvf myclass.jar myclass.class
My next step is to creates a classes.dex for my jar file, and add it to the jar:
dx --dex --output=classes.dex myclass.jar
aapt add myclass.jar classes.dex
Untill now everything works great, no errors.
At the end of this step, my jar file is as follows:
myclass.jar
-> classes.dex
-> myclass.class
-> META-INF
-> MANIFEST.MF
My manifest file contains this lines:
Manifest-Version: 1.0
Created-By: 1.7.0_79 (Oracle Corporation)
Now inside my application i'm doing this:
private void activate()
{
try {
URL url;
final String libPath = Environment.getExternalStorageDirectory() + "/myclass.jar";
final File tmpDir = getDir("dex", 0);
final DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());
final Class<Object> classToLoad = (Class<Object>) classloader.loadClass("myclass");
final Object myInstance = classToLoad.newInstance();
final Method doSomething = classToLoad.getMethod("doSomething");
String result = (String)doSomething.invoke(myInstance);
Toast.makeText(MainActivity.this, String.valueOf(result), Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
Notes:
Environment.getExternalStorageDirectory()
directory and i confirmed that the application is reading the file correctly.
The line that gives me the error is:
final Class<Object> classToLoad = (Class<Object>) classloader.loadClass("myclass");
The error:
Didn't find class "myclass" on path: DexPathList[[zip file "/storage/emulated/0/myclass.jar"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
This are the suppressed exceptions:
java.io.IOException: No original dex files found for dex location /storage/emulated/0/myclass.jar
java.lang.ClassNotFoundException: Didn't find class "myclass" on path: DexPathList[[dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-support-annotations-23.3.0_d42c1a3ea55c8ce3f82fc6c8adde2e2271b97d01-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-slice_9-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-slice_8-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-slice_7-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-slice_6-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-slice_5-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-slice_4-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-slice_3-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-slice_2-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-slice_1-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-slice_0-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-internal_impl-23.3.0_75eb76bdd9c015b48a4280667bfd60eddc59734a-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-com.android.support-support-vector-drawable-23.3.0_0a5b88d45587f58c7ea931638fd9c9d6c4641bc7-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-com.android.support-support-v4-23.3.0_a0a32aaad2874bf2c15ffa67543dfe5af5b91a95-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-com.android.support-appcompat-v7-23.3.0_eae70f9c3956161dfb324670cb40cb42e6e1b16a-classes.dex", dex file "/data/data/hayzohar.testingclassloaders/files/instant-run/dex/slice-com.android.support-animated-vector-drawable-23.3.0_d4513d6bda757fa567bc4d7ea3e4bb7cbd09c077-classes.dex"],nativeLibraryDirectories=[/data/app/hayzohar.testingclassloaders-2/lib/x86, /vendor/lib, /system/lib]]
What am i doing wrong?
After some more digging with this code, i found out that the problem was the permissions. The emulator had Android 6 running on it, and the target sdk in the gradle file was set to 23, meaning we must request runtime permissions.
The bottom line, the problem was that there was no permission to read the file.
If someone is facing this issue and is running an emulator with android 6, Make sure you request Runtime permissions (manifest is not enough) or you could just set your target sdk to version 22 and below.