Hey there!
I noticed a documentation discrepancy in the UnrealPluginLanguage that seems to be introduced in UE 5.0 (still affects 5.7). `soLoadLibrary` should load the library before libUnreal.so but it appears that it’s loaded after. Is this intended? As an SDK author the order may be relevant.
Providing a bit of context, We are trying to fix the problem described in https://developer.android.com/ndk/guides/jni\-tips\#faq:\-why\-didnt\-findclass\-find\-my\-class where the wrong class loader is used on a background thread that’s attached to the JVM. Initially, we wanted to fix this by caching the application class loader in our own JNI_OnLoad. Currently, our plugin adds our SDK static libraries to PublicAdditionalLibraries with the build system merging them into libUnreal.so. This results in a duplicate symbol linker error as UnrealEngine already defines it.
The cleanest fix is to build our library as an .so instead of .a such that it’s packaged in the apk separately; libUnreal and libSdk.so both have their own JNI_OnLoad symbols. However, this would require quite a bit of work to change our build and publishing pipeline.
Hoping to avoid that, we chose to expose a new API that should be called before making any SDK API calls. This API calls across the JNI so we need to load the necessary native symbols beforehand. The problem is that on Android, we can have multiple components serve as an entry point to our app (e.g. BroadcastReceiver that is registered to respond to a notifications Intent) which may bypass GameActivity, meaning we have to load libUnreal ourselves.
- Can you confirm that this doesn’t violate any assumptions made by the engine?
- This is where the ordering kind of matters; if we subclass GameApplication and load libUnreal.so there (so it’s handled for all entry points), this invalidates what soLoadLibrary is intended for. If we still want to load a library before libUnreal.so, we have to do it in our Application class (see code snippet).
- Do you have any recommendations as to which direction to take here? Any other things to consider?
https://github.com/EpicGames/UnrealEngine/blob/4.18/Engine/Source/Programs/UnrealBuildTool/System/UnrealPluginLanguage.cs
* <!-- optional libraries to load in GameActivity.java before libUE4.so -->
* <soLoadLibrary> </soLoadLibrary>
https://github.com/EpicGames/UnrealEngine/blob/4.18/Engine/Build/Android/Java/src/com/epicgames/ue4/GameActivity.java
static
{
System.loadLibrary("gnustl_shared");
//$${soLoadLibrary}$$
System.loadLibrary("UE4");
}
https://github.com/EpicGames/UnrealEngine/blob/5.0/Engine/Source/Programs/UnrealBuildTool/System/UnrealPluginLanguage.cs
* <!-- optional libraries to load in GameActivity.java before libUnreal.so -->
* <soLoadLibrary> </soLoadLibrary>
https://github.com/EpicGames/UnrealEngine/blob/5.0/Engine/Build/Android/Java/src/com/epicgames/unreal/GameActivity.java.template
static
{
System.loadLibrary("Unreal");
//$${soLoadLibrary}$$
System.loadLibrary("c++_shared");
}
// Example integration
package com.ea.nimble.unreal.android.exampleapp;
import com.epicgames.unreal.GameApplication;
import com.my.package;
import android.util.Log;
public class DemoApplication extends GameApplication
{
@Override
public void onCreate()
{
super.onCreate();
MySdk.notifyApplicationCreated(getApplicationContext());
Log.d("DemoApplication", "Application created");
}
static {
// If I want to load something before libUnreal.so, it has to happen here.
System.loadLibrary("Unreal");
}
}
[Attachment Removed]