Using Java reflection mechanism from within a JAR on Android - android

In my AndroidStudio project I want to use a JAR library that uses reflection mechanism to dynamically load a class and run its methods.
However, it fails to load the class and I'm getting the ClassNotFoundException.
When I try to load the class from within an activity -- it works.
It only fails when the system tries to load the class from within the library.
What is more, the library cannot load classes that are with the library, resulting in the same error.
Furthermore, I cannot load the classes from the library, even from the activity.
The class is loaded as follows:
Class<?> actionClass = Class.forName(callbackClass,true,ClassLoader.getSystemClassLoader());
The exception thrown looks as follows:
java.lang.ClassNotFoundException: demos.callbacks.GetDayOfAWeekCallback
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:324)
at com.example.tomek.test1.MainActivity.buttonOnClick(MainActivity.java:38)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.ClassNotFoundException: Didn't find class "demos.callbacks.GetDayOfAWeekCallback" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
... 14 more
Suppressed: java.lang.ClassNotFoundException: demos.callbacks.GetDayOfAWeekCallback
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 15 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available

OK, I have figured it out.
The problem was in using getSystemClassLoader.
Instead:
Class<?> actionClass = Class.forName(className,true,ClassLoader.getSystemClassLoader());
I used
Class<?> actionClass = Class.forName(className);
And it worked.
However it is still not perfectly clear to me why both of these methods works in desktop environment, and only the second one works in Android.

it's clear cause you use the jar ClassLoader which doesn't contain the class that you want to load. So to resolve this, you have to call your app ClassLoader.

Related

AWS Amplify Crashes on Android 6

I'm trying to use AWS amplify on android 6, but the app crashes suddenly after 30 seconds after the Configuration and gets this error.
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/time/LocalDateTime;
at com.amplifyframework.devmenu.PersistentLogger.addToLogs(PersistentLogger.java:116)
at com.amplifyframework.devmenu.PersistentLogger.debug(PersistentLogger.java:88)
at com.amplifyframework.logging.BroadcastLogger.debug(BroadcastLogger.java:101)
at com.amplifyframework.analytics.pinpoint.AutoEventSubmitter.lambda$new$0$AutoEventSubmitter(AutoEventSubmitter.java:44)
at com.amplifyframework.analytics.pinpoint.-$$Lambda$AutoEventSubmitter$kRbNZmP2XU9xJOUcrfJ3PKgcA28.run(lambda)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.os.HandlerThread.run(HandlerThread.java:61)
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.time.LocalDateTime" on path: DexPathList[[zip file "/data/app/com.nowpay.nowpay-1/base.apk"],nativeLibraryDirectories=[/data/app/com.nowpay.nowpay-1/lib/arm, /data/app/com.nowpay.nowpay-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at com.amplifyframework.devmenu.PersistentLogger.addToLogs(PersistentLogger.java:116) 
at com.amplifyframework.devmenu.PersistentLogger.debug(PersistentLogger.java:88) 
at com.amplifyframework.logging.BroadcastLogger.debug(BroadcastLogger.java:101) 
at com.amplifyframework.analytics.pinpoint.AutoEventSubmitter.lambda$new$0$AutoEventSubmitter(AutoEventSubmitter.java:44) 
at com.amplifyframework.analytics.pinpoint.-$$Lambda$AutoEventSubmitter$kRbNZmP2XU9xJOUcrfJ3PKgcA28.run(lambda) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:148) 
at android.os.HandlerThread.run(HandlerThread.java:61) 
Suppressed: java.lang.ClassNotFoundException: java.time.LocalDateTime
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 10 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
The basic problem here is that the app is trying to reference a class which doesn't exist at runtime:
java.lang.ClassNotFoundException: Didn't find class "java.time.LocalDateTime"
Initial runtime support for java.time.* was added to Android in API Level 26. For a period of time, java.time.* only worked on these devices.
As of Android Studio 4, java.time.* APIs can be "de-sugared" at build time. When using this functionality, the resulting code will run on all versions of Android. To benefit from this support, you must have Android Studio 4 or higher, and enable "core library desugaring." See the documentation for more details: https://developer.android.com/studio/write/java8-support#library-desugaring

