Skip to content

Install instructions out of date? Android runtime crash: java.lang.NoClassDefFoundError: Failed resolution of: Lno/fuse/rnunity/RNUnityManager #40

@markrickert

Description

@markrickert

I tried adding this library to my app using expo sdk 51 (react-native 0.75.5). I got iOS working pretty quickly but i'm struggling with the android integration. I am not using the new architecture.

After a lot of trial and error, i think i figured out that the instructions for integrating the library and .aar files are for an older version of gradle. The newest versions of react-native and expo are currently using gradle 8.8. So I asked ChatGPT to help me figure out the implementation and i was able to cobble together an expo plugin that would compile the app properly, however after metro would bundle the app, i'd get a runtime error and a react-native red screen:

java.lang.NoClassDefFoundError: Failed resolution of: Lno/fuse/rnunity/RNUnityManager;

Full Stacktrace:

ERROR Your app just crashed. See the error below.
java.lang.NoClassDefFoundError: Failed resolution of: Lno/fuse/rnunity/RNUnityManager;
no.fuse.rnunity.RNUnityPackage.createViewManagers(RNUnityPackage.java:22)
com.facebook.react.ReactInstanceManager.getOrCreateViewManagers(ReactInstanceManager.java:933)
com.swmansion.reanimated.ReanimatedPackage.createUIManager(ReanimatedPackage.java:78)
com.swmansion.reanimated.ReanimatedPackage.getModule(ReanimatedPackage.java:38)
com.facebook.react.BaseReactPackage$ModuleHolderProvider.get(BaseReactPackage.java:156)
com.facebook.react.BaseReactPackage$ModuleHolderProvider.get(BaseReactPackage.java:144)
com.facebook.react.bridge.ModuleHolder.create(ModuleHolder.java:186)
com.facebook.react.bridge.ModuleHolder.getModule(ModuleHolder.java:151)
com.facebook.react.bridge.NativeModuleRegistry.getModule(NativeModuleRegistry.java:148)
com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule(CatalystInstanceImpl.java:469)
com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule(CatalystInstanceImpl.java:445)
com.facebook.react.uimanager.UIManagerHelper.getUIManager(UIManagerHelper.java:88)
com.facebook.react.uimanager.UIManagerHelper.getUIManager(UIManagerHelper.java:46)
com.facebook.react.ReactInstanceManager.attachRootViewToInstance(ReactInstanceManager.java:1231)
com.facebook.react.ReactInstanceManager.setupReactContext(ReactInstanceManager.java:1180)
com.facebook.react.ReactInstanceManager.lambda$runCreateReactContextOnNewThread$1(ReactInstanceManager.java:1143)
com.facebook.react.ReactInstanceManager.$r8$lambda$FD-H2RG7CdgXPtYJUBikxLbd8MA(Unknown Source:0)
com.facebook.react.ReactInstanceManager$$ExternalSyntheticLambda4.run(Unknown Source:4)
android.os.Handler.handleCallback(Handler.java:959)
android.os.Handler.dispatchMessage(Handler.java:100)
com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
android.os.Looper.loopOnce(Looper.java:232)
android.os.Looper.loop(Looper.java:317)
com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:233)
java.lang.Thread.run(Thread.java:1012)
Caused by java.lang.ClassNotFoundException: no.fuse.rnunity.RNUnityManager
java.lang.VMClassLoader.findLoadedClass(Native Method)
java.lang.ClassLoader.findLoadedClass(ClassLoader.java:738)
java.lang.ClassLoader.loadClass(ClassLoader.java:363)
java.lang.ClassLoader.loadClass(ClassLoader.java:312)
no.fuse.rnunity.RNUnityPackage.createViewManagers(RNUnityPackage.java:22)
com.facebook.react.ReactInstanceManager.getOrCreateViewManagers(ReactInstanceManager.java:933)
com.swmansion.reanimated.ReanimatedPackage.createUIManager(ReanimatedPackage.java:78)
com.swmansion.reanimated.ReanimatedPackage.getModule(ReanimatedPackage.java:38)
com.facebook.react.BaseReactPackage$ModuleHolderProvider.get(BaseReactPackage.java:156)
com.facebook.react.BaseReactPackage$ModuleHolderProvider.get(BaseReactPackage.java:144)
com.facebook.react.bridge.ModuleHolder.create(ModuleHolder.java:186)
com.facebook.react.bridge.ModuleHolder.getModule(ModuleHolder.java:151)
com.facebook.react.bridge.NativeModuleRegistry.getModule(NativeModuleRegistry.java:148)
com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule(CatalystInstanceImpl.java:469)
com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule(CatalystInstanceImpl.java:445)
com.facebook.react.uimanager.UIManagerHelper.getUIManager(UIManagerHelper.java:88)
com.facebook.react.uimanager.UIManagerHelper.getUIManager(UIManagerHelper.java:46)
com.facebook.react.ReactInstanceManager.attachRootViewToInstance(ReactInstanceManager.java:1231)
com.facebook.react.ReactInstanceManager.setupReactContext(ReactInstanceManager.java:1180)
com.facebook.react.ReactInstanceManager.lambda$runCreateReactContextOnNewThread$1(ReactInstanceManager.java:1143)
com.facebook.react.ReactInstanceManager.$r8$lambda$FD-H2RG7CdgXPtYJUBikxLbd8MA(Unknown Source:0)
com.facebook.react.ReactInstanceManager$$ExternalSyntheticLambda4.run(Unknown Source:4)
android.os.Handler.handleCallback(Handler.java:959)
android.os.Handler.dispatchMessage(Handler.java:100)
com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
android.os.Looper.loopOnce(Looper.java:232)
android.os.Looper.loop(Looper.java:317)
com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:233)
java.lang.Thread.run(Thread.java:1012)
Caused by java.lang.NoClassDefFoundError: Failed resolution of: Lcom/unity3d/player/IUnityPlayerLifecycleEvents;
no.fuse.rnunity.RNUnityPackage.createViewManagers(RNUnityPackage.java:22)
com.facebook.react.ReactInstanceManager.getOrCreateViewManagers(ReactInstanceManager.java:933)
com.swmansion.reanimated.ReanimatedPackage.createUIManager(ReanimatedPackage.java:78)
com.swmansion.reanimated.ReanimatedPackage.getModule(ReanimatedPackage.java:38)
com.facebook.react.BaseReactPackage$ModuleHolderProvider.get(BaseReactPackage.java:156)
com.facebook.react.BaseReactPackage$ModuleHolderProvider.get(BaseReactPackage.java:144)
com.facebook.react.bridge.ModuleHolder.create(ModuleHolder.java:186)
com.facebook.react.bridge.ModuleHolder.getModule(ModuleHolder.java:151)
com.facebook.react.bridge.NativeModuleRegistry.getModule(NativeModuleRegistry.java:148)
com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule(CatalystInstanceImpl.java:469)
com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule(CatalystInstanceImpl.java:445)
com.facebook.react.uimanager.UIManagerHelper.getUIManager(UIManagerHelper.java:88)
com.facebook.react.uimanager.UIManagerHelper.getUIManager(UIManagerHelper.java:46)
com.facebook.react.ReactInstanceManager.attachRootViewToInstance(ReactInstanceManager.java:1231)
com.facebook.react.ReactInstanceManager.setupReactContext(ReactInstanceManager.java:1180)
com.facebook.react.ReactInstanceManager.lambda$runCreateReactContextOnNewThread$1(ReactInstanceManager.java:1143)
com.facebook.react.ReactInstanceManager.$r8$lambda$FD-H2RG7CdgXPtYJUBikxLbd8MA(Unknown Source:0)
com.facebook.react.ReactInstanceManager$$ExternalSyntheticLambda4.run(Unknown Source:4)
android.os.Handler.handleCallback(Handler.java:959)
android.os.Handler.dispatchMessage(Handler.java:100)
com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
android.os.Looper.loopOnce(Looper.java:232)
android.os.Looper.loop(Looper.java:317)
com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:233)
java.lang.Thread.run(Thread.java:1012)
Caused by java.lang.ClassNotFoundException: Didn't find class "com.unity3d.player.IUnityPlayerLifecycleEvents" on path: DexPathList[[zip file "/data/app/~~85NQTwgEsIMWF74L2osF1Q==/com.myapp.dev-LW0a1EufLb7G6FArPLCz1g==/base.apk"],nativeLibraryDirectories=[/data/app/~~85NQTwgEsIMWF74L2osF1Q==/com.myapp.dev-LW0a1EufLb7G6FArPLCz1g==/lib/arm64, /data/app/~~85NQTwgEsIMWF74L2osF1Q==/com.myapp.dev-LW0a1EufLb7G6FArPLCz1g==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]]
dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
java.lang.ClassLoader.loadClass(ClassLoader.java:379)
java.lang.ClassLoader.loadClass(ClassLoader.java:312)
no.fuse.rnunity.RNUnityPackage.createViewManagers(RNUnityPackage.java:22)
com.facebook.react.ReactInstanceManager.getOrCreateViewManagers(ReactInstanceManager.java:933)
com.swmansion.reanimated.ReanimatedPackage.createUIManager(ReanimatedPackage.java:78)
com.swmansion.reanimated.ReanimatedPackage.getModule(ReanimatedPackage.java:38)
com.facebook.react.BaseReactPackage$ModuleHolderProvider.get(BaseReactPackage.java:156)
com.facebook.react.BaseReactPackage$ModuleHolderProvider.get(BaseReactPackage.java:144)
com.facebook.react.bridge.ModuleHolder.create(ModuleHolder.java:186)
com.facebook.react.bridge.ModuleHolder.getModule(ModuleHolder.java:151)
com.facebook.react.bridge.NativeModuleRegistry.getModule(NativeModuleRegistry.java:148)
com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule(CatalystInstanceImpl.java:469)
com.facebook.react.bridge.CatalystInstanceImpl.getNativeModule(CatalystInstanceImpl.java:445)
com.facebook.react.uimanager.UIManagerHelper.getUIManager(UIManagerHelper.java:88)
com.facebook.react.uimanager.UIManagerHelper.getUIManager(UIManagerHelper.java:46)
com.facebook.react.ReactInstanceManager.attachRootViewToInstance(ReactInstanceManager.java:1231)
com.facebook.react.ReactInstanceManager.setupReactContext(ReactInstanceManager.java:1180)
com.facebook.react.ReactInstanceManager.lambda$runCreateReactContextOnNewThread$1(ReactInstanceManager.java:1143)
com.facebook.react.ReactInstanceManager.$r8$lambda$FD-H2RG7CdgXPtYJUBikxLbd8MA(Unknown Source:0)
com.facebook.react.ReactInstanceManager$$ExternalSyntheticLambda4.run(Unknown Source:4)
android.os.Handler.handleCallback(Handler.java:959)
android.os.Handler.dispatchMessage(Handler.java:100)
com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
android.os.Looper.loopOnce(Looper.java:232)
android.os.Looper.loop(Looper.java:317)
com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:233)
java.lang.Thread.run(Thread.java:1012)

Any clues or ideas on what might be happening here?

For reference, here is the expo config plugin i used to get the app working in react-native 0.74:

plugins/withUnityLibrary.ts
import { AndroidConfig } from "@expo/config-plugins";
import {
  ConfigPlugin,
  withAppBuildGradle,
  withProjectBuildGradle,
  withSettingsGradle,
  withStringsXml,
  withAndroidManifest,
  withGradleProperties,
} from "expo/config-plugins";

const withCustomSettingsGradle: ConfigPlugin = (config) => {
  return withSettingsGradle(config, (config) => {
    if (!config.modResults.contents.includes("unityLibrary")) {
      config.modResults.contents += `
include ':unityLibrary'
project(':unityLibrary').projectDir = new File('../unity/android')
      `;
    }
    return config;
  });
};

const withCustomAppBuildGradle: ConfigPlugin = (config) => {
  return withAppBuildGradle(config, (config) => {
    // Add flatDir repository for Unity .aar files
    if (!config.modResults.contents.includes("../unity/android")) {
      config.modResults.contents = config.modResults.contents.replace(
        /repositories\s*{/,
        `repositories {
    flatDir {
        dirs '../unity/android'
    }`,
      );
    }

    // Ensure the aar file is added to the existing dependencies block
    if (!config.modResults.contents.includes("../unity/android")) {
      config.modResults.contents = config.modResults.contents.replace(
        /dependencies\s*{/,
        `dependencies {
        implementation fileTree(dir: '../unity/android', include: ['*.aar'])
`,
      );
    }

    return config;
  });
};

const withCustomProjectBuildGradle: ConfigPlugin = (config) => {
  return withProjectBuildGradle(config, (config) => {
    // Ensure we modify the existing allprojects block instead of creating a new one
    config.modResults.contents = config.modResults.contents.replace(
      /allprojects\s*{[^}]*repositories\s*{[^}]*}/,
      (match) => {
        if (!match.includes("flatDir")) {
          return match.replace(
            /repositories\s*{/,
            `repositories {
      flatDir {
          dirs '../unity/android'
      }`
          );
        }
        return match; // No changes if flatDir is already present
      }
    );
    return config;
  });
};

const withCustomStringsXml: ConfigPlugin = (config) => {
  return withStringsXml(config, (config) => {
    config.modResults = AndroidConfig.Strings.setStringItem(
      [
        {
          _: "Game view",
          $: {
            name: "game_view_content_description",
          },
        },
        {
          _: "unity_root",
          $: {
            name: "unity_root",
          },
        },
      ],
      config.modResults
    );
    return config;
  });
};

const withCustomAndroidManifest: ConfigPlugin = (config) => {
  return withAndroidManifest(config, (config) => {
    const app = AndroidConfig.Manifest.getMainApplicationOrThrow(config.modResults);

    // Ensure android:extractNativeLibs is set to true in the <application> tag
    app.$['android:extractNativeLibs'] = 'true';

    // Find the MainActivity entry or add it if missing
    let mainActivity = AndroidConfig.Manifest.getMainActivity(config.modResults);
    if (!mainActivity) {
      mainActivity = {
        $: {
          'android:name': '.MainActivity',
        },
        'intent-filter': [],
      };
      app['activity'] = app['activity'] || [];
      app['activity'].push(mainActivity);
    }

    mainActivity.$['android:hardwareAccelerated'] = 'true';

    return config;
  });
};

const withCustomGradleProperties: ConfigPlugin = (config) => {
  return withGradleProperties(config, (config) => {
    const unityStreamingAssets = { key: 'unityStreamingAssets', value: '.unity3d' };

    const existingProperty = config.modResults.find((item) => item.key === unityStreamingAssets.key);
    if (!existingProperty) {
      config.modResults.push(unityStreamingAssets);
    }
    return config;
  });
};

// Main plugin function
export const withUnityLibrary: ConfigPlugin = (config) => {
  config = withCustomSettingsGradle(config);
  config = withCustomAppBuildGradle(config);
  config = withCustomProjectBuildGradle(config);
  config = withCustomStringsXml(config);
  config = withCustomAndroidManifest(config);
  config = withCustomGradleProperties(config);
  return config;
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions