Android Question Cast Object to String, Problem with B4XSerializator

mw71

Active Member
Licensed User
Longtime User
hi,

i cast Data from a SQLite File, put it first to a Map (in a loop) and this Map to a Custom Type with a Map
This Custom Type is send to Android Device via B4XSerializator.

B4X:
Type MyMessage (Befehl As String, DatenS As String, DatenL As List, DatenM As Map,Success As Boolean)



Private mm_out As MyMessage
Private m_tmp As Map
m_tmp.Initialize

do....
        m_tmp.Put(k,DBUtils.ExecuteMemoryTable(SQL_I,"SELECT * FROM Log",Null,0,0))    'or with WHERE'
loop

mm_out.DatenM = m_tmp      'mm_out is send via B4XSerializator to the Android Device

From B4A to B4J it works, but from B4J to B4A not.
In B4J in Debug Mode the Map shows o.k., but in B4A i cant cast the List Entry to String
B4X:
L_in.Initialize2(mm_In.DatenM.Get(k))     'mm_in is the same Custom Type (MyMessage....), k is ok, L_In.Size return the correct size
Dim val_2(14) As String = L_in.Get(i1)     'error, cant cast to String

whats wrong?
 

OliverA

Expert
Licensed User
Longtime User
Each item in the list returned by ExecuteMemoryTable is an array of strings. You are trying to assign the whole array to a string instead of an element within that array
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
Each item in the list returned by ExecuteMemoryTable is an array of strings.
? rigth

You are trying to assign the whole array to a string instead of an element within that array
I am a little bit confused,
- L_in.Initialize2(mm_In.DatenM.Get(k)) get the List out from the Map
- Dim val_2(14) As String is an array of string ??
- L_in.Get(i1) (i1 is the counter from a for / next loop) get the entry from the List with the Array of String?, i think
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
- Dim val_2(14) As String is an array of string ??
- L_in.Get(i1) (i1 is the counter from a for / next loop) get the entry from the List with the Array of String?, i think
Yup, reading comprehension fail on my end. The error message overwrote my though process. The only odd thing I see (this time) is that you are sizing your array. Don't do that, just do a
B4X:
Dim val_2() As String = L_in.Get(i1)
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
B4X:
Dim val_2() As String = L_in.Get(i1)

