Android crash on release variant, debug variant working

Are there any Android experts who can give me a clue how to fix this please?

So my first release of my Playstore boxer app worked fine.
Then I did a few ‘tweeks’, and updated Android Studio for the second release.
And it’s not working fine any more.

In Android Studio, if I run the debug variant, it works.
In Android Studio, if I run the release variant, it crashes.

After finding out how to turn on logging for the release variant…
I found that the crash is very basic, even before my app starts.
Seems that the JmeAndroidSystem cannot be found.

2023-05-12 12:54:58.383 7837-7837 com.jme3.s…JmeSystem com.tharg.boxer
E SEVERE Failed to create JmeSystem delegate: {0}
java.lang.NoSuchMethodException: com.jme3.system.android.JmeAndroidSystem. []
at java.lang.Class.getConstructor0(Class.java:2363)
at java.lang.Class.getDeclaredConstructor(Class.java:2201)
at com.jme3.system.JmeSystem.tryLoadDelegate(JmeSystem.java:238)
at com.jme3.system.JmeSystem.checkDelegate(JmeSystem.java:250)
at com.jme3.system.JmeSystem.showSettingsDialog(JmeSystem.java:226)
at com.jme3.app.SimpleApplication.start(SimpleApplication.java:120)
at com.tharg.boxer.AndroidHarness.onCreate(AndroidHarness.java:264)
at com.tharg.boxer.MainActivity.onCreate(MainActivity.java:67)
at android.app.Activity.performCreate(Activity.java:8591)
at android.app.Activity.performCreate(Activity.java:8570)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4150)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4325)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
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:2574)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8757)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

The full logcat’s of both the debug variant (working) and distribution (crashes) are here:

https://drive.google.com/drive/folders/12m3fqmGTMQJbQanXZxkALt9K5I7ruNq7?usp=share_link

Hope someone can help!

Are you using a trivial implementation of AndroidHarness Activity?

Please, double-check that you are including the jme3-android module in your dependencies and try a clean rebuild.

Hi Pavl_G, I don’t know if I’m using a trivial AndroidHarness or not. It is based on one I copied from the IALON project shared on github by Cédric de Launois. It has always worked in the past, and still works for the debug variant. Following your tip I have tried adding

implementation "org.jmonkeyengine:jme3-android:3.6.0-stable"
implementation "org.jmonkeyengine:jme3-android-native:3.6.0-stable"

to the app build.gradle as well as the main project build.gradle. No change I’m afraid …

1 Like

Since I don’t know if there are changes or not, it might be better to use the official AndroidHarness or JmeSurfaceView; because we are somewhat better aware of the official codebase rather than trivial implementations.

Using the official AndroidHarness I have the same problem with the release variant, albeit a different FATAL EXCEPTION. The debug variant still works. I have updated the logs here:
https://drive.google.com/drive/folders/12m3fqmGTMQJbQanXZxkALt9K5I7ruNq7?usp=share_link

I have gone back to android-studio-2022.1.1.19-windows.exe from android-studio-2022.2.1.19-windows.exe Android Studio version. About to try going back in gradle plugin versions too :slight_smile:

Here’s the crash using the official AndroidHarness:

E FATAL EXCEPTION: main
Process: com.tharg.boxer, PID: 18437
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tharg.boxer/com.tharg.boxer.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method ‘android.opengl.GLSurfaceView com.jme3.system.android.OGLESContext.createView(android.content.Context)’ on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4169)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4325)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
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:2574)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8757)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

Thanks for testing, I fear there is something related to java reflection restrictions that were lately causing problems on Android releases, you can open an issue, so we could investigate into this.

FYI, the Ialon version was slightly modified to support the Android “immersive” mode, i.e. display under the notch, until the related ticket is closed.
I don’t think it has anything to do with the problem, but yes it is better to reproduce the problem using the original code :wink:

1 Like