The Firebase implementation within an AAR I'm using causes my App to crash

I had been contacted to put a new library in the form of an AAR into my application. It worked fine before adding this AAR, but after that, every time I start it up, it crashes with the following stacktrace:
09-10 21:10:55.272 10354-10354/? W/System.err: java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/tasks/TaskCompletionSource;
at com.google.firebase.remoteconfig.FirebaseRemoteConfig.zza(Unknown Source)
at com.google.firebase.remoteconfig.FirebaseRemoteConfig.fetch(Unknown Source)
at com.picmix.mobile.activity.SplashActivity.onCreate(SplashActivity.java:89)
at android.app.Activity.performCreate(Activity.java:6093)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2458)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2577)
at android.app.ActivityThread.access$1000(ActivityThread.java:164)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1462)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:160)
at android.app.ActivityThread.main(ActivityThread.java:5541)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.tasks.TaskCompletionSource" on path: DexPathList[[zip file "/data/app/com.picmix.mobile-2/base.apk"],nativeLibraryDirectories=[/data/app/com.picmix.mobile-2/lib/arm, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
... 16 more
Suppressed: java.lang.ClassNotFoundException: com.google.android.gms.tasks.TaskCompletionSource
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 17 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
From my experience, this kind of error is because I hadn't enabled MultiDex support. The strange thing is that I have it enabled, my gradle file contains the following line:
compile 'com.android.support:multidex:1.0.3'
The application I use in the manifest extends MultiDexApplication instead of just Application.
So is it something with that AAR?

MultiDex issue: java.lang.ClassNotFoundException: Didn't find class on path: DexPathList

I am facing an issue with my app:
If I deactivate within Android Studio Instant Run, my app crashes upon startup with the stacktrace:
12-29 13:36:37.876 4549-4549/com.mycoolapp.debug E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mycoolapp.debug, PID: 4549
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.mycoolapp.debug/com.myapp.SplashScreenActivity}: java.lang.ClassNotFoundException: Didn't find class "com.myapp.SplashScreenActivity" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/com.mycoolapp.debug-2/base.apk"],nativeLibraryDirectories=[/data/app/com.mycoolapp.debug-2/lib/arm, /vendor/lib, /system/lib]]
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2216)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365)
at android.app.ActivityThread.access$800(ActivityThread.java:148)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5272)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.myapp.SplashScreenActivity" on path: DexPathList[[zip file "/system/framework/android.test.runner.jar", zip file "/data/app/com.mycoolapp.debug-2/base.apk"],nativeLibraryDirectories=[/data/app/com.mycoolapp.debug-2/lib/arm, /vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at android.app.Instrumentation.newActivity(Instrumentation.java:1065)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2206)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365) 
at android.app.ActivityThread.access$800(ActivityThread.java:148) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5272) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704) 
Suppressed: java.lang.NoClassDefFoundError: com.myapp.SplashScreenActivity
at dalvik.system.DexFile.defineClassNative(Native Method)
at dalvik.system.DexFile.defineClass(DexFile.java:226)
at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:219)
at dalvik.system.DexPathList.findClass(DexPathList.java:321)
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:54)
... 14 more
Suppressed: java.lang.ClassNotFoundException: com.myapp.SplashScreenActivity
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 13 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
As far as I have researched this belongs to multidex:
https://developer.android.com/studio/build/multidex.html
Even if I add the multiDexEnabled property to my gradle config the app crashes. Only if I enable InstantRun (which enables multidex in background), the app runs...
If I create an apk the installation works, but the app crashes on startup with the same error.
Since I have as minSDK API Level 21, there should be no other change except of the multiDexEnabled property necessary, right?
So last but not least my answer:
All my configuration for multidex was correct... I don't know why, but after a complete OS restart everything works fine now... :)
Just create new phone on AVD and try to install app on that phone. Hope it will work.
The accepted answer was only a temporary fix for me, after altering code and a few builds the error came back.
After alot of trial and error the real problem was the jdk location my project was using, instead of using the embedded jdk in android studio i was using an installed version from oracle. After going to File > Project Structure > SDK Location and checking Use embedded JDK the problem was fixed for good.
Check if your classpath
'com.android.tools.build:gradle:3.1.0-alpha05'
is up-to-date, had same problem and solved it with a full update.

