B4J Question aws lambda

Pablo Torres

Active Member
Licensed User
Longtime User
hi, has anyone succeed on developing an aws lambda function with b4j?
I have a couple of projects that I need to migrate to aws lambda as functions, but I can't get them working at all

Any help will be appreciated

Many thanks
 

alwaysbusy

Expert
Licensed User
Longtime User
Appstart does not return anything. The syntax of Appstart is:

B4X:
Sub AppStart (Args() As String)

not

B4X:
Sub AppStart (Args() As String) As String

I'm not really sure what you try to archive here, but why don't you just try to log it?

Something like:

B4X:
Sub Process_Globals
   
End Sub

Sub AppStart (Args() As String)
    ...
    Dim mapJson As Map
    mapJson.Initialize
    mapJson.Put("statusCode",200)
    mapJson.Put("body","the body text")
    Dim MyJG As JSONGenerator
    MyJG.Initialize(mapJson)
    Log(MyJG.ToString)
End Sub

Result after starting it with java -jar testReturn.jar:

1646117673031.png


you could also redirect the output to a file and then read it afterwards in some other app:

B4X:
Sub Process_Globals
    
End Sub

Sub AppStart (Args() As String)
    RedirectOutput(File.DirApp, "output.txt")
    
    Dim mapJson As Map
    mapJson.Initialize
    mapJson.Put("statusCode",200)
    mapJson.Put("body","the body text")
    Dim MyJG As JSONGenerator
    MyJG.Initialize(mapJson)
    Log(MyJG.ToString)
End Sub

Sub RedirectOutput (Dir As String, FileName As String)
   #if RELEASE
    Dim out As OutputStream = File.OpenOutput(Dir, FileName, False) 'Set to True to append the logs
    Dim ps As JavaObject
    ps.InitializeNewInstance("java.io.PrintStream", Array(out, True, "utf8"))
    Dim jo As JavaObject
    jo.InitializeStatic("java.lang.System")
    jo.RunMethod("setOut", Array(ps))
    jo.RunMethod("setErr", Array(ps))
   #end if
End Sub

Result is a file output.txt

1646118186238.png


Containing:

1646118255899.png


Alwaysbusy
 
Last edited:
Upvote 1

Pablo Torres

Active Member
Licensed User
Longtime User
Dear Marco, before posting the thread I did at least 3 times the search you suggest and did read ALL the post involved.
There is only one post where Erel says it shouldn't be a problem with a NON-UI app, but nothing else. (in fact he answer that a B4J server can't be a lambda function but a NON-UI can)
Have you done this search? Did you read the posts?

I find myself a problem with the arguments of the appstart, while in B4J the arguments is an array of string, in aws lambda needs to be (Object,String)
I also have a little problem about Json decoding, so I will appreciate any help anyone can give me

Do you have something to help me about this subject? Did you tried to develop a NON-ui for aws lambda and succeeded?
I would appreciate your help if you can or anyone's help, but please don't tell me to search again, I already did that 3 times, this is not my first post, I have been using B4X almost 10 years.

I understand that some questions can be answered with a previous post... this is not the case, that is why I posted the question.
You can verify that by doing the search yourself
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
I have a couple of projects that I need to migrate to aws lambda as functions, but I can't get them working at all
I bit of code might help - that doesn't work...
Just a hint since I have no idea of this issue... just an observation.
Wish you luck...

Thx
 
Upvote 0

Pablo Torres

Active Member
Licensed User
Longtime User
I bit of code might help - that doesn't work...
Just a hint since I have no idea of this issue... just an observation.
Wish you luck...

Thx
Great idea Harris, sorry I miss that
Here goes my code:

B4J:
'Non-UI application (console / server application)
#Region Project Attributes
    #MergeLibraries: True
    #AdditionalJar: mysql-connector-java-5.0.8-bin.jar
#End Region

Sub Process_Globals
   
End Sub

Sub AppStart (Args() As String) As String
    Try
        Dim lstResp As List
        lstResp.Initialize
        Dim jSQL As SQL
        jSQL.Initialize2("com.mysql.jdbc.Driver", "jdbc:mysql://XXXXXX:3306/YYYYY?characterEncoding=utf8", "ZZZZZZ","TTTTTTT")
        Dim rs As ResultSet=jSQL.ExecQuery("SELECT * FROM eventos WHERE valido=1 ORDER BY fecha")
        Do While rs.NextRow
            Dim newEvento As Map
            newEvento.Initialize
            newEvento.Put("IdEvento",rs.GetInt("idevento"))
            newEvento.Put("Nombre",rs.GetString("nombre"))
            newEvento.Put("Lugar",rs.GetString("lugar"))
            newEvento.Put("Fecha",rs.GetString("fecha"))
            newEvento.Put("Hora",rs.GetString("hora"))
            newEvento.Put("Tipo",rs.GetInt("tipo"))
            lstResp.Add(newEvento)
        Loop
        rs.Close
        jSQL.Close
        Dim mapJson As Map
        mapJson.Initialize
        mapJson.Put("statusCode",200)
        mapJson.Put("body",lstResp)
        Dim MyJG As JSONGenerator
        MyJG.Initialize(mapJson)
        Return MyJG.ToString
    Catch
        rs.Close
        jSQL.Close
        Dim mapJson As Map
        mapJson.Initialize
        mapJson.Put("statusCode",200)
        mapJson.Put("body","Se produjo un error: " & LastException)
        Dim MyJG As JSONGenerator
        MyJG.Initialize(mapJson)
        Return MyJG.ToString
    End Try
