jMonkeyEngine / jmonkeyengine

A complete 3-D game development suite written in Java.
http://jmonkeyengine.org
BSD 3-Clause "New" or "Revised" License
3.83k stars 1.13k forks source link

AndroidNativeImageLoader failing to load #1294

Open MeFisto94 opened 4 years ago

MeFisto94 commented 4 years ago

I just tried to start a simple android test application, but the result I got was:

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.github.MeFisto94.android.jme3.test-1/base.apk"],nativeLibraryDirectories=[/data/app/com.github.MeFisto94.android.jme3.test-1/lib/x86, /system/lib, /vendor/lib]]] couldn't find "libdecodejme.so"
        at java.lang.Runtime.loadLibrary0(Runtime.java:984)
        at java.lang.System.loadLibrary(System.java:1530)
        at com.jme3.texture.plugins.AndroidNativeImageLoader.<clinit>(AndroidNativeImageLoader.java:23)
        at java.lang.Class.classForName(Native Method)
        at java.lang.Class.forName(Class.java:400)
        at java.lang.Class.forName(Class.java:326)
        at com.jme3.asset.AssetConfig.acquireClass(AssetConfig.java:62)
        at com.jme3.asset.AssetConfig.loadText(AssetConfig.java:86)
        at com.jme3.asset.DesktopAssetManager.loadConfigFile(DesktopAssetManager.java:96)
        at com.jme3.asset.DesktopAssetManager.<init>(DesktopAssetManager.java:89)
        at com.jme3.system.JmeSystemDelegate.newAssetManager(JmeSystemDelegate.java:125)
        at com.jme3.system.JmeSystem.newAssetManager(JmeSystem.java:139)
        at com.jme3.app.LegacyApplication.initAssetManager(LegacyApplication.java:216)
        at com.jme3.app.LegacyApplication.initialize(LegacyApplication.java:593)
        at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:197)
        at com.jme3.app.AndroidHarness.initialize(AndroidHarness.java:477)

TLDR: Something is wrong with the natives again, I guess. @riccardobl Do we need to do something more than just adding jme3-android as dependency? I've only found https://mvnrepository.com/artifact/org.jmonkeyengine/jme3-bullet-native-android but it shouldn't include the Image Loader.

Edit: Either this https://github.com/jMonkeyEngine/jmonkeyengine/tree/master/jme3-android-native should be a separate artifact or part of jme3-android as dependency (I strongly guess and suggest the latter), so I guess that's the problem already.

Certainly missing that in https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-android/build.gradle though.

Edit2:

Sorry for the misinformation

Actually there is a jme3-android-native artifact, but I don't think it's what we want, is it? Why would someone omit it? If someone wants to omit it, the AndroidNativeImageLoader needs to be shifted to that artifact, so that it's not visible for the DesktopAssetManager

stephengold commented 4 years ago

I always assumed jme3-android-native was separate because someone circa 2014 couldn't figure out how to combine Java and native code in a single Gradle subproject.

MeFisto94 commented 4 years ago

If that is the reason we either should merge them (but that breaks backwards compat) or at least move the NativeImageLoader there, then.

But since it seems to be impossible to load transparent images (I don't know what premultiplied alpha means, v.rgb = v.rgb * v.a?), then it should be even more part of jme3-android

stephengold commented 4 years ago

We could ask @normen about the reason, assuming he still exists.

normen commented 4 years ago

Why jme3-android-native is separate? Because we usually always separated native and java code afaicr. That way you could still use and build everything java without having native compilers, Android NDK and whatnot installed.

Or was that not the question? :)

MeFisto94 commented 4 years ago

That's question number one, yes :) Thanks for that! In the meantime our gradle workflow supports building by downloading prebuilt artifacts.

The question that is the result of this is now:

  1. Do we merge jme3-android-native into jme3-android?
  2. Do we declare jme3-android-native as a runtime dependency of jme3-android? (More backcompat and confusion)
  3. Do we continue like that and make Native Image Loading optional? (I bet in the last 5 years android has added a way to load images without the need of a native library, which is actually a maintenance effort for us)

