B4J Question B4J - Code works when I debug step through it but fails without breakpoint

Fr Simon Rundell

Member
Licensed User
EDIT: Solution found (Thank you, all):
Dim aryDelete() As Object = tblBookList.Items.Get(0)
Original Question:
This is a good one...

The user has built a tableview (and why is there no satisfactory b4xtableview yet?) which has a list of books to be deleted. This code wants to build the MySQL query from the data in the first column of that tableview.

The following snippet of code fails on normal debug execution with

Line 4106
java.lang.ClassCastException: java.base/[Ljava.lang.Object; cannot be cast to java.base/[Ljava.lang.String;
It appears to fail at "Cycle=0" ie the first time the code encounters it, so its not as though the table is running out of elements...

BUT if I but a breakpoint in (at that Log("Cycle...) for example) and then step into each command (looking for my error) it builds the delete query correctly and executes fine.

Dear friends, what has this poor but enthusiastic hobby coder missed?

Failing code:
        Private sQuery As String
        Private intCount As Int
        Private totalRecords As Int = tblBookList.Items.Size
      
        RecordEvent("Size of the tblBookList to be deleted is " & tblBookList.Items.Size)
          
        sQuery="DELETE FROM tblBook WHERE BabcockCode IN ("
      
        For intCount=0 To totalRecords-1
            Log("Cycle: " & intCount)
            ' always select the first record in the table
            ' which as we delete the previous to be deleted record, will always be 0
            Dim aryDelete() As String = tblBookList.Items.Get(0)       '<---- this is the flagged error line
            sQuery=sQuery & aryDelete(0) & ", "
            ' remove item from list as it happens
            tblBookList.Items.RemoveAt(0)
        Next
      
        'trim off last ", "
        sQuery=sQuery.SubString2(0, sQuery.Length-2) & ");"

        Log("Bulk Book Delete: " & sQuery)
        SQL.ExecNonQuery(sQuery)
 
Last edited:

Sandman

Well-Known Member
Licensed User
While I have nothing to add to your actual question, I feel I must at least mention that your way of building the sql query opens you up to potential hacking from bad actors, which might lead to data destruction and who knows what else. The concept is called SQL Injection and you can find lots of information on the net if you search for it. One page with info: https://en.wikipedia.org/wiki/SQL_injection. (Depending on where your data is coming from you might still be secure, but why even take the chance.)

Luckily there's a very simple and secure way of doing it instead. Take a look at this thread, and specifically look at the code examples where values in the sql statements are marked by questionmarks. After that, the actual values are added in an array. This is the correct, and secure, way of doing it.
 

Fr Simon Rundell

Member
Licensed User
A good point: most of my queries in this App get paramaterised into ExecNonQuery2 to prevent SQLInjection, and here, the table is non-editable and the field which populates it will only add data to the table once it has been validated. I just tried to hack it with a SQL Injection and it doesn't allow it. Thank you for reminding me, though.
 

stevel05

Expert
Licensed User
I can't give you the reason it behaves in that way, but it appears that you may have a non string value in the table row.

Check the rows for non string values, may be a null in there somewhere if it's read from the database.
 

Daestrum

Well-Known Member
Licensed User
You could try
B4X:
Dim aryDelete() As Object = tblBookList.Items.Get(0)
providing the aryDelete(0) is a String it should work in the query building.
 

Fr Simon Rundell

Member
Licensed User
You could try
B4X:
Dim aryDelete() As Object = tblBookList.Items.Get(0)
providing the aryDelete(0) is a String it should work in the query building.
YES! ISSUE SOLVED for the Array, for which I thank you.

No idea why it wouldn't error in debug/step into mode unless the debug engine changes the objects in the process. One to ponder.
 
Top