I used the debugger (once I figured out how to turn it on for the release variant).
The ‘get constructor’ of JmeAndroidSystem fails in the release variant.
But works in the debug variant.
The code that does the actual ‘getting’ is native.
I’m not sure how to step into that.

Maybe JmeAndroidSystem has not been put on whatever list the native code is looking at?
I don’t know.

Android API 33, extension level 3 Platform
Class.java
...

DEBUG VARIANT: VALUES FROM THE DEBUGGER are my comments //

    private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
                                        int which) throws NoSuchMethodException
    {
        if (parameterTypes == null) {
            parameterTypes = EmptyArray.CLASS;
        }
        for (Class<?> c : parameterTypes) {
            if (c == null) {
                throw new NoSuchMethodException("parameter type is null");
            }
        }
        Constructor<T> result = getDeclaredConstructorInternal(parameterTypes); //RESULT: "public com.jme3.system.android.JmeAndroidSystem()"
        if (result == null || which == Member.PUBLIC && !Modifier.isPublic(result.getAccessFlags())) { //WHICH=1**
            throw new NoSuchMethodException(getName() + ".<init> "
                    + Arrays.toString(parameterTypes)); //PARAMETER TYPES: Class[0]@22734
        }
        return result; //RESULT: "public com.jme3.system.android.JmeAndroidSystem()"
    }
	
RELEASE VARIANT: //parameterTypes= Class[0]@22733 //RESULT IS NULL.

    @FastNative
    private native Constructor<T> getDeclaredConstructorInternal(Class<?>[] args);
	
//note getDeclaredConstructorInternal is native, can't step in :-(

I have upgraded everything to the latest. Android Studio, its plugins, gradle, Java 17 (required by the latest Android and gradle plugins). This particular crash has disappeared. However, I can no longer run the emulators, due to my old graphics card, but the app works on a physical device as long as minifyEnabled is false.
If minifyEnabled is true I get another crash…

1 Like

What type of crashes do you get? Could you share the crash logs?

Hi @Pavl_G,
The crash happens at line 255 in AndroidHarness with minifyEnabled = true
ctx = (OGLESContext) app.getContext();

At this line the debugger reports:
app = No such instance field: ‘app’
and
ctx = No such instance field: ‘ctx’

with minifyEnabled = false, app is set to my Main class and ctx is null.

