[SOLVED] JNI exception when trying to use OGG files on Android

Whenever I try to load a ogg file on android, the app crashes with the following stack trace:

 JNI DETECTED ERROR IN APPLICATION: JNI GetFieldID called with pending exception java.lang.NoSuchFieldError: no "Ljava/nio/ByteBuffer;" field "ovf" in class "Lcom/jme3/audio/plugins/NativeVorbisFile;" or its superclasses
   at void com.jme3.audio.plugins.NativeVorbisFile.nativeInit() (NativeVorbisFile.java:-2)
   at void com.jme3.audio.plugins.NativeVorbisFile.<clinit>() (NativeVorbisFile.java:19)
   at com.jme3.audio.AudioStream com.jme3.audio.plugins.NativeVorbisLoader.loadStream(com.jme3.asset.AssetInfo) (NativeVorbisLoader.java:97)
   at java.lang.Object com.jme3.audio.plugins.NativeVorbisLoader.load(com.jme3.asset.AssetInfo) (NativeVorbisLoader.java:128)
   at java.lang.Object com.jme3.asset.DesktopAssetManager.loadLocatedAsset(com.jme3.asset.AssetKey, com.jme3.asset.AssetInfo, com.jme3.asset.AssetProcessor, com.jme3.asset.cache.AssetCache) (DesktopAssetManager.java:259)
   at java.lang.Object com.jme3.asset.DesktopAssetManager.loadAsset(com.jme3.asset.AssetKey) (DesktopAssetManager.java:373)
   at void com.jme3.audio.AudioNode.<init>(com.jme3.asset.AssetManager, java.lang.String, boolean, boolean) (AudioNode.java:163)
   at void com.jme3.audio.AudioNode.<init>(com.jme3.asset.AssetManager, java.lang.String, com.jme3.audio.AudioData$DataType) (AudioNode.java:144)
.....

The full crash report can be found here.

Is there any lib that has to be added in order to have ogg files working on android devices?

What Java/Android Version are you testing against? Could it be that the java.nio.ByteBuffer Class has been removed or at least changed? I Remember that they wanted to deprecate them

I’ve tested it against 6.0.1. It doesn’t seem to be removed or deprecated.

This is a big lie… The field is right there:

Yes, I know it T.T, all seems to be fine, that’s the problem why I didn’t already fix it myself and that’s why I think Darkchaos suggested the removal of that class (java.nio.ByteBuffer) on the android version, the field is there so maybe the class isn’t?, I’m not much experienced on JNI.

Yeah it’s a fault on my side. I read that like “Field ovf of class ByteBuffer”… however I also did some research:
Oracle definitely wants to remove the Unsafe API in Java 9 but they will also delay that because it would break lots of internal code, so we still have some time until that happens.

If the class wasn’t there, you would most likely see a segfault or some other error “class handle invalid”, actually it pretty well knows the class.

I guess you tried re-building and all that?

Yes, I’ve tried it many times, and to execute in many different android devices. I wanted to try a ‘master’ build (currently I’m using 3.1-stable) but I get (with: ./gradlew build):

:jme3-bullet-native-android:check UP-TO-DATE
:jme3-bullet-native-android:build UP-TO-DATE
:jme3-core:sourcesJar UP-TO-DATE
:jme3-core:writeFullPom UP-TO-DATE
:jme3-core:assemble UP-TO-DATE
:jme3-core:compileTestJava UP-TO-DATE
:jme3-core:processTestResources UP-TO-DATE
:jme3-core:testClasses UP-TO-DATE
:jme3-core:test

com.jme3.collision.CollideIgnoreTransformTest > testPhantomTriangles FAILED
    java.lang.NullPointerException
        at com.jme3.system.JmeSystem.isLowPermissions(JmeSystem.java:99)
        at com.jme3.asset.plugins.ClasspathLocator.locate(ClasspathLocator.java:89)
        at com.jme3.asset.ImplHandler.tryLocate(ImplHandler.java:177)
        at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:359)
        at com.jme3.asset.DesktopAssetManager.loadMaterial(DesktopAssetManager.java:394)
        at com.jme3.collision.CollideIgnoreTransformTest.createRedSquare(CollideIgnoreTransformTest.java:80)
        at com.jme3.collision.CollideIgnoreTransformTest.testPhantomTriangles(CollideIgnoreTransformTest.java:95)

89 tests completed, 1 failed, 1 skipped
:jme3-core:test FAILED

FAILURE: Build failed with an exception.

That is really strange, actually many of the tests shouldn’t pass when the problem is inheritent with JmeSystem.
Something seems wierd in that setup actually.
Can someone different confirm he gets the same issue?

And maybe also ensuring that you delete the ~/.m2 folder or the jar’s inside at least, so you don’t pull them in.

implies you don’t have a proper delegate or the creation thereof failed. Is this now desktop or android?

Desktop, I’ve build the engine many times from different versions, this time is just failing (I though it was something about any last change and it would be fixed any time soon). I’ve just tried it moving the .m2 folder (I have many custom libraries there, but nothing that could interfere with the build, or should…) but it didn’t change anything.

Well using gradlew install would place the engine there.
And what you see is indeed a new test, I don’t know if you can’t skip the tests actually, but the issue seems to be failing to use the DesktopAssetManager.

Maybe this is an issue with the test though, since tests might not have a lwjgl window and as such maybe have a TestAssetManager? (But that’s just wildly guessing)

I’ve just tried with: ./gradlew build -x :jme3-core:test and the build got successful. Lets see now if it works and this is just an already-fixed bug.

EDIT: It is still there with the master version. The libraries I’m adding with gradle are:

Both:

  • jme3-core
  • jme3-jogg

PC:

  • jme3-desktop
  • jme3-lwjgl

Android:

  • jme3-android-native

Definitely it wasn’t a lie, the file wasn’t there. I was relaxed when all in a sudden I though: proguard.

Fixed with:

-keepclassmembers class com.jme3.audio.plugins.NativeVorbisFile {
    public <fields>;
}

Thanks to both for helping :wink: