Decouple NativeMap and NativeArray from reactnativejni (#50437)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/50437

Currently we do have `NativeArray`, `NativeMap` being tightly coupled with the old arch (i.e. everything inside `libreactnativejni.so`).
Those classes however are primitives used also by the New Arch and they should be accessible even without the bridge infra.

I've noticed this dependency while working on the Legacy Arch warnings.

Here I'm refactoring those primitives to live in a separate `libreactnativejni_common` module that can be loaded indipendently.

Changelog:
[Internal] [Changed] - Decouple NativeMap and NativeArray from `reactnativejni`

Reviewed By: javache, mdvacca

Differential Revision: D71635967

fbshipit-source-id: 64b0fc26491977a0e6c5be4688ff91969c81d680
This commit is contained in:
Nicola Corti
2025-04-03 06:49:59 -07:00
committed by Facebook GitHub Bot
parent adff5fcd35
commit 1786912263
9 changed files with 100 additions and 17 deletions
@@ -3554,6 +3554,7 @@ public final class com/facebook/react/soloader/OpenSourceMergedSoMapping : com/f
public final fun libreact_newarchdefaults_so ()I
public final fun libreactnative_so ()I
public final fun libreactnativeblob_so ()I
public final fun libreactnativejni_common_so ()I
public final fun libreactnativejni_so ()I
public final fun librninstance_so ()I
public final fun libturbomodulejsijni_so ()I
@@ -9,6 +9,7 @@ package com.facebook.react.bridge
import com.facebook.jni.HybridClassBase
import com.facebook.proguard.annotations.DoNotStripAny
import com.facebook.soloader.SoLoader
/**
* An implementation of [Dynamic] that has a C++ implementation.
@@ -45,4 +46,10 @@ private class DynamicNative : HybridClassBase(), Dynamic {
override fun recycle() {
// Noop - nothing to recycle since there is no pooling
}
private companion object {
init {
SoLoader.loadLibrary("reactnativejni_common")
}
}
}
@@ -9,6 +9,7 @@ package com.facebook.react.bridge
import com.facebook.jni.HybridClassBase
import com.facebook.proguard.annotations.DoNotStrip
import com.facebook.soloader.SoLoader
/** Base class for an array whose members are stored in native code (C++). */
@DoNotStrip
@@ -19,7 +20,7 @@ public abstract class NativeArray protected constructor() :
private companion object {
init {
BridgeSoLoader.staticInit()
SoLoader.loadLibrary("reactnativejni_common")
}
}
}
@@ -9,6 +9,7 @@ package com.facebook.react.bridge
import com.facebook.jni.HybridClassBase
import com.facebook.proguard.annotations.DoNotStrip
import com.facebook.soloader.SoLoader
/** Base class for a Map whose keys and values are stored in native code (C++). */
@DoNotStrip
@@ -17,7 +18,7 @@ public abstract class NativeMap : HybridClassBase() {
private companion object {
init {
BridgeSoLoader.staticInit()
SoLoader.loadLibrary("reactnativejni_common")
}
}
}
@@ -30,6 +30,7 @@ public object OpenSourceMergedSoMapping : ExternalSoMapping {
"react_newarchdefaults",
"reactnativeblob",
"reactnativejni",
"reactnativejni_common",
"rninstance",
"turbomodulejsijni",
"uimanagerjni",
@@ -68,6 +69,7 @@ public object OpenSourceMergedSoMapping : ExternalSoMapping {
"reactnative" -> libreactnative_so()
"reactnativeblob" -> libreactnativeblob_so()
"reactnativejni" -> libreactnativejni_so()
"reactnativejni_common" -> libreactnativejni_common_so()
"rninstance" -> librninstance_so()
"turbomodulejsijni" -> libturbomodulejsijni_so()
"uimanagerjni" -> libuimanagerjni_so()
@@ -109,6 +111,8 @@ public object OpenSourceMergedSoMapping : ExternalSoMapping {
public external fun libreactnativejni_so(): Int
public external fun libreactnativejni_common_so(): Int
public external fun librninstance_so(): Int
public external fun libturbomodulejsijni_so(): Int
@@ -214,6 +214,7 @@ add_library(reactnative
$<TARGET_OBJECTS:react_utils>
$<TARGET_OBJECTS:reactnativeblob>
$<TARGET_OBJECTS:reactnativejni>
$<TARGET_OBJECTS:reactnativejni_common>
$<TARGET_OBJECTS:reactperflogger>
$<TARGET_OBJECTS:rninstance>
$<TARGET_OBJECTS:rrc_image>
@@ -303,6 +304,7 @@ target_include_directories(reactnative
$<TARGET_PROPERTY:react_utils,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:reactnativeblob,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:reactnativejni,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:reactnativejni_common,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:reactperflogger,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:rninstance,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:rrc_image,INTERFACE_INCLUDE_DIRECTORIES>
@@ -8,7 +8,37 @@ set(CMAKE_VERBOSE_MAKEFILE on)
include(${REACT_COMMON_DIR}/cmake-utils/react-native-flags.cmake)
file(GLOB reactnativejni_SRC CONFIGURE_DEPENDS *.cpp)
file(GLOB reactnativejni_common_SRC CONFIGURE_DEPENDS *.cpp)
#############################
### reactnativejni_common ###
#############################
# This library contains the code from reactnativejni that is used by both old and new
# arch so it can be built in a separate library.
include(${REACT_ANDROID_DIR}/src/main/jni/first-party/jni-lib-merge/SoMerging-utils.cmake)
add_library(
reactnativejni_common
OBJECT
JDynamicNative.cpp
NativeArray.cpp
NativeCommon.cpp
NativeMap.cpp
OnLoad-common.cpp
ReadableNativeArray.cpp
ReadableNativeMap.cpp
WritableNativeArray.cpp
WritableNativeMap.cpp
)
target_merge_so(reactnativejni_common)
target_include_directories(reactnativejni_common PUBLIC ../../)
target_link_libraries(reactnativejni_common fbjni folly_runtime)
target_compile_reactnative_options(reactnativejni_common PRIVATE)
target_compile_options(reactnativejni_common PRIVATE -Wno-unused-lambda-capture)
######################
### reactnativejni ###
@@ -19,7 +49,25 @@ include(${REACT_ANDROID_DIR}/src/main/jni/first-party/jni-lib-merge/SoMerging-ut
add_library(
reactnativejni
OBJECT
${reactnativejni_SRC}
CatalystInstanceImpl.cpp
InspectorNetworkRequestListener.cpp
JExecutor.cpp
JInspector.cpp
JMessageQueueThread.cpp
JReactCxxErrorHandler.cpp
JReactMarker.cpp
JReactSoftExceptionLogger.cpp
JRuntimeExecutor.cpp
JRuntimeScheduler.cpp
JSLoader.cpp
JSLogging.cpp
JavaModuleWrapper.cpp
JniJSModulesUnbundle.cpp
MethodInvoker.cpp
ModuleRegistryBuilder.cpp
OnLoad.cpp
ReactInstanceManagerInspectorTarget.cpp
SafeReleaseJniRef.cpp
)
target_merge_so(reactnativejni)
@@ -35,6 +83,7 @@ target_link_libraries(reactnativejni
logger
react_cxxreact
react_renderer_runtimescheduler
reactnativejni_common
runtimeexecutor
yoga
)
@@ -0,0 +1,31 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <fbjni/fbjni.h>
#include "JCallback.h"
#include "JDynamicNative.h"
#include "NativeArray.h"
#include "NativeMap.h"
#include "WritableNativeArray.h"
#include "WritableNativeMap.h"
namespace facebook::react {
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
return facebook::jni::initialize(vm, [] {
JCxxCallbackImpl::registerNatives();
JDynamicNative::registerNatives();
NativeArray::registerNatives();
NativeMap::registerNatives();
ReadableNativeArray::registerNatives();
ReadableNativeMap::registerNatives();
WritableNativeArray::registerNatives();
WritableNativeMap::registerNatives();
});
}
} // namespace facebook::react
@@ -15,14 +15,10 @@
#include "CatalystInstanceImpl.h"
#include "CxxModuleWrapperBase.h"
#include "InspectorNetworkRequestListener.h"
#include "JCallback.h"
#include "JDynamicNative.h"
#include "JInspector.h"
#include "JReactMarker.h"
#include "JavaScriptExecutorHolder.h"
#include "ReactInstanceManagerInspectorTarget.h"
#include "WritableNativeArray.h"
#include "WritableNativeMap.h"
#ifndef WITH_GLOGINIT
#define WITH_GLOGINIT 1
@@ -44,17 +40,8 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
gloginit::initialize();
FLAGS_minloglevel = 0;
#endif
CatalystInstanceImpl::registerNatives();
CxxModuleWrapperBase::registerNatives();
JCxxCallbackImpl::registerNatives();
NativeArray::registerNatives();
ReadableNativeArray::registerNatives();
WritableNativeArray::registerNatives();
NativeMap::registerNatives();
ReadableNativeMap::registerNatives();
WritableNativeMap::registerNatives();
JDynamicNative::registerNatives();
JReactMarker::registerNatives();
JInspector::registerNatives();
ReactInstanceManagerInspectorTarget::registerNatives();