Does anyone know about that "Premultiplied Alpha only"? @nickidebruyn maybe?

normen commented 4 years ago

Mhm, I'd vote for keeping it separate as well for those reasons. The native code might change, get deprecated, become platform dependent or something like that. This way it's easy to root out the cancer if it becomes malignant ;)

But my vote shouldn't count here anymore as I didn't follow the changes at all for at least a year, if not two. You know best what is what and what works these days.

But as always if you need any help when you end up in a dark corner of the codebase with only some //normen: TODO: WTF lines looking at you or something - I'm here :)

stephengold commented 4 years ago

Declaring jme3-android-native as a runtime dependency of jme3-android seems like the best solution for now.

MeFisto94 commented 4 years ago

Things to investigate: What does the NativeLoader talk about, is this still true in recent Android? Can we load RGBA Textures on Android at all when this Native Loader isn't available?

Because in addition to 2, we should probably still move the AndroidNativeImageLoader to jme3-android-native, so that just using jme3-android still works when android-native is explicitly removed, I guess

stephengold commented 4 years ago

If jme3-android-native is a dependency, then removing it would be an error (if you're not using Gradle) or very difficult (if you are).

MeFisto94 commented 4 years ago

Okay, that's true, but I think we can still move the file, specifically if we want to remove the jme3-android-native package in the future. What do you think about that?

stephengold commented 4 years ago

I believe the time to move the file is when the android-native package gets removed. One change, less confusion for users.

pavly-gerges commented 3 years ago

I just tried to start a simple android test application, but the result I got was:

java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.github.MeFisto94.android.jme3.test-1/base.apk"],nativeLibraryDirectories=[/data/app/com.github.MeFisto94.android.jme3.test-1/lib/x86, /system/lib, /vendor/lib]]] couldn't find "libdecodejme.so"
        at java.lang.Runtime.loadLibrary0(Runtime.java:984)
        at java.lang.System.loadLibrary(System.java:1530)
        at com.jme3.texture.plugins.AndroidNativeImageLoader.<clinit>(AndroidNativeImageLoader.java:23)
        at java.lang.Class.classForName(Native Method)
        at java.lang.Class.forName(Class.java:400)
        at java.lang.Class.forName(Class.java:326)
        at com.jme3.asset.AssetConfig.acquireClass(AssetConfig.java:62)
        at com.jme3.asset.AssetConfig.loadText(AssetConfig.java:86)
        at com.jme3.asset.DesktopAssetManager.loadConfigFile(DesktopAssetManager.java:96)
        at com.jme3.asset.DesktopAssetManager.<init>(DesktopAssetManager.java:89)
        at com.jme3.system.JmeSystemDelegate.newAssetManager(JmeSystemDelegate.java:125)
        at com.jme3.system.JmeSystem.newAssetManager(JmeSystem.java:139)
        at com.jme3.app.LegacyApplication.initAssetManager(LegacyApplication.java:216)
        at com.jme3.app.LegacyApplication.initialize(LegacyApplication.java:593)
        at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:197)
        at com.jme3.app.AndroidHarness.initialize(AndroidHarness.java:477)

TLDR: Something is wrong with the natives again, I guess. @riccardobl Do we need to do something more than just adding jme3-android as dependency? I've only found https://mvnrepository.com/artifact/org.jmonkeyengine/jme3-bullet-native-android but it shouldn't include the Image Loader.

Edit: Either this https://github.com/jMonkeyEngine/jmonkeyengine/tree/master/jme3-android-native should be a separate artifact or part of jme3-android as dependency (I strongly guess and suggest the latter), so I guess that's the problem already.

Certainly missing that in https://github.com/jMonkeyEngine/jmonkeyengine/blob/master/jme3-android/build.gradle though.

Edit2:

Sorry for the misinformation

Actually there is a jme3-android-native artifact, but I don't think it's what we want, is it? Why would someone omit it? If someone wants to omit it, the AndroidNativeImageLoader needs to be shifted to that artifact, so that it's not visible for the DesktopAssetManager

Are you using mavenLocal(); because seems that decode.gradle cannot locate the deocde module , the decode native module need to be located through the buildDir or getBuildDir() so that all the files inside that module gets copied to the jme3-android module jni folder :

https://github.com/jMonkeyEngine/jmonkeyengine/blob/1a42b212b967b41f94c18690c43a549e27a1dcda/jme3-android-native/decode.gradle#L5

https://github.com/jMonkeyEngine/jmonkeyengine/blob/1a42b212b967b41f94c18690c43a549e27a1dcda/jme3-android-native/decode.gradle#L56

So. i think the problem was mainly here in ${buildDir} is not outputing good reference to the local disk build directories.

i was having the same problem though , but it gets fixed when i referred to jme3-android-native remote repositories instead of local ones :

https://hub.jmonkeyengine.org/t/solved-snapshot-leads-to-some-troubles-on-android/44438?u=pavl_g

pavly-gerges commented 3 years ago

@riccardobl Do we need to do something more than just adding jme3-android as dependency?

Actually there is a jme3-android-native artifact, but I don't think it's what we want, is it?

The answer of these questions is fairly simple , due to chained inclusion of jme3-android java module inside jme3-android-native native module , you can simply remove jme3-android & add only jme3-android-native & jme3-android would be included directly by the fact that jme3-android-native already uses it.

There would be also no problem if you add both.

The problem here is with implementation "org.jmonkeyengine:jme3-android-native:3.4.0-SNAPSHOT" which is mavenLocal();.

Ali-RS commented 3 years ago

Can we load RGBA Textures on Android at all when this Native Loader isn't available?

It should be possible with AndroidBufferImageLoader in jme3-android that uses Android's Bitmap class to load images.

https://github.com/jMonkeyEngine/jmonkeyengine/blob/9cb633d6a1eae3d36d503b58e327e50cd0dd9a0d/jme3-android/src/main/java/com/jme3/texture/plugins/AndroidBufferImageLoader.java#L54

stephengold commented 3 years ago

Trying to summarize...

The actual issues here seem to be documentation issues:

pavly-gerges commented 3 years ago
  • Document how to build JME applications for Android: what dependencies are needed.

If you would like to have some basic very simple jme examples on jme3-android examples let me know , I can prepare an example for each class , the current examples :

They are basically an Activity(Android Container Screen) with a list to choose which testCase from jme3-tests you want to run , then when one item is chosen , the package is assigned through the jme-FragmentHarness & jme3 game starts(very complicated for the first look , is not it?,but stills great for jme3 android massive classes integrations). https://github.com/jMonkeyEngine/jmonkeyengine/tree/master/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples

Are great , but they focus mainly on android(that's a little bit trivial) not jme very much , I think having simpler examples would be good.

  • Document how to deploy the jme3-android-native library to MavenLocal

I cannot understand what was the problem with this , could you illustrate more , please.

stephengold commented 3 years ago

Additional Android examples would be welcome. Probably they should go in the jme3-android-examples folder/directory.

To install jme3-android-native to MavenLocal: ./gradlew :jme3-android-native:install

stephengold commented 3 years ago

I don't understand the question. Please elaborate.

pavly-gerges commented 3 years ago

I don't understand the question. Please elaborate.

Android Applications Modules are different Android packages , so users when they clone , they could select each one independently & run them separately on the emulator as if they are different apks , in addition files of resources , xml are separated as if you are coding separate apps in the same project.

https://developer.android.com/studio/projects/add-app-module

EDIT : I thought this would be better for a reason which is each module would have his own gradle file & dependencies & its own source so we could have like HelloJmeAndroid , AndroidHarnessExample , JmeSurfaceViewExample , & may be convert game into android example.