Skip to content

Google Play Store Console pre-launch report shows errors due to usage of non-SDK API classes #1678

Closed
@digitprop

Description

@digitprop

When submitting an Android JME app in the Google Play Store, for target API level 30 and higher, the Play Store Console reports multiple errors. These are due to AndroidBufferAllocator accessing fields of java.nio.ByteBufferAsFloat and similar (ByteBufferAsChar, ByteBufferAsInt, etc). These classes are not part of the SDK-approved Android API, and as such their use is not allowed for API levels 30 and higher.

This is the stack trace:

StrictMode policy violation: android.os.strictmode.NonSdkApiUsedViolation: Ljava/nio/ByteBufferAsCharBuffer;->bb:Ljava/nio/ByteBuffer;
	at android.os.StrictMode.lambda$static$1(StrictMode.java:407)
	at android.os.-$$Lambda$StrictMode$lu9ekkHJ2HMz0jd3F8K8MnhenxQ.accept(Unknown Source:2)
	at java.lang.Class.getDeclaredField(Native Method)
	at com.jme3.util.AndroidBufferAllocator.<clinit>(AndroidBufferAllocator.java:70)
	at java.lang.Class.classForName(Native Method)
	at java.lang.Class.forName(Class.java:454)
	at java.lang.Class.forName(Class.java:379)
	at com.jme3.util.BufferAllocatorFactory.create(BufferAllocatorFactory.java:25)
	at com.jme3.util.BufferUtils.<clinit>(BufferUtils.java:66)
	at com.jme3.util.BufferUtils.createIntBuffer(BufferUtils.java:926)
	at com.jme3.renderer.android.AndroidGL.<init>(AndroidGL.java:47)
	at com.jme3.system.android.OGLESContext.initInThread(OGLESContext.java:205)
	at com.jme3.system.android.OGLESContext.onSurfaceCreated(OGLESContext.java:184)
	at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1560)
	at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1285)

This is the static initializer of AndroidBufferAllocator where the error occurs:

    static {
        for (String className : wrapperClassNames) {
            try {
                Class clazz = Class.forName(className);

                // loop for all possible field names in android
                for (String fieldName : possibleBufferFieldNames) {
                    try {
                        Field field = clazz.getDeclaredField(fieldName); // <-- Problem is here
                        field.setAccessible(true);
                        fieldIndex.put(clazz, field);
                        break;
                    } catch (NoSuchFieldException e) {
                    }
                }
            } catch (ClassNotFoundException ex) {
            }
        }
    }

Workaround: Replace AndroidBufferAllocator by an implementation which does nothing on destroyDirectBuffer(Buffer), such as PrimitiveAllocator. This can be done by setting the system property com.jme3.BufferAllocatorImplementation to the full class name of the replacing Allocator during startup / initialization.

Up until API level 29 this was not a problem, as the affected classes where gray-listed. However, recently Google made API level 30 the mandatory target level for releases on the play store.

See also forum entry AndroidBufferAllocator and NonSdkApiUsedViolation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions