Spanish [SOLUCIONADO] Error JRDC2 servidor

RAFA BRAVO

Member
Licensed User
Hola buenos días, utilizo el ejemplo del tutorial de Erel https://www.b4x.com/android/forum/t...-rdc-remote-database-connector.61801/#content . Lo utilizo en una aplicación para crear una cuenta de usuario y un inicio de sesión a la misma aplicación. Todo funciona perfecto, el único problema que tengo es que si la dirección IP del servidor no es la correcta o a cambiado, o por ejemplo, el móvil no está conectado a la red en el momento de su uso, aparece un error:
Registro conectado a: Xiaomi Mi 9T --------- beginning of system --------- beginning of main *** Service (starter) Create *** ** Service (starter) Start ** ** Activity (main) Create, isFirst = true ** ** Activity (main) Resume ** Main *** Service (httputils2service) Create *** ** Service (httputils2service) Start ** ResponseError. Reason: java.sql.SQLException: Parameter index out of range (2 > number of parameters, which is 1)., Response: <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> <title>Error 500 java.sql.SQLException: Parameter index out of range (2 &gt; number of parameters, which is 1).</title> </head> <body><h2>HTTP ERROR 500</h2> <p>Problem accessing /rdc. Reason: <pre> java.sql.SQLException: Parameter index out of range (2 &gt; number of parameters, which is 1).</pre></p><hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.z-SNAPSHOT</a><hr/> </body> </html> ERROR: <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> <title>Error 500 java.sql.SQLException: Parameter index out of range (2 &gt; number of parameters, which is 1).</title> </head> <body><h2>HTTP ERROR 500</h2> <p>Problem accessing /rdc. Reason: <pre> java.sql.SQLException: Parameter index out of range (2 &gt; number of parameters, which is 1).</pre></p><hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.z-SNAPSHOT</a><hr/> </body> </html> main$ResumableSub_SearchRecordresume (java line: 869) java.lang.NullPointerException: Attempt to read from field 'anywheresoftware.b4a.objects.collections.List b4a.googlecontacts.main$_dbresult.Rows' on a null object reference at b4a.googlecontacts.main$ResumableSub_SearchRecord.resume(main.java:869) at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267) at anywheresoftware.b4a.BA.raiseEvent2(BA.java:207) at anywheresoftware.b4a.keywords.Common$11.run(Common.java:1178) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:201) at android.app.ActivityThread.main(ActivityThread.java:6861) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

He estado buscando pero no encuentro la solución, me gustaría poder mostrar un mensaje de error de conexión, y evitar que me expulse de la aplicación. Talvez debería de crear la comunicación en un modulo servicio? Gracias de antemano.
 

José J. Aguilar

Expert
Licensed User
Hola Rafa:

Puedes echar un ojo a este ejemplo a ver si te da alguna pista.

Si te fijas en la función de Login, lanzas la consulta al servidor jRDC2 con el wait for. Si obtienes "Success", se ha hecho bien. Si no, muestras un mensaje de error. Puede ser o bien que la conexión a internet no esté activa, o bien el servidor jRDC2 no responda.
B4X:
Sub btnLogin_Click
    Toast.Show("Checking user and password...")
    Dim Parametros() As String = Array As String(etUser.Text.Trim, etPass.Text.Trim)
    Wait For(jRDC.GetRecord("Login", Parametros)) Complete (Answer As Map)
    If Answer.Get("Success") Then
        Dim l As List
        Dim rs As DBResult
        rs = Answer.Get("Data")
        l = rs.Rows
        If l.Size > 0 Then 'We get a result
            Dim UserData As List
            For Each row() As Object In l
                UserData = row
            Next
            'Save the user name and id to build the sql queries
            'Guardamos el nombre de usuario y el id para construir las sentencias sql
            KVS.Put("user", etUser.Text.Trim)
            KVS.Put("id_user", UserData.Get(0))
            B4XPages.ShowPageAndRemovePreviousPages("Page Data")
        Else
            xui.MsgboxAsync("Wrong username or password", "Error")
        End If
    Else
        xui.MsgboxAsync("Problem connecting: " & Answer.Get("Error"), "Error")
    End If
End Sub

De todas formas, tu error parece distinto. Parece que estás enviando una consulta al servidor con menos parámetros de los que recibe.
Comprueba el número de ? que tienes en tus config.properties en B4J, y el número de parámetros que envías desde el cliente (B4A?)

Saludos,
 

RAFA BRAVO

Member
Licensed User
Perdón creo que en ese log de error salía algún error anterior, he desinstalado la aplicación y la he vuelto a instalar este es el log correcto:
Registro conectado a: Xiaomi Mi 9T --------- beginning of main *** Service (starter) Create *** ** Service (starter) Start ** ** Activity (main) Create, isFirst = true ** ** Activity (main) Resume ** Main *** Service (httputils2service) Create *** ** Service (httputils2service) Start ** ResponseError. Reason: java.net.ConnectException: Failed to connect to /192.168.18.2:17178, Response: ERROR: java.net.ConnectException: Failed to connect to /192.168.18.2:17178 main$ResumableSub_LogInresume (java line: 811) java.lang.NullPointerException: Attempt to read from field 'anywheresoftware.b4a.objects.collections.List b4a.googlecontacts.main$_dbresult.Rows' on a null object reference at b4a.googlecontacts.main$ResumableSub_LogIn.resume(main.java:811) at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267) at anywheresoftware.b4a.BA.raiseEvent2(BA.java:207) at anywheresoftware.b4a.keywords.Common$11.run(Common.java:1178) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:201) at android.app.ActivityThread.main(ActivityThread.java:6861) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)
Log("ERROR: " & j.ErrorMessage) Este log si se muestra, pero luego me expulsa de la app, el resto de log ya es el error que me esta sucediendo y no puedo resolver.
Aquí te dejo la rutina a la que llamo cuando quiero iniciar sesión, solo recibo el error cuando la conexión no se a establecido correctamente.

Sub para iniciar sesión:
Sub LogIn(usuario1 As String,contraseña2 As String)

    Dim req As DBRequestManager = CreateRequest
    Dim cmd As DBCommand = CreateCommand("selectedSesion", Array(usuario1,contraseña2))
    Wait For (req.ExecuteQuery(cmd, 0, Null)) JobDone(j As HttpJob)
    ProgressDialogShow("Cargando...")
    If j.Success Then
        req.HandleJobAsync(j, "req")
        Wait For (req) req_Result(res As DBResult)
        
        'work with result
        'req.PrintTable(res)
'        Log(res.Columns)
        
        For Each row() As Object In res.Rows
            EditTextNombreUsuario.Text = ""
            EditTextContraseña.text = ""
            Starter.InicioSesionApp = row(6)
            StartActivity(firstLayout)
            Activity.Finish
        Next
    Else
        Log("ERROR: " & j.ErrorMessage)
        ToastMessageShow("Error en la conexión",False)
    End If
    ProgressDialogHide
    If res.Rows.Size = 0 Then
        ToastMessageShow("Usuario o contraseña incorrecto",False)
    End If
    j.Release
End Sub
 

José J. Aguilar

Expert
Licensed User
¿Qué pasa si comentas o borras estas líneas cuando no estás conectado?

B4X:
   If res.Rows.Size = 0 Then
        ToastMessageShow("Usuario o contraseña incorrecto",False)
    End If
 

RAFA BRAVO

Member
Licensed User
Muchas gracias José, ahora si funciona perfecto.

B4X:
Sub LogIn(usuario1 As String,contraseña2 As String)

    Dim req As DBRequestManager = CreateRequest
    Dim cmd As DBCommand = CreateCommand("selectedSesion", Array(usuario1,contraseña2))
    Wait For (req.ExecuteQuery(cmd, 0, Null)) JobDone(j As HttpJob)
    ProgressDialogShow("Cargando...")
    If j.Success Then
        req.HandleJobAsync(j, "req")
        Wait For (req) req_Result(res As DBResult)
        
        For Each row() As Object In res.Rows
            
                EditTextNombreUsuario.Text = ""
                EditTextContraseña.text = ""
                Starter.InicioSesionApp = row(6)
                StartActivity(firstLayout)
                Activity.Finish
            
        Next
        If res.Rows.Size = 0 Then
            ToastMessageShow("Usuario o contraseña incorrecto",True)
        End If
    Else
        Log("ERROR: " & j.ErrorMessage)
        ToastMessageShow("Error en la conexión",False)
    End If

    ProgressDialogHide
    j.Release
End Sub

Tarda un poco en mostrar el mensaje de error de conexión, pero no me expulsa de la app ni aparece el error ya.
 

José J. Aguilar

Expert
Licensed User
Prueba a ver si puedes cambiar el valor de timeout de j (httpjob), creo que por defecto son 30 segundos.
Prueba a poner un
B4X:
log(j.GetRequest.Timeout)
a ver si te devuelve algo, y a intentar cambiarlo con
B4X:
j.GetRequest.Timeout = 4000

No he probado nada de esto. Si te funciona, pon cómo ha funcionado al final.

saludos,
 
Top