How to resolve ClassNotFoundException in Android Studio

I have recently migrated my project from Eclipse to Android Studio. Earlier everything was working perfectly, but recently when I started working on it again I am not able to launch the application. Its always showing me the same error. I haven't changed anything on application level, still getting the same result. Here is the log I am getting
FATAL EXCEPTION: main
Process: com.example.android, PID: 6977
java.lang.RuntimeException: Unable to instantiate application com.example.android.MobApplication: java.lang.ClassNotFoundException: Didn't find class "com.example.android.MobApplication" on path: DexPathList[[zip file "/data/app/com.example.android-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at android.app.LoadedApk.makeApplication(LoadedApk.java:601)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4919)
at android.app.ActivityThread.access$1500(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5721)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.android.MobApplication" on path: DexPathList[[zip file "/data/app/com.example.android-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at android.app.Instrumentation.newApplication(Instrumentation.java:986)
at android.app.LoadedApk.makeApplication(LoadedApk.java:587)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4919)
at android.app.ActivityThread.access$1500(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1424)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5721)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
Suppressed: java.lang.ClassNotFoundException: com.example.android.MobApplication
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 13 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
As I have recently switched my IDE I am facing problems to solve this one. I have also tried the other answers but still unable to solve this error. Kindly help me with this so I can proceed with my project.
Any help would be appreciable.
Thanks
This might be the 65k methods limit. Try to use the solutions in the link.
Edit: For others who stumble this issue - #Salman Khan added multiDexEnabled true to the gradle file (as written in the link) and it solved the problem. It would be still better to read the whole article and follow the steps there.
Replaced lambda with anonymous class:
java.lang.ClassNotFoundException happened in my android studio project in two classes – in both of them there was lambda expressions. After I replaced lambda with anonymous class – the build was successful.
In my case, I needed to edit from:
String id = MyClass.class.toString();
Into:
String id = MyClass.class.getName();
Because .toString() returns something like "class mypackage.MyClass" (instead of "mypackage.MyClass").

NoClassDefFoundError attempting to use FatSecret REST API in Android Studio

I am using the FatSecretAPI in order to retreive items from their database.
I have used this library - http://ranesr.github.io/fatsecret4j/ and done the following:
Created a new module in Android Studio as a new Java Library
Copied the relevant java files across as per the structure provided in the link
Located File > Project Structure... > Modules > my app > Dependencies and added the fatsecret module as a dependency
Called the FatSecretAPI class and instantiated with both my keys as per:
FatSecretAPI api = new FatSecretAPI("my auth key", "my shared key");
Cleaned and Rebuilt the project.
Upon running the app and opening the activity this call is in, I get the following error:
FATAL EXCEPTION: main
Process: com.example.chris.rapical, PID: 7140
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/fatsecret/platform/FatSecretAPI;
at com.example.chris.rapical.FoodSearchOnlineActivity.onCreate(FoodSearchOnlineActivity.java:51)
at android.app.Activity.performCreate(Activity.java:6500)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1120)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3072)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3218)
at android.app.ActivityThread.access$1000(ActivityThread.java:198)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1676)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6837)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.fatsecret.platform.FatSecretAPI" on path: DexPathList[[zip file "/data/app/com.example.chris.rapical-1/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at com.example.chris.rapical.FoodSearchOnlineActivity.onCreate(FoodSearchOnlineActivity.java:51) 
at android.app.Activity.performCreate(Activity.java:6500) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1120) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3072) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3218) 
at android.app.ActivityThread.access$1000(ActivityThread.java:198) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1676) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:6837) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199) 
Suppressed: java.lang.ClassNotFoundException: com.fatsecret.platform.FatSecretAPI
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 15 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
Things I have tried:
Cleaning and rebuilding the app
Deleting the /class folder and re-building
Running 'gradlew clean' on CMD at project location
All 3 have no successs.
Figured it out - When I was going to create the new Module, I selected Java library instead of Android library. Duh.

Categories

Resources