From a672eff6fa406a9b3097f43896b54136d3c06928 Mon Sep 17 00:00:00 2001 From: David Reiss Date: Tue, 2 Jul 2019 15:44:44 -0700 Subject: [PATCH] Add SoLoader flag to skip calling merged JNI_OnLoad Summary: `SoLoader.loadLibrary()` currently crashes if you attempt to load a merged library that does not define JNI_OnLoad. In the past, we've told people to work around this by just not calling `loadLibrary` for those libs. However, I'm about to land a cxx_library with no entry points, which will be loaded solely to ensure its static constructors are called. (Those static constructors register Caffe2 operators that are called later.) Add a flag for SoLoader to skip attempting to call JNI_OnLoad, which will be used for loading the operator library. Reviewed By: joelmccall Differential Revision: D14248187 fbshipit-source-id: 67f34b7f03754cc0c7fef05da64ff1701cf68ef7 --- java/com/facebook/soloader/SoLoader.java | 34 +++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/java/com/facebook/soloader/SoLoader.java b/java/com/facebook/soloader/SoLoader.java index b3573b4..c08d9ec 100644 --- a/java/com/facebook/soloader/SoLoader.java +++ b/java/com/facebook/soloader/SoLoader.java @@ -146,6 +146,14 @@ public class SoLoader { */ public static final int SOLOADER_DISABLE_BACKUP_SOSOURCE = (1 << 3); + /** + * Skip calling JNI_OnLoad if the library is merged. This is necessary for libraries that don't + * define JNI_OnLoad and are only loaded for their side effects (like static constructors + * registering callbacks). DO NOT use this to allow implicit JNI registration (by naming your + * methods Java_com_facebook_whatever) because that is buggy on Android. + */ + public static final int SOLOADER_SKIP_MERGED_JNI_ONLOAD = (1 << 4); + @GuardedBy("sSoSourcesLock") private static int sFlags; @@ -641,19 +649,21 @@ private static boolean loadLibraryBySoName( } } - boolean isAlreadyMerged = - !TextUtils.isEmpty(shortName) && sLoadedAndMergedLibraries.contains(shortName); - if (mergedLibName != null && !isAlreadyMerged) { - if (SYSTRACE_LIBRARY_LOADING) { - Api18TraceUtils.beginTraceSection("MergedSoMapping.invokeJniOnload[" + shortName + "]"); - } - try { - Log.d(TAG, "About to merge: " + shortName + " / " + soName); - MergedSoMapping.invokeJniOnload(shortName); - sLoadedAndMergedLibraries.add(shortName); - } finally { + if ((loadFlags & SOLOADER_SKIP_MERGED_JNI_ONLOAD) == 0) { + boolean isAlreadyMerged = + !TextUtils.isEmpty(shortName) && sLoadedAndMergedLibraries.contains(shortName); + if (mergedLibName != null && !isAlreadyMerged) { if (SYSTRACE_LIBRARY_LOADING) { - Api18TraceUtils.endSection(); + Api18TraceUtils.beginTraceSection("MergedSoMapping.invokeJniOnload[" + shortName + "]"); + } + try { + Log.d(TAG, "About to merge: " + shortName + " / " + soName); + MergedSoMapping.invokeJniOnload(shortName); + sLoadedAndMergedLibraries.add(shortName); + } finally { + if (SYSTRACE_LIBRARY_LOADING) { + Api18TraceUtils.endSection(); + } } } }