javaandroidreact-nativeruntime-errorexpo

java.lang.ClassNotFoundException: Didn't find class "eduapp.arg.MainApplication" on path: DexPathList


This is a react native application made first with expo and then ejected. When I want to perform the build it does not give any error but when installing and running it crashes, the app never always closes at once and shows an error.

Using the adb logcat tool to see the phone log and show me this:

Unable to instantiate application eduapp.arg.MainApplication: java.lang.ClassNotFoundException: Didn't find class "eduapp.arg.MainApplication" on path: DexPathList

08-07 02:32:48.585 10182 10182 E AndroidRuntime: FATAL EXCEPTION: main
08-07 02:32:48.585 10182 10182 E AndroidRuntime: Process: eduapp.arg, PID: 10182
08-07 02:32:48.585 10182 10182 E AndroidRuntime: java.lang.RuntimeException: Unable to instantiate application eduapp.arg.MainApplication: java.lang.ClassNotFoundException: Didn't find class "eduapp.arg.MainApplication" on path: DexPathList[[zip file "/data/app/eduapp.arg-FAa3-QgPlP0Ej-TLlvTegw==/base.apk"],nativeLibraryDirectories=[/data/app/eduapp.arg-FAa3-QgPlP0Ej-TLlvTegw==/lib/arm64, /data/app/eduapp.arg-FAa3-QgPlP0Ej-TLlvTegw==/base.apk!/lib/arm64-v8a, /system/lib64]]
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at android.app.LoadedApk.makeApplication(LoadedApk.java:1073)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5920)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at android.app.ActivityThread.access$1200(ActivityThread.java:200)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1673)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:106)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:201)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:6810)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
08-07 02:32:48.585 10182 10182 E AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "eduapp.arg.MainApplication" on path: DexPathList[[zip file "/data/app/eduapp.arg-FAa3-QgPlP0Ej-TLlvTegw==/base.apk"],nativeLibraryDirectories=[/data/app/eduapp.arg-FAa3-QgPlP0Ej-TLlvTegw==/lib/arm64, /data/app/eduapp.arg-FAa3-QgPlP0Ej-TLlvTegw==/base.apk!/lib/arm64-v8a, /system/lib64]]
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at android.app.AppComponentFactory.instantiateApplication(AppComponentFactory.java:50)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at androidx.core.app.CoreComponentFactory.instantiateApplication(CoreComponentFactory.java:47)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at android.app.Instrumentation.newApplication(Instrumentation.java:1121)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        at android.app.LoadedApk.makeApplication(LoadedApk.java:1065)
08-07 02:32:48.585 10182 10182 E AndroidRuntime:        ... 9 more
08-07 02:32:48.591  2038  3384 W ActivityManager:   Force finishing activity eduapp.arg/.MainActivity

Adb Log

Here I leave the Android Manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="eduapp.arg">
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  <uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
  <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  <uses-permission android:name="android.permission.USE_FINGERPRINT"/>
  <uses-permission android:name="android.permission.VIBRATE"/>
  <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  <uses-permission android:name="android.permission.CAMERA"/>
  <uses-permission android:name="android.permission.READ_CONTACTS"/>
  <uses-permission android:name="android.permission.READ_CALENDAR"/>
  <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
  <uses-permission android:name="android.permission.WAKE_LOCK"/>
  <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
  <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme">
    <meta-data android:name="expo.modules.updates.EXPO_UPDATE_URL" android:value="YOUR-APP-URL-HERE"/>
    <meta-data android:name="expo.modules.updates.EXPO_SDK_VERSION" android:value="37.0.0"/>
    <meta-data android:name="expo.modules.updates.ENABLED" android:value="true"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
    <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:screenOrientation="portrait">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
    </activity>
    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
    <activity
      android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
      android:theme="@style/Base.Theme.AppCompat">
    </activity>
  </application>
</manifest>

AndroidManifest

Here is the MainApplication.java

package com.frontendeduapp;

import android.app.Application;
import android.content.Context;
import android.net.Uri;

import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.facebook.react.BuildConfig;
import com.frontendeduapp.generated.BasePackageList;

import org.unimodules.adapters.react.ReactAdapterPackage;
import org.unimodules.adapters.react.ModuleRegistryAdapter;
import org.unimodules.adapters.react.ReactModuleRegistryProvider;
import org.unimodules.core.interfaces.Package;
import org.unimodules.core.interfaces.SingletonModule;
import expo.modules.constants.ConstantsPackage;
import expo.modules.permissions.PermissionsPackage;
import expo.modules.filesystem.FileSystemPackage;
import expo.modules.updates.UpdatesController;

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;

public class MainApplication extends Application implements ReactApplication {
  private final ReactModuleRegistryProvider mModuleRegistryProvider = new ReactModuleRegistryProvider(
    new BasePackageList().getPackageList()
  );

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      List<ReactPackage> packages = new PackageList(this).getPackages();
      packages.add(new ModuleRegistryAdapter(mModuleRegistryProvider));
      return packages;
    }

    @Override
    protected String getJSMainModuleName() {
      return "index";
    }

    @Override
    protected @Nullable String getJSBundleFile() {
      if (BuildConfig.DEBUG) {
        return super.getJSBundleFile();
      } else {
        return UpdatesController.getInstance().getLaunchAssetFile();
      }
    }

    @Override
    protected @Nullable String getBundleAssetName() {
      if (BuildConfig.DEBUG) {
        return super.getBundleAssetName();
      } else {
        return UpdatesController.getInstance().getBundleAssetName();
      }
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);
    initializeFlipper(this); // Remove this line if you don't want Flipper enabled

    if (!BuildConfig.DEBUG) {
      UpdatesController.initialize(this);
    }
  }

  /**
   * Loads Flipper in React Native templates.
   *
   * @param context
   */
  private static void initializeFlipper(Context context) {
    if (BuildConfig.DEBUG) {
      try {
        /*
         We use reflection here to pick up the class that initializes Flipper,
        since Flipper library is not available in release mode
        */
        Class<?> aClass = Class.forName("com.facebook.flipper.ReactNativeFlipper");
        aClass.getMethod("initializeFlipper", Context.class).invoke(null, context);
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      } catch (NoSuchMethodException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        e.printStackTrace();
      }
    }
  }
}

I leave the github link if you want to see the complete project.

https://github.com/SasePriv/FrontEnd-EduApp/tree/expo-eject


Solution

  • From the logs: Unable to instantiate application eduapp.arg.MainApplication: java.lang.ClassNotFoundException: Didn't find class "eduapp.arg.MainApplication" on path

    From the Android Developer docs, one of the uses for the package attribute in AndroidManifest is:

    ...to resolve any relative class names that are declared in the manifest file. For example, if package is set to "com.example.myapp", an activity declared as is resolved to be com.example.myapp.MainActivity

    So, your MainApplication is in package com.frontendeduapp, yet you defined the package in your AndroidManifest as eduapp.arg. So now when building your app, that value for package is used to turn your relative .MainApplication into eduapp.arg.MainApplication when really it should be com.frontendeduapp.MainApplication.

    Solution is to replace eduapp.arg with com.frontendeduapp in your AndroidManifest and rebuild.