2023-07-02 12:06:27.786 28392-28392 InsetsController com.tharg.boxer D onStateChanged: InsetsState: {mDisplayFrame=Rect(0, 0 - 1600, 720), mDisplayCutout=DisplayCutout{insets=Rect(45, 0 - 0, 0) waterfall=Insets{left=0, top=0, right=0, bottom=0} boundingRect={Bounds=[Rect(0, 272 - 45, 448), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0)]} cutoutPathParserInfo={CutoutPathParserInfo{displayWidth=720 displayHeight=1600 physicalDisplayWidth=720 physicalDisplayHeight=1600 density={1.75} cutoutSpec={M 0,0 H -88 V 45 H 88 V 0 H 0 Z} rotation={1} scale={1.0} physicalPixelDisplaySizeRatio={1.0}}}}, mRoundedCorners=RoundedCorners{[RoundedCorner{position=TopLeft, radius=60, center=Point(60, 60)}, RoundedCorner{position=TopRight, radius=60, center=Point(1540, 60)}, RoundedCorner{position=BottomRight, radius=60, center=Point(1540, 660)}, RoundedCorner{position=BottomLeft, radius=60, center=Point(60, 660)}]} mRoundedCornerFrame=Rect(0, 0 - 1600, 720), mPrivacyIndicatorBounds=PrivacyIndicatorBounds {static bounds=Rect(1517, 0 - 1600, 45) rotation=1}, mSources= { InsetsSource: {mType=ITYPE_STATUS_BAR, mFrame=[0,0][1600,45], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_NAVIGATION_BAR, mFrame=[1510,0][1600,720], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_LEFT_GESTURES, mFrame=[0,0][45,720], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_RIGHT_GESTURES, mFrame=[1600,0][1600,720], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_TOP_MANDATORY_GESTURES, mFrame=[0,0][1600,45], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_BOTTOM_MANDATORY_GESTURES, mFrame=[1510,0][1600,720], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_LEFT_DISPLAY_CUTOUT, mFrame=[0,0][45,720], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_TOP_DISPLAY_CUTOUT, mFrame=[0,0][1600,-100000], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_RIGHT_DISPLAY_CUTOUT, mFrame=[100000,0][1600,720], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_BOTTOM_DISPLAY_CUTOUT, mFrame=[0,100000][1600,720], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_TOP_TAPPABLE_ELEMENT, mFrame=[0,0][1600,45], mVisible=true, mInsetsRoundedCornerFrame=false}, InsetsSource: {mType=ITYPE_BOTTOM_TAPPABLE_ELEMENT, mFrame=[1510,0][1600,720], mVisible=true, mInsetsRoundedCornerFrame=false} } host=com.tharg.boxer/com.tharg.boxer.MainActivity from=android.view.ViewRootImpl.setView:1732
2023-07-02 12:06:27.791 28392-28392 ViewRootIm…nActivity] com.tharg.boxer
I setView = com.android.internal.policy.DecorView@3198fd5 TM=true
--------- beginning of crash
2023-07-02 12:06:27.799 28392-28392 AndroidRuntime com.tharg.boxer D Shutting down VM
2023-07-02 12:06:27.805 28392-28392 AndroidRuntime com.tharg.boxer E FATAL EXCEPTION: main
Process: com.tharg.boxer, PID: 28392
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tharg.boxer/com.tharg.boxer.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method ‘com.jme3.system.JmeContext com.jme3.app.LegacyApplication.getContext()’ on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4169)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4325)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
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:2574)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8757)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method ‘com.jme3.system.JmeContext com.jme3.app.LegacyApplication.getContext()’ on a null object reference
at com.jme3.app.AndroidHarness.onCreate(AndroidHarness.java:255)
at com.tharg.boxer.MainActivity.onCreate(MainActivity.java:74)
at android.app.Activity.performCreate(Activity.java:8591)
at android.app.Activity.performCreate(Activity.java:8570)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1384)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4150)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4325)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
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:2574)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8757)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
2023-07-02 12:06:27.886 28392-28392 Process com.tharg.boxer I Sending signal. PID: 28392 SIG: 9
---------------------------- PROCESS ENDED (28392) for package com.tharg.boxer ----------------------------

DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG
Values at breakpoint line 255 AndroidHarness minifyEnabled = true
ctx = (OGLESContext) app.getContext();

