B4J Question Cannot cast Map to Map$MyMap Error...

techknight

Well-Known Member
Licensed User
Longtime User
So I am trying to implement some more code in my project, and it keeps crashing with this:

java.lang.ClassCastException: anywheresoftware.b4a.objects.collections.Map cannot be cast to anywheresoftware.b4a.objects.collections.Map$MyMap

Here is the code:
B4X:
Public Sub GetAllFilesRecursive(FullSync As Boolean)
    MediaFiles.Clear
    If File.ListFiles(MediaDIR).Size = 0 Then Return 'No Files Found
    ReadMediaDir(MediaDIR, True) 'Get all files and folders, Parse and store only Media Files.
    Files.Clear 'empty our file directory
    Folders.Clear 'empty folder directory
'    BuildMediaFiles(FullSync)
    Wait For (BuildMediaFiles(FullSync)) Complete (Result As Boolean)
    Log(MediaFiles)
End Sub

'Build the Thumbnails, Duration of video (if applicable), and full binary blob (if applicable) of each media file.
Public Sub BuildMediaFiles(IncludeBinary As Boolean) As ResumableSub
    MediaType.InitializeStatic("com.google.common.net.MediaType")
    For Each MF As MediaFile In MediaFiles
        If MediaType.RunMethodJO("parse",Array(MF.FileType)).RunMethod("is",Array(MediaType.GetField("ANY_IMAGE_TYPE"))) = True Then 'It is an Image File
            Dim ThumbNailImage As Image
            ThumbNailImage.InitializeSample(MediaDIR & MF.Subdir, MF.FileName, 320, 240)
            MF.Thumbnail = BitmapToBase64(ThumbNailImage)
        Else If MediaType.RunMethodJO("parse",Array(MF.fileType)).RunMethod("is",Array(MediaType.GetField("ANY_VIDEO_TYPE"))) = True Then 'It is a video file
            Dim rs As ResumableSub = GenerateVideoDetails(MF.FileName, MF.Subdir)
            Wait For (rs) Complete (Result As Object)
            Log(GetType(Result))
            If Result Is Boolean Then 'We returned a fault from GenerateVideoDetails, either a corrupt file or the file was in use.
                MF.Thumbnail = "failed"
                MF.Duration = ""
            Else 'We got a good reply
                Dim M As Map = Result 'Get the map.
                MF.Duration = M.GetKeyAt(0)  '*****Crash Occurs here*******
                MF.Thumbnail = M.GetValueAt(0)
                If IncludeBinary = True Then MF.Blob = FileToBytes(MediaDIR & MF.Subdir, MF.FileName)
            End If
        End If
    Next
    Return True
End Sub

'Generates the video thumbnail and video duration from FFMpeg
Private Sub GenerateVideoDetails(FileName As String, FilePath As String) As ResumableSub
    Dim sh1 As Shell
    If File.Exists(File.DirTemp, "thumb.png") = True Then File.Delete(File.DirTemp, "thumb.png") 'Remove the file
    sh1.Initialize("sh1", "ffmpeg", Array As String("-i", MediaDIR & FilePath & "/" & FileName, "-vf", "thumbnail,scale=320:240", "-frames:v", "1", File.DirTemp & "/" & "thumb.png")) 'Grab the duration and thumbnail from the media file
    sh1.WorkingDirectory = File.DirApp
    sh1.Run(10000)
    Wait For sh1_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
    If Success = False Then
        Return False
    Else
        Try 'Parse Duration from Response Text. ffmpeg outputs on STDErr for some reason. So we will use a sum of both stdout and stderr.
            Dim StdOutErr As String = StdOut & StdErr
            Dim Response() As String = Regex.Split("Duration:", StdOutErr)
            Dim Duration() As String = Regex.Split(",", Response(1))
        Catch 'Failed to parse the correct duration information. Maybe passed a bad file?
            Return False
        End Try
        Dim bmp As Image
        bmp.Initialize(File.DirTemp, "thumb.png")
        Dim M As Map
        M.Initialize
        M.Put(Duration(0), BitmapToBase64(bmp))
        Return M
    End If
End Sub

I marked above the line at which the crash occurs. Any ideas?
 

techknight

Well-Known Member
Licensed User
Longtime User
Its no different than passing different objects from the same sub, and I used it heavily in B4A And it works. (with the exception in this case), so how is that a mistake? Sorry just trying to learn how and why it is a mistake?

I switched from a Map to a String array, and that worked while the map didn't. I am still stuck in VB land where I think object is like a "variant" where you can pass anything in it as long as you check its type and handle it properly. I haven't had an issue yet until this one.
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
The case with ResumableSub return value is similar to the case with CallSub calls. If it was a regular sub then it would have worked (though it is bad practice to return different types from the same sub).

The return value type should match the parameter type defined in the wait for complete event. Otherwise it will fail in some cases.
 
Upvote 0
Top