Minie - Problem generating Android signed bundle

Ops, i forgot to do extractNativeLibs = true may be that was the issue, i will test it again later and report, btw if that is the case (aar doesn’t include the native files) then we can check them (on +ano @aar) by looking on bundled external libraries on the project palette on android studio.

1 Like

This is working for me:

plugins {
    id 'com.android.library'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        minSdkVersion 26
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {

    implementation("com.google.guava:guava:30.1.1-android")
    implementation 'com.jmedeisis:bugstick:0.2.2'

    implementation "org.jmonkeyengine:jme3-core:3.5.0-stable"
    implementation "org.jmonkeyengine:jme3-effects:3.5.0-stable"
    implementation "org.jmonkeyengine:jme3-android-native:3.5.0-stable"
    implementation 'com.github.stephengold:SkyControl:0.9.32'
    implementation group: 'commons-io', name: 'commons-io', version: '2.0.1'

    implementation 'com.github.stephengold:MaVehicles:0.7.0'
    implementation "com.github.stephengold:Minie:4.7.1+bare"
    implementation "com.github.stephengold:Minie:4.7.1+ano"

    implementation 'com.github.stephengold:Garrett:0.2.0'

    api 'com.simsilica:sim-math:1.4.1'
    api 'org.jmonkeyengine:jme3-terrain:3.5.0-stable'

    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
    //implementation fileTree(dir: 'C:\\dev\\SceneMax3DGameHub\\scenemaxeng\\libs', include: ['*.aar', '*.jar'], exclude: [])
    implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

1 Like

I do have:

android:extractNativeLibs="true"

in the Android manifest file

1 Like

I checked my external libraries and cannot find minie+ano @aar, only minie+bare :
image

It’s a typical dependency problem, i will try 4.9.0.

EDIT:
Cannot find it also with 4.9.0, it should be the same as jme3-android-natives module :

image

1 Like

Minie has no separate module for multithreading. NativeLibrary.countThreads() is implemented by the native function Java_com_jme3_bullet_util_NativeLibrary_countThreads (no final underscores). In single-threaded native libraries, Java_com_jme3_bullet_util_NativeLibrary_countThreads is hard-coded to return 1. All the published Android natives are single-threaded.

What’s special about countThreads()? It’s used in the BulletAppState constructor. So in most Minie apps, it’s the first native physics method invoked. So you must ensure that the native library gets loaded before any BulletAppState is instantiated. For example, the following code that works with with jme3-jbullet (and also with jme3-bullet and Minie v4.2) may fail with Minie v4.3 or higher:

public class Test extends SimpleApplication {
    static BulletAppState bulletAppState = new BulletAppState();
    static void main(String... args) {
        new Test().start();
    }
    //...

It will fail consistently on desktop (since jme3-desktop doesn’t load native libraries until start()). Its behavior on Android will depend on the order in which the static initializers execute.

Determining whether the native physics library is loaded is tricky on Android, because Android won’t issue a diagnostic if loadLibrary() fails:

TLDR: make sure the native library is loaded before instantiating the BulletAppState.

2 Likes

Try executing the “assemble” task instead of “build”. do u see any difference?

1 Like

I am just running on android studio, it dexes an app, assemble and launches the mainactivity…is there anything i am missing ?

I agree there is something weird with bundling of native “.so” files. I’m not 100% sure what the problem (and the resolution) is. Using bare+ano combo works for me but I’m not sure why? maybe it’s something with the gradle version??
I can send u a zoom link so u can review my project if it helps…

1 Like

I ran TestRigidBodyControl jMonkey example.

Hmm interesting, but i think that’s a conflict with android design though,

On Android to start a jme app, it’s done from android context (not controlled by the user) from AndroidHarness or JmeSurfaceView, both of which creates a context first using SystemDelegate then initializes the jme app and update and renderer starts…so i am not sure, this needs time for investigation…

The Static initializer is called before anything including Clazz.staticMethod() and Clazz clazz = new Clazz(); as there is no main method to rely on on android so we should omit this principle i think if we want to solve this problem…looking on the android sequence of running a jme app, i found the following sequence :

  1. Starts jme game.
  2. The start method → calls JmeAndroidSystem → creates a GL context.
  3. JmeSurfaceView/Harness takes the process and display onto the application.

So, here is my guess now : between step 1 and 2, there is a call to LegacyApplication#initialize() which calls my game simpleInit, so this call should be synchronized after step 2 (if you want to load the native bullet shared libs first)…step 2 is the step where the Static initializer is called…

Alright i tried this :

static {
    System.loadLibrary("bulletjme");
}

in my main class that loads the game, and i got the classical shared library exception :

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.scrappers.hellominie, PID: 13178
    java.lang.UnsatisfiedLinkError: dlopen failed: library "libbulletjme.so" not found
        at java.lang.Runtime.loadLibrary0(Runtime.java:1087)
        at java.lang.Runtime.loadLibrary0(Runtime.java:1008)
        at java.lang.System.loadLibrary(System.java:1664)
        at com.scrappers.hellominie.MainActivity.<clinit>(MainActivity.java:19)
        at java.lang.Class.newInstance(Native Method)
        at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
        at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1253)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3335)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7664)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

The native lib isn’t there, and as i mentioned here too :

1 Like

Could you please check +ano extension on your gradle external libraries on android studio, they should also have the native libs inside.

Can u instruct me exactly what to do in Android Studio?

1 Like

Check these :

1 Like

i think if it was libempty.so, android will never rejects it, but anyway this will pump the app with non-sense files and it may be a future problem.

The placeholder files did not have the “.so” extension, so I’d be surprised if they were mistaken for native libraries. And just to be safe, I removed the placeholders, effective with Minie version 4.7.1 …

1 Like

Android ensures all files under lib are shared object files in their respective architecture folder, doing empty only, android reads it as a violation (because it reserves the folder for natives only), but libempty.so or libbulletempty.so can trick the android system as if they are really object files…

1 Like

Thanks for the great videos.
I analyzed the AAB file created and found that everything is included as expected:

2 Likes

@Pavl_G I suggest it’s best for us to set a quick online meeting so we can think together what is the difference between my & your project and find the problem.

2 Likes

Thanks for testing !

Yeah, i agree, we may schedule a meeting if that error persists, and you right it seems a gradle problem, which gradle version are you using ? i am using gradle-6.5 for this project.

Today, i have checked the remote repository maven Sonatype (android native object “ano” jar file) at :

https://search.maven.org/remotecontent?filepath=com/github/stephengold/Minie/4.9.0+ano/Minie-4.9.0+ano.jar

And i found it viable and it has the android native shared object files at their respective arches.

So, i headed again to build.gradle, and i found something interesting, here is a video :

EDIT :
The whole trouble arises from using + sign within gradle !

2 Likes

I find that very surprising. According to the (unofficial) semantic versioning standard (https://semver.org/), “+” is used to distinguish different builds of a particular version.

So it seems like a bug in Gradle v6.5 . FYI, the latest release of Gradle is v7.4.2, and I’m using it without difficulties.

1 Like