this = {MainActivity@22780}
ESCAPE_EVENT = “TouchEscape”
appClass = “com.tharg.boxer.Main”
audioRendererType = “OpenAL_SOFT”
eglAlphaBits = 0
eglBitsPerPixel = 24
eglDepthBits = 16
eglSamples = 0
eglStencilBits = 0
exitDialogMessage = “Are you sure you want to quit?”
exitDialogTitle = “Exit?”
finishOnAppStop = true
firstDrawFrame = true
frameLayout = null
frameRate = -1
handleExitHook = false
inConfigChange = false
isGLThreadPaused = true
joystickEventsEnabled = true
keyEventsEnabled = true
mouseEventsEnabled = true
mouseEventsInvertX = false
mouseEventsInvertY = false
screenFullScreen = true
screenShowTitle = true
splashImageView = null
splashPicID = 2131165404
view = null
mActionBar = null
mActionModeTypeStarting = 0
mActivityInfo = {ActivityInfo@22786} “ActivityInfo{89c0b97 com.tharg.boxer.MainActivity}”
mActivityLifecycleCallbacks = {ArrayList@22787} size = 2
mActivityTransitionState = {ActivityTransitionState@22788}
mApplication = {Application@22789}
mAssistToken = {BinderProxy@22790}
mAutofillClientController = {AutofillClientController@22791}
mCallbacksController = null
mCalled = true
mCanEnterPictureInPicture = true
mChangeCanvasToTranslucent = false
mChangingConfigurations = false
mComponent = {ComponentName@22792} “ComponentInfo{com.tharg.boxer/com.tharg.boxer.MainActivity}”
mConfigChangeFlags = 0
mContentCaptureManager = null
mCurrentConfig = {Configuration@22793} “{1.1 302mcc490mnc [en_CA] ldltr sw384dp w781dp h360dp 300dpi nrml long land finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1600, 720) mAppBounds=Rect(45, 0 - 1510, 720) mMaxBounds=Rect(0, 0 - 1600, 720) mDisplayRotation=ROTATION_90 mWindowingMode=fullscreen mDisplayWindowingMode=fullscreen mActivityType=standard mAlwaysOnTop=undefined mRotation=ROTATION_90 mPopOver=off mStageConfig=undefined mFreeformTaskPinningState=unpinned mFreeformStashState=undefined} s.2 fontWeightAdjustment=0 ff=0 bf=0 bts=0 themeSeq=0 nightDim=-1}”
mDecor = null
mDefaultBackCallback = null
mDefaultKeyMode = 0
mDefaultKeySsb = null
mDestroyed = false
mDexTaskDocking = -1
mDoReportFullyDrawn = true
mDumpableContainer = null
mEmbeddedID = null
mEnableDefaultActionBarUp = false
mEnterAnimationComplete = false
mEnterTransitionListener = {SharedElementCallback$1@22794}
mExitTransitionListener = {SharedElementCallback$1@22794}
mFinished = false
mFragments = {FragmentController@22795}
mFreeformTaskPinning = 0
mFreeformTaskStashing = 0
mHandler = {Handler@22796} “Handler (android.os.Handler) {3c32184}”
mHasCurrentPermissionsRequest = false
mIdent = 187935029
mInOutsideLongPress = false
mInOutsideTouch = false
mInstanceTracker = {StrictMode$InstanceTracker@22797}
mInstrumentation = {Instrumentation@22798}
mIntent = {Intent@22799} “Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.tharg.boxer/.MainActivity }”
mIsFlexPanelMode = false
mIsInMultiWindowMode = false
mIsInPictureInPictureMode = false
mIsPopOver = false
mLastNonConfigurationInstances = null
mLaunchedFromBubble = false
mLongPressDetector = {GestureDetector@22800}
mLongPressListener = {Activity$3@22801}
mMainThread = {ActivityThread@22802}
mManagedCursors = {ArrayList@22803} size = 0
mManagedDialogs = null
mMenuInflater = null
mParent = null
mPendingOptions = null
mReferrer = “com.android.shell”
mRestoredFromBundle = false
mResultCode = 0
mResultData = null
mResumed = false
mSearchEvent = null
mSearchManager = null
mShareableActivityToken = {BinderProxy@22805}
mShouldDockBigOverlays = false
mSplashScreen = null
mStartedActivity = false
mStopped = false
mTaskDescription = {ActivityManager$TaskDescription@22806} “TaskDescription Label: null Icon: null IconFilename: null colorPrimary: -657931 colorBackground: -328966 statusBarColor: -16777216 navigationBarColor: -592138 (contrast when transparent) resizeMode: RESIZE_MODE_RESIZEABLE minWidth: -1 minHeight: -1 colorBackgrounFloating: -1”
mTitle = “Boxer”
mTitleColor = 0
mTitleReady = false
mToken = {BinderProxy@22808}
mTranslucentCallback = null
mUiThread = {Thread@22617} “Thread[main,5,main]”
mUiTranslationController = null
mVisibleFromClient = true
mVisibleFromServer = false
mVoiceInteractor = null
mWindow = {PhoneWindow@22809}
mWindowAdded = false
mWindowControllerCallback = {Activity$1@22810}
mWindowManager = {WindowManagerImpl@22811}
mWindowingMode = 1
mInflater = {PhoneLayoutInflater@22812}
mOverrideConfiguration = null
mResources = {Resources@22813}
mTheme = {Resources$Theme@22814} “{InheritanceMap=[id=0x7f10021fcom.tharg.boxer:style/Theme.Ialon.Launcher, id=0x7f100216com.tharg.boxer:style/Theme.AppCompat.Light.NoActionBar, id=0x7f100210com.tharg.boxer:style/Theme.AppCompat.Light, id=0x7f100050com.tharg.boxer:style/Base.Theme.AppCompat.Light, id=0x7f1000b3com.tharg.boxer:style/Base.V28.Theme.AppCompat.Light, id=0x7f1000b0com.tharg.boxer:style/Base.V26.Theme.AppCompat.Light, id=0x7f1000aacom.tharg.boxer:style/Base.V23.Theme.AppCompat.Light, id=0x7f1000a8com.tharg.boxer:style/Base.V22.Theme.AppCompat.Light, id=0x7f10009dcom.tharg.boxer:style/Base.V21.Theme.AppCompat.Light, id=0x7f1000b6com.tharg.boxer:style/Base.V7.Theme.AppCompat.Light, id=0x7f100131com.tharg.boxer:style/Platform.AppCompat.Light, id=0x7f10013ccom.tharg.boxer:style/Platform.V25.AppCompat.Light, id=0x1030241android:style/Theme.Material.Light.NoActionBar, id=0x1030237android:style/Theme.Material.Light, id=0x103000candroid:style/Theme.Light, id=0x1030005android:style/Theme], Themes=[com.tharg.boxer:sty”
mThemeResource = 2131755551
mBase = {ContextImpl@22815}
mCallbacksRegisteredToSuper = null
mLock = {Object@22816}
shadow$klass = {Class@22728} “class com.tharg.boxer.MainActivity”
shadow$monitor = 0
app = No such instance field: ‘app’
view = null
ctx = No such instance field: ‘ctx’
appClass = “com.tharg.boxer.Main”

Values at breakpoint line 255 AndroidHarness minifyEnabled = true
ctx = (OGLESContext) app.getContext();

this = {MainActivity@22969}
savedInstanceState = null
data = null
app = {Main@22970}
view = null
ctx = null
appClass = “com.tharg.boxer.Main”

BTW, I do have a proguard-rules.pro file, but every line is commented out.

FWIW, I once tried to enable this option and I got tons of class not found exceptions at runtime. My understanding was that I need to precisely specify the packages/classes I want to keep, inside the prog-guard rules so R8 (android code shrinking, obfuscation, and optimization tool) wouldn’t purge them when building, but I might be wrong!

1 Like

That sounds very likely Ali_RS! I’ve never experienced a “No such instance field” error before but from what I’ve read it seems similar to ClassNotFound. Which we all know and love :wink: Not sure how to add “Leave my Main class ALONE” in proguard, but I’ll hunt around and try an find the syntax.
Thanks for the tip.

1 Like

RIGHT BACK WHERE I STARTED!
With minifyEnabled true:-
I had to add the following 2 lines to proguard_rules.pro to get my app to compile:

-dontwarn javax.imageio.*
-dontwarn java.awt.image.*

I had to add the following to get my app to attempt to start:

-keep public class com.tharg.** {
  public protected *;
}

I now get the same crash as I did when I started this topic.

java.lang.NoSuchMethodException: com.jme3.system.android.JmeAndroidSystem.<init> 

Adding the following proguard rule has no effect.

-keep public class com.jme.system.** {
  public protected *;
}

So I give up.

minifyEnabled = false

from now on…

2 Likes