dont work :-(

B4X:
Dim val_2() As String
val_2= L_in.Get(i1)
also dont work

Test B4A to B4J (now same Problem)
Code in B4A
B4X:
        Private m_tmp As Map               
        m_tmp.Initialize

            If File.Exists(varPfad,k) Then
                Try

                    sql_r.Initialize(varPfad,k,False)

                    Private L_tmp As List
                    L_tmp = DBUtils.ExecuteMemoryTable_Datum(sql_r,mm_In.DatenM.get(k),Null,0,0)

                    m_tmp.put(k,L_tmp)
                Catch
                    Log(LastException)
                End Try
                sql_r.close
            End If
'put the Map to the Custom Type
mm_Out.DatenM = m_tmp
'and send it
CallSub2(Starter, "SendData", ser.ConvertObjectToBytes(mm_Out))

at B4J, Debug and show with "mouse over"
B4X:
For Each k As String In mm_in_batch.DatenM.Keys    '<<- go with the mouse to DatenM, i can see
'mm_in_batch.DatenM
' |
'+- Size 6          <<- o.k.
'+ Key1
'     |
'     +Elementdata
'      |   + 0          <<- the String Array, o.k.     
'      |      + 0       <<- the Data in the String Array, o.k.
'      |      + 1
'      |      + 2
'      |      + 3......
'     +Size 1      <<- e.g., o.k.
'+ Key2
'       .
'       .
'       .
'it's looks all o.k.


Dim L_In As List
L_In.initialize
L_In = mm_in_batch.Datenm.get(k)    'with "mouse over" L_In is empty??? (debugger at next line!)

SQL_I.InitializeSQLite(Main.SetupPage.varLogPfad,k,False) 
 

    For i1 = 0 To L_In.Size - 1
        Dim val_2() As String
        val_2 = L_In.Get(i1)       'crash
..........
 
Last edited:
Upvote 0

OliverA

Expert
Licensed User
Longtime User
In B4J, what fails? Line 26? The commented out line (if not commented out) line 27? Is it the exact same error message? Are you sure the type definitions match exactly and they are exactly declared the same in the Main modules of both projects?
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
B4J crash in Line 30

B4A (the Project stats in 2015?) the Custom Type is declare in Main (Activity) Process Globals
B4J (B4X Pages Project) its Declare also Declare in Main, Process Globals

the definitins match, i have Copy/Paste from one to the other

what I forgot, I don't see any data at "Mouse Over" at L_In and the size is shown as 0, but a Log(L_In.size) returns the correct size.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
So in B4J, if you set your breakpoint at line 25 (SQL_I.InitializeSQLite(Main.SetupPage.varLogPfad,k,False)) and let the program run, once it hits the breakpoint, L_In is empty? (As an aside, L_In.Initialize is not required, since the list is just assigned another list from your map)
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
right, it run to breakpoint at Line 25, L_In is empty if i show with "mouse over" (move to L_In with the Mouse, the small window open and show me....empty)
what confuses me is that when I set a Log(L_In.Size) in line 24, for example, I get the correct (expected) size for L_In.


right, initalize is not required, I have tested if it helps.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
What does this do?
B4X:
    For i1 = 0 To L_In.Size - 1
        if L_In.Get(i1) = Null then
           Log("Houston, we've got a problem")
        else
           Dim val_2() As String
           val_2 = L_In.Get(i1)
           'rest of code 
        End If
Next
Note: may need to be
B4X:
if  Null = L_In.Get(i1) then
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
crash in Line 6 (from Code Snippet)
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')
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Hm... Old school....
B4X:
    For i1 = 0 To L_In.Size - 1
        Log($"toString representation of data: ${L_In.Get(i1)}"$)
    Next
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
toString representation of data: [Ljava.lang.Object;@3968581
toString representation of data: [Ljava.lang.Object;@73655917
toString representation of data: [Ljava.lang.Object;@1492fd24
toString representation of data: [Ljava.lang.Object;@45ae6129
toString representation of data: [Ljava.lang.Object;@72235e90
toString representation of data: [Ljava.lang.Object;@2b571c22
toString representation of data: [Ljava.lang.Object;@282fafb1
toString representation of data: [Ljava.lang.Object;@1ebe34b4
toString representation of data: [Ljava.lang.Object;@76012e2d
toString representation of data: [Ljava.lang.Object;@65a48ac3
toString representation of data: [Ljava.lang.Object;@3023e3e1
toString representation of data: [Ljava.lang.Object;@5f576ac5
toString representation of data: [Ljava.lang.Object;@4ef8f839
toString representation of data: [Ljava.lang.Object;@2a1db261
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
ExecuteMemoryTable_Datum
What is this? I just noticed you are not using the standard ExecuteMemoryTable. What is the code for this?
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
the date is save in the Database as yyyymmdd (today: 20210314), this copy of the orginal sub format the Datum, give back as string (e.g. 14/03/2021, for display)
In this Case it is better to use the orginal ExecuteMemoryTable, change, but the same Problem
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Has this at one time worked for you? Doing some tests on my own, it looks like something happens between the ConvertObjectToBytes and ConvertBytesToObject where the type of an array is lost and is just set/cast to Object (in this case Array As String is converted to Array As Object).
Update: I observed this behavior using B4J v8.90
Update2: Attaching B4J code used for testing
 

Attachments

  • SerializatorTest.zip
    3 KB · Views: 181
Upvote 0

mw71

Active Member
Licensed User
Longtime User
some (few) times it worked, but I cannot reproduce this. In the (all) most cases it comes to the abort.
Map with Strings as Values and List work as exceptet
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
good idea to test it this way ?

- if I run it slowly (breakpoint and then step by step with F8) everything is o.k.
- Automatically it aborts
- a try with sleep(0) and sleep(100) did not bring anything

Error Log:
Waiting for debugger to connect...
Program started.
[Ljava.lang.String;@f660176
[Ljava.lang.Object;@43fb8aac
[Ljava.lang.Object;@18f9b7f1
Fehler in Zeile: 39 (B4XMainPage)
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._initialize(b4xmainpage.java:179)
at b4j.example.b4xpagesmanager._initialize(b4xpagesmanager.java:107)
at b4j.example.main._appstart(main.java:80)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:237)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
at b4j.example.main.start(main.java:38)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
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)
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I haven't checked the code, however make sure that you are not trying to serialize an array of strings as it is not supported.

The following types are supported: Lists, Arrays of bytes and Arrays of objects, Maps, Strings, primitive types and user defined types.

You should convert arrays of strings to List before serialization.
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
hi Erel,

thanks for your anser, now it's clear why it dont work (DBUtils.ExecuteMemoryTable deliver an array of Strings).

@OliverA,
many thanks for your Test & Work?

I check how i solve the Problem, e.g. with JSON, maybe
 
Upvote 0
Top