End Sub

When I run this I get a "null" response, I don't know how to proceed with this, I'm really stucked an any help will be appreciated
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
Loops pretty simple to me! I do this sort of thing all the time....
Try throwing some log messages in at various places ( ie. inside the loop) to see what may be happening.

Try it as a UI if you can't debug a NON-UI....
 
Upvote 0

Pablo Torres

Active Member
Licensed User
Longtime User
Loops pretty simple to me! I do this sort of thing all the time....
Try throwing some log messages in at various places ( ie. inside the loop) to see what may be happening.

Try it as a UI if you can't debug a NON-UI....
I can debug NON-UI, no problem about that (but it was a good tip anyway)

I believe the problem is that my appstart function is not giving any answers back, that is why I receive a null as a response
How can I send a string as a response while executing my jar?
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
Return MyJG.ToString

So your logs show this (MyJG.ToString) is populated with expected string response... ?

How is the jar being called - from where - (return result from what app call) ?

As a matter of my best practices, I do not run business logic in the App Start - just initialize globals and such.
The last line in App Start will call the sub to return expected data....

If I understand correctly, your app starts and stops (terminates) with no StartMessageLoop (as with UI apps demand - keeps app alive).
I tried NON-UI, did not understand the requirements and resorted to UI apps that hide the forms - then ExitApplication with no result (data was written elsewhere).

Some bright member will chime in soon with a resolve....
 
Upvote 0

Pablo Torres

Active Member
Licensed User
Longtime User
So your logs show this (MyJG.ToString) is populated with expected string response... ?

How is the jar being called - from where - (return result from what app call) ?

As a matter of my best practices, I do not run business logic in the App Start - just initialize globals and such.
The last line in App Start will call the sub to return expected data....

If I understand correctly, your app starts and stops (terminates) with no StartMessageLoop (as with UI apps demand - keeps app alive).
I tried NON-UI, did not understand the requirements and resorted to UI apps that hide the forms - then ExitApplication with no result (data was written elsewhere).

Some bright member will chime in soon with a resolve....
yes, my logs show MyJG.ToString is populated perfectly.
I truly believe that the problem is that my app terminates without giving any response, that is thee reason why I always get "null" answer when executed
It executes fine, just don't reply anything, I have to fix that but I don't know how
 
Upvote 0

Pablo Torres

Active Member
Licensed User
Longtime User
I'm not really sure what you try to archive here, but why don't you just try to log it?
I'm trying to work server less with a aws lambda function made my B4J and a AWS Aurora DB also serverless, that way I avoid all issues about servers, I just need to maintain a DB online and perform some actions on it (read, write, etc)
So, It seems that this combo (aws lambda + aurora) is almost perfect for that task and aws lambda functions support many languages including java, you just have to upload the .jar

But (here goes the problem) I can't get an answer from the jar when I execute it, like a response, and that is what I need to make it works
I need to make a jar (something like a handler for servers) that when you execute it, it gives you a response back (a string for example)

Don't know how to do that
 
Upvote 0

Pablo Torres

Active Member
Licensed User
Longtime User
Is there any possibility to modified the main class and compile again with a Java ide to get the main class accept diferents args and return a value?
The only ways possible to my knowledge are the ones I described above. A jar can not directly return a string like you tried to do as AppStart has no return value.
 
Upvote 0

Harris

Expert
Licensed User
Longtime User
There is no such thing. The Java entry point (main) never returns values.
@Pablo Torres , time to rethink your strategy. aws is one of many options you may consider...
VPS is what I chose, since I have total control. Yes, there is a learning curve and (some) expense.
All depends on your expected monetary return (and your (less than) deep pockets)?
 
Upvote 0

Pablo Torres

Active Member
Licensed User
Longtime User
In fact,
@Pablo Torres , time to rethink your strategy. aws is one of many options you may consider...
VPS is what I chose, since I have total control. Yes, there is a learning curve and (some) expense.
All depends on your expected monetary return (and your (less than) deep pockets)?
I see, so there is no solution in B4J for this…
Unfortunately there is no chance to change strategy, I did choosed VPS in all my projects before and that works great, but I need to implement AWS lambda functions on this one due to scalability issues.
Many thanks guys for your efforts
 
Upvote 0
Top