Android Question [SOLVED] [B4X] (ClassCastException) java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.String[]

MrKim

Well-Known Member
Licensed User
Longtime User
Edit: See 3rd Post.

I am seeing something similar to this.

I get the error in both B4A and B4J'

B4X:
B4J
https://www.b4x.com/android/forum/threads/class-java-lang-error-cannot-be-cast-to-class-java-lang-exception.118465/
B4A
(ClassCastException) java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.String[]

It Occurs in the following code:

B4X:
Sub GetPic
    Try
'        Dim req As DBRequestManager = req.Initialize(Me, $"http://${IPAddre.Text}:17178/rdcx"$)
'        Dim cmd As DBCommand = CreateCommand("GetEmployees", Array())
        Dim FN As String = ""
        Dim FDir As String = ""
        Dim H As HttpJob
        H.Initialize("H", Me)
        'Sleep(10)
        Dim XXX As Int
    #IF B4A
        Dim B As Bitmap
        B.InitializeMutable(TravPic.mBase.Width, TravPic.mBase.Height)
        TravPic.Bitmap = B
    #ELSE
'        Dim C As Canvas
'        C.Initialize("")
'        Dim FX As JFX
'        C.ClearRect(0, 0, 1000, 1000)
'        C.DrawLine(0, 0, 8, 8, FX.Colors.Black , 5)
'        TravPic.Bitmap = C.Snapshot
    #END IF
        Dim req As DBRequestManager = CreateRequest
        Dim cmd As DBCommand = CreateCommand("PMPicTest", Array())
        TextArea1.Text = "Getting 5 pictures"
        Sleep(100)
        Wait For (req.ExecuteQuery(cmd, 0, "")) JobDone(j As HttpJob)
        If j.Success Then
            req.HandleJobAsync(j, "req")
            Wait For (req) req_Result(res As DBResult)
            For Each row() As String In res.Rows
                TextArea1.Text = $"${TextArea1.Text}
${row(0)}
"$
#IF B4J
                FN = File.GetName(row(0))
                FDir = File.GetFileParent(row(0))
                If File.Exists(FDir, FN) Then
                    XXX = XXX+ 1
                    Wait For(GetPicFromServer(FN, FDir)) Complete(R As Boolean)
                    TextArea1.Text = TextArea1.Text & CRLF & "Wait 1 Second"
                    Sleep(1000)
                    If XXX > 5 Then    Exit
                End If
