Android Question Does exceptions in inline java mess with live updating the code?

Sandman

Well-Known Member
Licensed User
I'm testing some things and have a piece of inline java that is throwing an exception under some conditions. That exception is not fatal for the app at all, and is also wrapped in a try/catch block.

However, if the exception is thrown, it's not possible to live update the code anymore. In fact, one needs to even clean the project to get it running as expected again.

I can't tell if this is a bug, a known limitation or simply an error on my part somewhere. I'm hoping for the latter, and for the forum to help me out. :)

This is my code. (Stripped down to bare minimum.)

B4X:
Sub Globals
    Dim myButton As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    myButton.Initialize("myButton")
    myButton.Text = "Throw exception"
    Activity.AddView(myButton, 5%X, 30%Y,90%X,20%Y)
End Sub

Sub myButton_Click

    Log("Clicked")

    Try
        Dim JO As JavaObject = Me
        JO.RunMethod("justTestingStuff", Null) ' <-- This is line 44
    Catch
        Log(LastException)
        Return
    End Try

    LogColor("Everything seems to have worked out fine.", Colors.Green)

End Sub

#if JAVA
public static void justTestingStuff() { 
    throw new RuntimeException("Stuff went bad");
}
#End If

A tap on the button produces this in the log...

B4X:
Clicked
(RuntimeException) java.lang.RuntimeException: Stuff went bad
...which seems to be working perfectly fine. The exception message is in there. Multiple taps just produces the same over and over again.

However, any code changes in the myButton_Click sub changes things completely - even if the change is totally harmless. (It seems to be fine to change other subs though.) To try this, change the log message "Clicked" to "Clicked2" and save to update the code running in the phone.

Tap the button, and this is the result:

B4X:
Clicked2
Error occurred on line: 44 (Main)
java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:131)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:778)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:358)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:6294)
    at android.view.View$PerformClick.run(View.java:24770)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.RuntimeException: Stuff went bad
    at b4a.example.main.justTestingStuff(main.java:457)
    ... 20 more
(Exception) java.lang.Exception:  java.lang.reflect.InvocationTargetException
 

Semen Matusovskiy

Well-Known Member
Licensed User
However, any code changes in the myButton_Click sub changes things completely - even if the change is totally harmless. (It seems to be fine to change other subs though.) To try this, change the log message "Clicked" to "Clicked2" and save to update the code running in the phone.
I tried to change Log ("Clicked") to Log ("Clicked2") in all regimes (Release, Debug, Obfuscated). The output is expected
Clicked2
(RuntimeException) java.lang.RuntimeException: Stuff went bad


I also tried to change a text of the button. Also all is expected.
So, the problem does not exist or you need to describe a situation more exactly.

 

Sandman

Well-Known Member
Licensed User
It is a bit confusing but everything is working properly. The exception is caught.
Yes, that is true. But the type of the exception is changed. In the first case GetType(LastException) returns java.lang.RuntimeException, and after the edit that changes to java.lang.Exception.

I have no problem with the log getting a stack trace all of a sudden, but it's a little bit problematic that the type changes. Is this something even worth posting a wish about, or is it way off the radar in the cost/benefit ratio?

(Why am I interested in this? I'm strongly considering breaking up my app in a bunch of libraries with super clean separations. And using custom (not shown in the code above) exceptions is a nice way of communicating fails back to the main app, which will use try/catch blocks for all calls into my libs. And I can't really do that if the type of the exception changes. That said, we're talking about scenarios where I'm live updating code, so it's not the end of the world if it doesn't work. It just adds some friction.)
 

Semen Matusovskiy

Well-Known Member
Licensed User
Are you using the legacy debugger, or something like that? It seems strange that you're not seeing this problem. Can you try the attached project? And perhaps attach the one you did also?
Today I, at first, took your zip, then attached. Tested under API 25 emulator in release mode .
Should be explanation. First of all, do you use B4A 8.50 ?
 

Attachments

Last edited:

Sandman

Well-Known Member
Licensed User
Tested under API 25 emulator in release mode. Should be explanation.
I feel we have a little bit of language barrier here, but are you saying you tried it in release mode? That's not what this thread is about. This is only about running the app in debug mode, changing the code, saving and continue running - without stopping the app in between.


First of all, do you use B4A 8.50 ?
I sure do.
 

Semen Matusovskiy

Well-Known Member
Licensed User
The problem is exactly like you described. See below.

Personally I have serious prejudice agaist debuggers.
It was a period when I used Visual Basic. Thanks to interpreter to debug was enough comfortable.

But then I began to use PowerBasic (www.powerbasic.com). Fantastic compiler, but not comfortable debugger.
Because I continue to use PowerBasic in Windows, I subconsciously transfer hostility to B4A debugger.
For me Log statement is more than enough :)


B4X:
Clicked2
Error occurred on line: 42 (Main)
java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:131)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runVoidMethod(Shell.java:783)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:363)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:260)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:171)
    at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:80)
    at android.view.View.performClick(View.java:5610)
    at android.view.View$PerformClick.run(View.java:22265)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6077)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.RuntimeException: Stuff went bad
    at b4a.example.main.justTestingStuff(main.java:451)
    ... 20 more
(Exception) java.lang.Exception:  java.lang.reflect.InvocationTargetException
java.lang.Exception
 
Top