#ELSE
                Dim FDir As String = row(0).SubString2(0, row(0).LastIndexOf("\"))
                Dim FN As String = row(0).SubString(row(0).LastIndexOf("\") + 1)
                XXX = XXX+ 1
                Wait For(GetPicFromServer(FN, FDir)) Complete(R As Boolean)
                TextArea1.Text = TextArea1.Text & CRLF & "Wait 1 Second"
                Sleep(1000)
                If XXX > 5 Then    Exit
#END IF
            Next
        Else
            Log("ERROR: " & j.ErrorMessage)
            TextArea1.Text = TextArea1.Text & CRLF & j.ErrorMessage
        End If
        j.Release
    Catch
        Log(LastException)
    End Try
End Sub

Sub GetPicFromServer(FN As String, FDir As String) As ResumableSub
    Dim H As HttpJob
    H.Initialize("H", Me)
    Dim T As Long = DateTime.Now
    H.Download2($"http://${IPAddre.Text}:17178/getfile"$, Array As String("FileName", FDir & "\" & FN, "Dir", FDir))
    Wait For (H) JobDone(j As HttpJob)
    If j.Success Then
        TextArea1.Text = TextArea1.Text & "Got Picture in " & ((DateTime.Now - T) / 1000) & " Seconds."
        If j.GetString2("UTF8").SubString2(0, 6).EqualsIgnoreCase("Failed") Then
            TextArea1.Text = $"Couldn't find ${FDir}\${FN}"$
        Else
            T = DateTime.Now
            TravPic.Bitmap = j.GetBitmap
            TravPic.ResizeMode = "FIT"
            TextArea1.Text = TextArea1.Text & CRLF & "Load Picture in " & ((DateTime.Now - T) / 1000) & " Seconds."
        End If
    End If
    j.Release
    Return True
End Sub

I am not sure if it has anything to do with GetPicFromServer because here is the interesting part:
Let me see if I can list the various conditions. These all apply to the GetPic sub.
B4J Debug mode:
Adding a Break anywhere in the sub prevents the problem. THE CODE DOES NOT HAVE TO ACTUALLY HIT THE BREAK AND STOP.
Remming the line Log(LastException) inside the catch block prevents the problem.
IF I rem the Try Catch block AND put a break line the code runs and Log(LastException) Logs (Exception) Not initialized
I have similar results in Android.
I cannot get it working in Release Mode.
 
Last edited:

MrKim

Well-Known Member
Licensed User
Longtime User
Edit: See 3nd Post.

I am seeing something similar to this.

I get the error in both B4A and B4J'

B4X:
B4J
https://www.b4x.com/android/forum/threads/class-java-lang-error-cannot-be-cast-to-class-java-lang-exception.118465/
B4A
(ClassCastException) java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.String[]

It Occurs in the following code:

B4X:
Sub GetPic
    Try
'        Dim req As DBRequestManager = req.Initialize(Me, $"http://${IPAddre.Text}:17178/rdcx"$)
'        Dim cmd As DBCommand = CreateCommand("GetEmployees", Array())
        Dim FN As String = ""
        Dim FDir As String = ""
        Dim H As HttpJob
        H.Initialize("H", Me)
        'Sleep(10)
        Dim XXX As Int
    #IF B4A
        Dim B As Bitmap
        B.InitializeMutable(TravPic.mBase.Width, TravPic.mBase.Height)
        TravPic.Bitmap = B
    #ELSE
'        Dim C As Canvas
'        C.Initialize("")
'        Dim FX As JFX
'        C.ClearRect(0, 0, 1000, 1000)
'        C.DrawLine(0, 0, 8, 8, FX.Colors.Black , 5)
'        TravPic.Bitmap = C.Snapshot
    #END IF
        Dim req As DBRequestManager = CreateRequest
        Dim cmd As DBCommand = CreateCommand("PMPicTest", Array())
        TextArea1.Text = "Getting 5 pictures"
        Sleep(100)
        Wait For (req.ExecuteQuery(cmd, 0, "")) JobDone(j As HttpJob)
        If j.Success Then
            req.HandleJobAsync(j, "req")
            Wait For (req) req_Result(res As DBResult)
            For Each row() As String In res.Rows
                TextArea1.Text = $"${TextArea1.Text}
${row(0)}
"$
#IF B4J
                FN = File.GetName(row(0))
                FDir = File.GetFileParent(row(0))
                If File.Exists(FDir, FN) Then
                    XXX = XXX+ 1
                    Wait For(GetPicFromServer(FN, FDir)) Complete(R As Boolean)
                    TextArea1.Text = TextArea1.Text & CRLF & "Wait 1 Second"
                    Sleep(1000)
                    If XXX > 5 Then    Exit
                End If
#ELSE
                Dim FDir As String = row(0).SubString2(0, row(0).LastIndexOf("\"))
                Dim FN As String = row(0).SubString(row(0).LastIndexOf("\") + 1)
                XXX = XXX+ 1
                Wait For(GetPicFromServer(FN, FDir)) Complete(R As Boolean)
                TextArea1.Text = TextArea1.Text & CRLF & "Wait 1 Second"
                Sleep(1000)
                If XXX > 5 Then    Exit
#END IF
            Next
        Else
            Log("ERROR: " & j.ErrorMessage)
            TextArea1.Text = TextArea1.Text & CRLF & j.ErrorMessage
        End If
        j.Release
    Catch
        Log(LastException)
    End Try
End Sub

Sub GetPicFromServer(FN As String, FDir As String) As ResumableSub
    Dim H As HttpJob
    H.Initialize("H", Me)
    Dim T As Long = DateTime.Now
    H.Download2($"http://${IPAddre.Text}:17178/getfile"$, Array As String("FileName", FDir & "\" & FN, "Dir", FDir))
    Wait For (H) JobDone(j As HttpJob)
    If j.Success Then
        TextArea1.Text = TextArea1.Text & "Got Picture in " & ((DateTime.Now - T) / 1000) & " Seconds."
        If j.GetString2("UTF8").SubString2(0, 6).EqualsIgnoreCase("Failed") Then
            TextArea1.Text = $"Couldn't find ${FDir}\${FN}"$
        Else
            T = DateTime.Now
            TravPic.Bitmap = j.GetBitmap
            TravPic.ResizeMode = "FIT"
            TextArea1.Text = TextArea1.Text & CRLF & "Load Picture in " & ((DateTime.Now - T) / 1000) & " Seconds."
        End If
    End If
    j.Release
    Return True
End Sub

I am not sure if it has anything to do with GetPicFromServer because here is the interesting part:
Let me see if I can list the various conditions. These all apply to the GetPic sub.
B4J Debug mode:
Adding a Break anywhere in the sub prevents the problem. THE CODE DOES NOT HAVE TO ACTUALLY HIT THE BREAK AND STOP.
Remming the line Log(LastException) inside the catch block prevents the problem.
IF I rem the Try Catch block AND put a break line the code runs and Log(LastException) Logs (Exception) Not initialized
I have similar results in Android.
I cannot get it working in Release Mode.
I finally figured it out - I was able to pinpoint the problem line by adding LOTS of Log(LastException) lines to find where it actually failed.
It was on this line:
B4X:
            For Each row() As String In res.Rows
It evidently MUST remain:
B4X:
            For Each row() As Object In res.Rows

Here is what happened. I am developing in B4J (easier for me) I wrote the code, it worked.

When I went to B4A this failed:
B4X:
                Dim FDir As String = row(0).SubString2(0, row(0).LastIndexOf("\"))

                Dim FN As String = row(0).SubString(row(0).LastIndexOf("\") + 1)

I thought Hmm I wonder if I can change For Each row() As Object to For Each row() As String. I did and it worked - until it didn't.
I needed to Leave row() as Object and assign row(0) to a string.

Perhaps an compiler error could be added to prevent that from being allowed?

Hope this experience can help someone else.
 
Last edited:
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
Why are you using Canvas instead of B4XCanvas???

Remove the Try / Catch block and post the full error message.
As mentioned above, I figured out what I did wrong. But FYI here is the full error message. I hope you can add a compiler error to keep average coders like me from making this mistake again. I am always looking for ways to minimize code and one of the ways I like is to avoid unnecessary assignment statements. I am used to VBA which just makes the conversion for you. Also, I was told over and over early in my career with VBA DON'T USE VARIANTS unless you absolutely have to they are expensive in terms of memory and speed so I very rarely do, so I am just not used to this type of issue.

B4X:
b4xmainpage$ResumableSub_GetPic.resume (java line: 405)
java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.String; ([Ljava.lang.Object; and [Ljava.lang.String; are in module java.base of loader 'bootstrap')
    at b4j.example.b4xmainpage$ResumableSub_GetPic.resume(b4xmainpage.java:405)
    at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:136)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:85)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:487)
    at anywheresoftware.b4a.keywords.Common.access$0(Common.java:467)
    at anywheresoftware.b4a.keywords.Common$CallSubDelayedHelper.run(Common.java:541)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:834)

Oh, and I switched to a B4Xcanvas but I wonder why it is important? I only use it in this instance for B4J (this will never go to B4i) B4A doesn't need a Canvas.

I sort of make an assumption that if something is only needed in one environment (ie B4J/A/i) that the native type for that environment will be more eficient/faster/smaller code. Is this an invalid assumption?

Thanks again for your help.
 
Last edited:
Upvote 0
Top